package jmsltestsuite; import java.awt.Button; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import com.softsynth.jmsl.JMSL; import com.softsynth.jmsl.MusicDevice; import com.softsynth.jmsl.MusicShape; import com.softsynth.jmsl.ParallelCollection; import com.softsynth.jmsl.midi.MidiIO_MidiShare; import com.softsynth.jmsl.midi.MidiInstrument; /** This class tests MidiScheduling by playing a parallel collection of monophonic melodies, whose timing (in)accuracy is clearly audible. Uses GRAME's MidiShare to get accurate Midi output. Comment in or out the line in main()... JMSL.midi = new MidiIO_MidiShare(); ...and recompile, to toggle between MidiPort and MidiShare. Grame's MidiShare uses its own event buffer, which is more accurate than JMSL's Java-Thread-based Event Scheduler, used to schedule non-event buffered Midi output as it is currently implemented in MidiPort. This test sends on Midi Channel 10 !!! @author Nick Didkovsky 3/22/01 */ public class TestMidiScheduling extends Frame implements ActionListener { private Button stopButton; private Button goButton; private ParallelCollection parallelCollection; public TestMidiScheduling() { setLayout(new FlowLayout()); add(goButton = new Button("GO")); goButton.addActionListener(this); add(stopButton = new Button("STOP")); stopButton.addActionListener(this); stopButton.setEnabled(false); build(); } public void build() { parallelCollection = new ParallelCollection(); parallelCollection.setRepeats(1000); int numShapes = 1; int numSeconds = 10; double wholenote = 1.0; for (int shapeIndex = 0; shapeIndex < numShapes; shapeIndex++) { int index = shapeIndex + 1; MusicShape m = new MusicShape(4); parallelCollection.add(m); m.setInstrument(new MidiInstrument(10)); for (int i = 0; i < 32; i++) { double dur = 0.125; double pitch = 36; if (i % 4 == 0) { m.add(0, 31, 90, dur * 0.80); } m.add(dur, pitch, 90, dur * 0.80); } } System.out.println("Does this sound like rhythmically solid timing?"); } public void actionPerformed(ActionEvent ev) { Object source = ev.getSource(); if (source == goButton) { goButton.setEnabled(false); stopButton.setEnabled(true); parallelCollection.launch(JMSL.now()); } if (source == stopButton) { parallelCollection.finishAll(); try { parallelCollection.waitForDone(); } catch (InterruptedException e) { e.printStackTrace(); } goButton.setEnabled(true); stopButton.setEnabled(false); } } public static void main(String args[]) { JMSL.clock.setAdvance(0.1); TestMidiScheduling tms = new TestMidiScheduling(); MusicDevice dev = MidiIO_MidiShare.instance(); // MusicDevice dev = MidiIO_JavaSound.instance(); // MusicDevice dev = MidiIO_MidiPort.instance(); // MusicDevice dev = MidiIO_MidiPortLegacy.instance(); dev.edit(tms); dev.open(); tms.pack(); tms.setVisible(true); WindowAdapter windowAdapter = new WindowAdapter() { public void windowClosing(WindowEvent e) { JMSL.closeMusicDevices(); System.exit(0); } }; tms.addWindowListener(windowAdapter); } }