Skip to content

Commit 7f612a0

Browse files
committed
Ensure that all models compile in headless mode
1 parent 62d547e commit 7f612a0

File tree

1 file changed

+60
-42
lines changed

1 file changed

+60
-42
lines changed

src/main/java/SoundExtension.java

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.File;
44
import java.io.IOException;
55

6+
import javax.sound.midi.MidiUnavailableException;
67
import javax.sound.sampled.AudioFormat;
78
import javax.sound.sampled.AudioInputStream;
89
import javax.sound.sampled.AudioSystem;
@@ -13,9 +14,11 @@
1314
import javax.sound.sampled.LineUnavailableException;
1415
import javax.sound.sampled.UnsupportedAudioFileException;
1516

17+
import org.nlogo.api.ExtensionException;
1618
import org.nlogo.api.ExtensionManager;
1719

1820
public class SoundExtension extends org.nlogo.api.DefaultClassManager {
21+
private boolean isHeadless = true;
1922

2023
/**
2124
* Names of the drums. <p>
@@ -124,41 +127,44 @@ public void load(org.nlogo.api.PrimitiveManager primManager) {
124127
*/
125128
public void runOnce(org.nlogo.api.ExtensionManager em)
126129
throws org.nlogo.api.ExtensionException {
127-
try {
128-
129-
// Open a synthesizer
130-
synth = javax.sound.midi.MidiSystem.getSynthesizer();
131-
synth.open();
132-
133-
// Get array of synth channels
134-
channels = synth.getChannels();
135-
// initializing channels to 0 to fix bug #1027
136-
// channels have program=0 to begin with, but this additional initialization
137-
// seems to make them work properly for instrument 0 (acoustic grand piano)
138-
// when they arent initialized like this, then when inst 0 is used
139-
// the channel plays the wrong instrument.
140-
// maybe someday we can figure out why, but for now this is sufficient. -JC 7/2/10
141-
for (javax.sound.midi.MidiChannel ch : channels) {
142-
ch.programChange(0);
143-
}
130+
isHeadless = !em.workspaceContext().workspaceGUI();
144131

145-
javax.sound.midi.Soundbank soundbank = synth.getDefaultSoundbank();
132+
if (!isHeadless) {
133+
try {
134+
// Open a synthesizer
135+
synth = javax.sound.midi.MidiSystem.getSynthesizer();
136+
synth.open();
137+
138+
// Get array of synth channels
139+
channels = synth.getChannels();
140+
// initializing channels to 0 to fix bug #1027
141+
// channels have program=0 to begin with, but this additional initialization
142+
// seems to make them work properly for instrument 0 (acoustic grand piano)
143+
// when they arent initialized like this, then when inst 0 is used
144+
// the channel plays the wrong instrument.
145+
// maybe someday we can figure out why, but for now this is sufficient. -JC 7/2/10
146+
for (javax.sound.midi.MidiChannel ch : channels) {
147+
ch.programChange(0);
148+
}
146149

147-
if (soundbank == null) {
148-
try {
149-
java.io.InputStream soundbankStream = getClass().getClassLoader().getResourceAsStream("soundbank-min.gm");
150-
java.io.BufferedInputStream bufferedSoundbankStream = new java.io.BufferedInputStream(soundbankStream);
151-
soundbank = javax.sound.midi.MidiSystem.getSoundbank(bufferedSoundbankStream);
152-
} catch (java.io.IOException e) {
153-
throw new org.nlogo.api.ExtensionException("Failed to load soundbank: " + e.toString());
154-
} catch (javax.sound.midi.InvalidMidiDataException e) {
155-
throw new org.nlogo.api.ExtensionException("Failed to load soundbank: " + e.toString());
150+
javax.sound.midi.Soundbank soundbank = synth.getDefaultSoundbank();
151+
152+
if (soundbank == null) {
153+
try {
154+
java.io.InputStream soundbankStream = getClass().getClassLoader().getResourceAsStream("soundbank-min.gm");
155+
java.io.BufferedInputStream bufferedSoundbankStream = new java.io.BufferedInputStream(soundbankStream);
156+
soundbank = javax.sound.midi.MidiSystem.getSoundbank(bufferedSoundbankStream);
157+
} catch (java.io.IOException e) {
158+
throw new org.nlogo.api.ExtensionException("Failed to load soundbank: " + e.toString());
159+
} catch (javax.sound.midi.InvalidMidiDataException e) {
160+
throw new org.nlogo.api.ExtensionException("Failed to load soundbank: " + e.toString());
161+
}
156162
}
157-
}
158163

159-
boolean loaded = synth.loadAllInstruments(soundbank);
160-
} catch (javax.sound.midi.MidiUnavailableException ex) {
161-
throw new org.nlogo.api.ExtensionException("MIDI is not available");
164+
boolean loaded = synth.loadAllInstruments(soundbank);
165+
} catch (MidiUnavailableException ex) {
166+
throw new ExtensionException("MIDI is not available.");
167+
}
162168
}
163169
}
164170

@@ -177,7 +183,10 @@ public void unload(ExtensionManager em) {
177183
*/
178184
static void startNote(int instrument, int note, int velocity) {
179185
javax.sound.midi.MidiChannel channel = ensureChannel(instrument);
180-
channel.noteOn(note, velocity);
186+
187+
if (channel != null) {
188+
channel.noteOn(note, velocity);
189+
}
181190
}
182191

183192
/**
@@ -210,8 +219,10 @@ static void stopNotes(int instrument) {
210219
* Stops all notes.
211220
*/
212221
static void stopNotes() {
213-
// the api says stop messages are recevied by all channels
214-
channels[0].allNotesOff();
222+
if (channels.length > 0) {
223+
// the api says stop messages are recevied by all channels
224+
channels[0].allNotesOff();
225+
}
215226
}
216227

217228
/**
@@ -224,19 +235,24 @@ static void stopNotes() {
224235
*/
225236
static void playNote(int instrument, int note, int velocity, int duration) {
226237
javax.sound.midi.MidiChannel channel = ensureChannel(instrument);
227-
channel.noteOn(note, velocity);
228238

229-
// start the stop thread
230-
if (duration > -1) {
231-
(new StopNoteThread(channel, note, duration)).start();
239+
if (channel != null) {
240+
channel.noteOn(note, velocity);
241+
242+
// start the stop thread
243+
if (duration > -1) {
244+
(new StopNoteThread(channel, note, duration)).start();
245+
}
232246
}
233247
}
234248

235249

236250
static void playNoteLater(int instrument, int note, int velocity, int duration, int delay) {
237251
javax.sound.midi.MidiChannel channel = ensureChannel(instrument);
238-
new PlayNoteThread(channel, note, velocity, duration, delay)
239-
.start();
252+
253+
if (channel != null) {
254+
new PlayNoteThread(channel, note, velocity, duration, delay).start();
255+
}
240256
}
241257

242258
/**
@@ -246,7 +262,9 @@ static void playNoteLater(int instrument, int note, int velocity, int duration,
246262
* @param velocity the speed at which the drum was hit, from 0 to 128
247263
*/
248264
static void playDrum(int drum, int velocity) {
249-
channels[PERCUSSION_CHANNEL].noteOn(drum, velocity);
265+
if (channels.length > 0) {
266+
channels[PERCUSSION_CHANNEL].noteOn(drum, velocity);
267+
}
250268
}
251269

252270

@@ -462,7 +480,7 @@ private static javax.sound.midi.MidiChannel getChannel(int instrument) {
462480
private static javax.sound.midi.MidiChannel ensureChannel(int instrument) {
463481
javax.sound.midi.MidiChannel channel = getChannel(instrument);
464482

465-
if (channel != null) {
483+
if (channel != null || channels.length == 0) {
466484
return channel;
467485
}
468486

0 commit comments

Comments
 (0)