[jmsl] Navigating Sequential Sequence

jmsl at music.columbia.edu jmsl at music.columbia.edu
Tue Apr 28 09:42:12 EDT 2009


Hi Chi

You don't have to have the Behavior finish all. You can achieve the same 
with setRepeats(seq.size() - startingIndex) before launching

waitForDone() blocks until done so it is probably missing the mouse 
clicks while waiting.

Thanks
Nick

jmsl at music.columbia.edu wrote:
> Thanks. It's making some progress!
> I needed it to stop when it reaches end instead of going back to 0, so 
> I made a repeatPlayable to keep checking if currentPosition is same as 
> original position and finishAll() when they are the same.
> I'm stil having problem with moving during playback. It works in a 
> slow moving, but it doesn't work if I press previous like 2 or 3 times.
> Here is my new code.
> Thanks,
>
> Chi
>
> import java.awt.BorderLayout;
> import java.awt.GridLayout;
> import java.awt.event.ActionEvent;
> import java.awt.event.ActionListener;
> import java.awt.event.InputEvent;
> import java.awt.event.ItemEvent;
> import java.awt.event.ItemListener;
> import java.awt.event.KeyEvent;
> import javax.swing.JApplet;
> import javax.swing.JButton;
> import javax.swing.JCheckBoxMenuItem;
> import javax.swing.JFrame;
> import javax.swing.JLabel;
> import javax.swing.JMenu;
> import javax.swing.JMenuBar;
> import javax.swing.JMenuItem;
> import javax.swing.JOptionPane;
> import javax.swing.JPanel;
> import javax.swing.KeyStroke;
> import com.didkovsky.portview.swing.ViewFactorySwing;
> import com.softsynth.jmsl.Behavior;
> import com.softsynth.jmsl.Composable;
> import com.softsynth.jmsl.EventScheduler;
> import com.softsynth.jmsl.JMSL;
> import com.softsynth.jmsl.JMSLMixerContainer;
> import com.softsynth.jmsl.JMSLRandom;
> import com.softsynth.jmsl.MusicShape;
> import com.softsynth.jmsl.Playable;
> import com.softsynth.jmsl.SequentialCollection;
> import com.softsynth.jmsl.midi.MidiIO_JavaSound;
> import com.softsynth.jmsl.midi.MidiInstrument;
>
> public class SequenceTest extends JApplet {
>
> private JMSLMixerContainer mixer;
> private MidiInstrument ins;
> private MusicShape ms;
> private SequentialCollection sequenceCol;
> private JCheckBoxMenuItem sequencePlayCB;
> private JMenuItem moveMi, nextMi, prevMi, addMi, insertMi, removeMi, 
> midiOutMi;
> private JButton position;
> private JLabel program;
> private int currentSequence;
>
> private String[] programNames = {
> "1 Acoustic Grand Piano",
> "2 Bright Acoustic Piano", "3 Electric Grand Piano",
> "4 Honky-tonk Piano", "5 Electric Piano 1", "6 Electric Piano 2",
> "7 Harpsichord", "8 Clavinet", "9 Celesta", "10 Glockenspiel",
> "11 Music Box", "12 Vibraphone", "13 Marimba", "14 Xylophone",
> "15 Tubular Bells", "16 Dulcimer", "17 Drawbar Organ",
> "18 Percussive Organ", "19 Rock Organ", "20 Church Organ",
> "21 Reed Organ", "22 Accordion", "23 Harmonica",
> "24 Tango Accordion", "25 Acoustic Guitar (nylon)",
> "26 Acoustic Guitar (steel)", "27 Electric Guitar (jazz)",
> "28 Electric Guitar (clean)", "29 Electric Guitar (muted)",
> "30 Overdriven Guitar", "31 Distortion Guitar",
> "32 Guitar harmonics", "33 Acoustic Bass",
> "34 Electric Bass (finger)", "35 Electric Bass (pick)",
> "36 Fretless Bass", "37 Slap Bass 1", "38 Slap Bass 2",
> "39 Synth Bass 1", "40 Synth Bass 2", "41 Violin", "42 Viola",
> "43 Cello", "44 Contrabass", "45 Tremolo Strings",
> "46 Pizzicato Strings", "47 Orchestral Harp", "48 Timpani",
> "49 String Ensemble 1", "50 String Ensemble 2",
> "51 Synth Strings 1", "52 Synth Strings 2", "53 Choir Aahs",
> "54 Voice Oohs", "55 Synth Voice", "56 Orchestra Hit",
> "57 Trumpet", "58 Trombone", "59 Tuba", "60 Muted Trumpet",
> "61 French Horn", "62 Brass Section", "63 Synth Brass 1",
> "64 Synth Brass 2", "65 Soprano Sax", "66 Alto Sax",
> "67 Tenor Sax", "68 Baritone Sax", "69 Oboe", "70 English Horn",
> "71 Bassoon", "72 Clarinet", "73 Piccolo", "74 Flute",
> "75 Recorder", "76 Pan Flute", "77 Blown Bottle", "78 Shakuhachi",
> "79 Whistle", "80 Ocarina", "81 Lead 1 (square)",
> "82 Lead 2 (sawtooth)", "83 Lead 3 (calliope)",
> "84 Lead 4 (chiff)", "85 Lead 5 (charang)", "86 Lead 6 (voice)",
> "87 Lead 7 (fifths)", "88 Lead 8 (bass + lead)",
> "89 Pad 1 (new age)", "90 Pad 2 (warm)", "91 Pad 3 (polysynth)",
> "92 Pad 4 (choir)", "93 Pad 5 (bowed)", "94 Pad 6 (metallic)",
> "95 Pad 7 (halo)", "96 Pad 8 (sweep)", "97 FX 1 (rain)",
> "98 FX 2 (soundtrack)", "99 FX 3 (crystal)",
> "100 FX 4 (atmosphere)", "101 FX 5 (brightness)",
> "102 FX 6 (goblins)", "103 FX 7 (echoes)", "104 FX 8 (sci-fi)",
> "105 Sitar", "106 Banjo", "107 Shamisen", "108 Koto",
> "109 Kalimba", "110 Bag pipe", "111 Fiddle", "112 Shanai",
> "113 Tinkle Bell", "114 Agogo", "115 Steel Drums", "116 Woodblock",
> "117 Taiko Drum", "118 Melodic Tom", "119 Synth Drum",
> "120 Reverse Cymbal", "121 Guitar Fret Noise", "122 Breath Noise",
> "123 Seashore", "124 Bird Tweet", "125 Telephone Ring",
> "126 Helicopter", "127 Applause", "128 Gunshot"
> };
>
> public SequenceTest() {
> super();
> start();
> }
>
> public void start() {
> synchronized (JMSL.class) {
> initJMSL();
> initMixer();
> initInstrument();
> buildCollection();
> initMusicShape();
> buildGUI();
> }
> }
>
> public void stop() {
> synchronized (JMSL.class) {
> removeAll();
> sequenceCol.finishAll();
> try {
> sequenceCol.waitForDone();
> } catch (InterruptedException e) {
> e.printStackTrace();
> }
> mixer.stop();
> JMSL.scheduler.stop();
> JMSL.closeMusicDevices();
> }
> }
>
> private void initJMSL() {
> JMSL.setViewFactory(new ViewFactorySwing());
> JMSL.scheduler = new EventScheduler();
> JMSL.scheduler.start();
> JMSL.clock.setAdvance(0.1);
> JMSLRandom.randomize();
> JMSL.midi = MidiIO_JavaSound.instance();
> JMSL.midi.open();
> }
>
> private void initMixer() {
> mixer = new JMSLMixerContainer();
> mixer.start();
> }
>
> private void initInstrument() {
> ins = new MidiInstrument(1, 0);
> ins.setProgram(10);
> mixer.addInstrument(ins);
> mixer.panAmpChange(0, 0.5, 1.0);
> }
>
> private void buildCollection() {
> sequenceCol = new SequentialCollection();
> sequenceCol.setRepeats(Integer.MAX_VALUE);
> sequenceCol.addRepeatPlayable(new SequenceRepeatPlayable());
> sequenceCol.addStopPlayable(new SequenceStopPlayable());
> }
>
> private void initMusicShape() {
> ms = new MusicShape(ins.getDimensionNameSpace());
> ms.useStandardDimensionNameSpace();
> ms.setInstrument(ins);
> sequenceCol.add(generate());
> }
>
> private void buildGUI() {
> setName("Random");
> setSize(640, 480);
> setLayout(new BorderLayout());
>
> JMenuBar mb = new JMenuBar();
> setJMenuBar(mb);
> JMenu m;
> JButton bt;
> mb.add(m = new JMenu("Action"));
> m.setMnemonic(KeyEvent.VK_A);
>
> m.add(sequencePlayCB = new JCheckBoxMenuItem("Play"));
> sequencePlayCB.setMnemonic(KeyEvent.VK_P);
> sequencePlayCB.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0));
> sequencePlayCB.addItemListener(new ItemListener() {
> public void itemStateChanged(ItemEvent e) {
> if (sequencePlayCB.getState()) {
> playSequence();
> } else {
> stopSequence();
> }
> }
> });
>
> m.add(moveMi = new JMenuItem("Go..."));
> moveMi .setMnemonic(KeyEvent.VK_G);
> moveMi .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, 0));
> moveMi .addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> String str = JOptionPane.showInputDialog(null, "Enter a new position: 
> ", "New Position", 1);
> if (str == null) return;
> int n = 0;
> try {n = Integer.parseInt(str);
> } catch (NumberFormatException error) {return;}
> move(n-1);
> }
> });
>
> m.add(prevMi = new JMenuItem("Previous"));
> prevMi .setMnemonic(KeyEvent.VK_V);
> prevMi .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, 0));
> prevMi .addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> prevSequence();
> }
> });
>
> m.add(nextMi = new JMenuItem("Next"));
> nextMi .setMnemonic(KeyEvent.VK_N);
> nextMi .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0));
> nextMi .addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> nextSequence();
> }
> });
>
> m.add(addMi = new JMenuItem("Add"));
> addMi .setMnemonic(KeyEvent.VK_A);
> addMi .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0));
> addMi .addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> addSequence();
> }
> });
>
> m.add(insertMi = new JMenuItem("Insert"));
> insertMi .setMnemonic(KeyEvent.VK_I);
> insertMi .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, 0));
> insertMi .addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> insertSequence();
> }
> });
>
> m.add(removeMi = new JMenuItem("Remove"));
> removeMi .setMnemonic(KeyEvent.VK_R);
> removeMi .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0));
> removeMi .addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> removeSequence();
> }
> });
>
> int ctrl = InputEvent.CTRL_MASK;
> m.add(midiOutMi = new JMenuItem("Midi Output"));
> midiOutMi .setMnemonic(KeyEvent.VK_O);
> midiOutMi .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ctrl));
> midiOutMi .addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> JMSL.midi.edit(new java.awt.Frame());
> mixer.panAmpChange(0, 0.5, 1.0);
> }
> });
>
> add(position = new JButton("" + (currentSequence+1) + "/" + 
> sequenceCol.size()), BorderLayout.NORTH);
> position.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> moveMi.


