@@ -138,14 +138,20 @@ private void createSynth(AudioDeviceManager deviceManager) {
138
138
if (this .synth != null ) {
139
139
this .stopSynth (true );
140
140
}
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
+ }
142
148
this .outputDevice = deviceManager .getDefaultOutputDeviceID ();
143
149
this .synth = JSyn .createSynthesizer (deviceManager );
144
150
}
145
151
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
149
155
// JavaSound
150
156
protected boolean usePortAudio (boolean portAudio ) {
151
157
if (portAudio != this .synth .getAudioDeviceManager () instanceof JPortAudioDevice ) {
@@ -191,8 +197,11 @@ private void startSynth() {
191
197
}
192
198
this .setVolume (1.0f );
193
199
200
+ // prevent IndexOutOfBoundsException on input-less devices
201
+ int inputChannels = this .inputDevice >= 0 ?
202
+ this .synth .getAudioDeviceManager ().getMaxInputChannels (this .inputDevice ) : 0 ;
194
203
this .synth .start (this .sampleRate ,
195
- this .inputDevice , this . synth . getAudioDeviceManager (). getMaxInputChannels ( this . inputDevice ) ,
204
+ this .inputDevice , inputChannels ,
196
205
this .outputDevice , this .synth .getAudioDeviceManager ().getMaxOutputChannels (this .outputDevice ));
197
206
}
198
207
0 commit comments