@@ -138,14 +138,20 @@ private void createSynth(AudioDeviceManager deviceManager) {
138138 if (this .synth != null ) {
139139 this .stopSynth (true );
140140 }
141- this .inputDevice = deviceManager .getDefaultInputDeviceID ();
141+ try {
142+ // this might be -1 if there is no device with inputs. handled below.
143+ this .inputDevice = deviceManager .getDefaultInputDeviceID ();
144+ } catch (RuntimeException e ) {
145+ // JPortAudioDevice even throws an exception if none of the devices have
146+ // inputs...
147+ }
142148 this .outputDevice = deviceManager .getDefaultOutputDeviceID ();
143149 this .synth = JSyn .createSynthesizer (deviceManager );
144150 }
145151
146- // called in three different cases:
147- // 1. explicitly by the user
148- // 2. automatically by selectOutputDevice when it fails to open a line using
152+ // called in two different cases:
153+ // 1. explicitly by the user (through MultiChannel.usePortAudio())
154+ // 2. automatically by selectOutputDevice() when it fails to open a line using
149155 // JavaSound
150156 protected boolean usePortAudio (boolean portAudio ) {
151157 if (portAudio != this .synth .getAudioDeviceManager () instanceof JPortAudioDevice ) {
@@ -191,8 +197,11 @@ private void startSynth() {
191197 }
192198 this .setVolume (1.0f );
193199
200+ // prevent IndexOutOfBoundsException on input-less devices
201+ int inputChannels = this .inputDevice >= 0 ?
202+ this .synth .getAudioDeviceManager ().getMaxInputChannels (this .inputDevice ) : 0 ;
194203 this .synth .start (this .sampleRate ,
195- this .inputDevice , this . synth . getAudioDeviceManager (). getMaxInputChannels ( this . inputDevice ) ,
204+ this .inputDevice , inputChannels ,
196205 this .outputDevice , this .synth .getAudioDeviceManager ().getMaxOutputChannels (this .outputDevice ));
197206 }
198207
0 commit comments