> ();
> }
> });
>
> JPanel p = new JPanel();
> p.setLayout(new GridLayout(2,3));
> p.setVisible(true);
> add(p, BorderLayout.CENTER);
>
> p.add(bt = new JButton("Play"));
> bt.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> sequencePlayCB.doClick();
> }
> });
>
> p.add(bt = new JButton("<--"));
> bt.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> prevMi.doClick();
> }
> });
>
> p.add(bt = new JButton("-->"));
> bt.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> nextMi.doClick();
> }
> });
>
> p.add(bt = new JButton("Add"));
> bt.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> addMi.doClick();
> }
> });
>
> p.add(bt = new JButton("Insert"));
> bt.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> insertMi.doClick();
> }
> });
>
> p.add(bt = new JButton("Remove"));
> bt.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> removeMi.doClick();
> }
> });
>
> JPanel midi = new JPanel();
> midi.setLayout(new BorderLayout());
> midi.setVisible(true);
> add(midi, BorderLayout.SOUTH);
>
> midi.add(program = new JLabel 
> (programNames[((MidiInstrument)ms.getInstrument()).getProgram()]), 
> BorderLayout.CENTER);
>
> midi.add(bt = new JButton("-"), BorderLayout.WEST);
> bt.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> int p = ((MidiInstrument)ms.getInstrument()).getProgram()-1;
> if (p > 0) {
> ((MidiInstrument)ms.getInstrument()).setProgram(p);
> program.setText(programNames[p]);
> }
> }
> });
>
> midi.add(bt = new JButton("+"), BorderLayout.EAST);
> bt.addActionListener(new ActionListener() {
> public void actionPerformed(ActionEvent e) {
> int p = ((MidiInstrument)ms.getInstrument()).getProgram()+1;
> if (p < 127) {
> ((MidiInstrument)ms.getInstrument()).setProgram(p);
> program.setText(programNames[p]);
> }
> }
> });
>
> validate();
> setVisible(true);
> }
>
> private void playSequence() {
> if (sequenceCol.size() > 0) {
>
> sequenceCol.setBehavior(new SequentialCursorBehavior(currentSequence));
> sequenceCol.launch(JMSL.now(), null);
> }
> }
>
> private void stopSequence() {
> sequenceCol.finishAll();
> updatePosition();
> }
>
> private void prevSequence() {
> move(currentSequence-2);
> }
>
> private void nextSequence() {
> move(currentSequence+1);
> }
>
> private void insertSequence() {
> sequenceCol.insert(generate(), currentSequence);
> updatePosition();
> }
>
> private void addSequence() {
> sequenceCol.add(generate());
> updatePosition();
> }
>
> private MusicShape generate() {
> MusicShape temp = (MusicShape) ms.clone();
> temp.removeAll();
> temp.add(0.25, JMSLRandom.choose(60, 88), 127, 0.25);
> temp.add(0.75, JMSLRandom.choose(60, 88), 127, 0.25);
> return temp;
> }
>
> private void removeSequence() {
> if (sequenceCol.size() > 0) {
> if (currentSequence >= sequenceCol.size() - 1)
> currentSequence=sequenceCol.size() - 1;
> sequenceCol.remove(currentSequence);
> if (currentSequence >= sequenceCol.size() - 1)
> currentSequence = sequenceCol.size() - 1;
> }
> }
>
> private void updatePosition() {
> position.setText("" + (currentSequence+ 1) + "/" + sequenceCol.size());
> }
>
> private void move(int n) {
> if (n >= 0 && n < sequenceCol.size()) {
> if (sequencePlayCB.getState() == true) {
> sequenceCol.finishAll();
> try {
> sequenceCol.waitForDone();
> } catch (InterruptedException e) {
> e.printStackTrace();
> }
> currentSequence = n;
> sequenceCol.setBehavior(new SequentialCursorBehavior(currentSequence));
> sequenceCol.launch(JMSL.now(), null);
> }
> else {
> currentSequence = n;
> updatePosition();
> }
> }
> }
>
> public static void main(String[] args) {
> JFrame frame = new JFrame("Sequence Test");
> frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
> frame.setSize(680, 480);
> frame.add(new SequenceTest());
> frame.pack();
> frame.validate();
> frame.setVisible(true);
> }
>
> class SequenceRepeatPlayable implements Playable {
> public double play(double playTime, Composable thing) throws 
> InterruptedException {
> SequentialCollection col = (SequentialCollection)thing;
> SequentialCursorBehavior behavior = 
> (SequentialCursorBehavior)col.getBehavior();
> if (behavior.getOriginalPosition() == behavior.getCurrentPosition()) {
> sequencePlayCB.doClick();
> }
> return playTime;
> }
> }
>
> class SequenceStopPlayable implements Playable {
> public double play(double playTime, Composable thing) throws 
> InterruptedException {
> SequentialCollection col = (SequentialCollection)thing;
> SequentialCursorBehavior behavior = 
> (SequentialCursorBehavior)col.getBehavior();
> currentSequence = behavior.getOriginalPosition();
> return playTime;
> }
> }
>
> class SequentialCursorBehavior implements Behavior {
>
> int currentPosition;
> int originalPosition;
>
> public int getCurrentPosition() {
> return currentPosition;
> }
>
> public void setCurrentPosition(int currentPosition) {
> this.currentPosition = currentPosition;
> }
>
> public int getOriginalPosition() {
> return originalPosition;
> }
>
> public SequentialCursorBehavior(int pos) {
> this.currentPosition = pos;
> this.originalPosition = pos;
> }
>
> public Composable choose(SequentialCollection col) {
> Composable nextChild = col.get(currentPosition);
> updatePosition();
> if (currentPosition == col.size() - 1) {
> currentPosition = originalPosition;
> }
> else {
> currentPosition++;
> }
> currentSequence=currentPosition;
>
> return nextChild;
> }
> }
>
> }
>
> _______________________________________________
> jmsl mailing list
> jmsl at music.columbia.edu
> http://music.columbia.edu/mailman/listinfo/jmsl


More information about the jmsl mailing list