[jmsl] Navigating Sequential Sequence

jmsl at music.columbia.edu jmsl at music.columbia.edu
Wed Apr 29 06:45:20 EDT 2009


Very happy to hear it! Yours is an exciting project; and a lot of good 
JMSL development came out of it, most notably getting JavaSound MIDI to 
control external devices at last (which you report works from an applet 
no less! ... something I would have guessed would have been blocked by 
the applet security model)
Thanks
Nick

jmsl at music.columbia.edu wrote:
> Oh wow, that's so simple! Why didn't I think of that! Thanks a lot.
>
> Chi
> ----- Original Message ----- From: <jmsl at music.columbia.edu>
> To: <jmsl at music.columbia.edu>
> Sent: Tuesday, April 28, 2009 9:42 AM
> Subject: Re: [jmsl] Navigating Sequential Sequence
>
>
>> 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
>> _______________________________________________
>> jmsl mailing list
>> jmsl at music.columbia.edu
>> http://music.columbia.edu/mailman/listinfo/jmsl
>>
> _______________________________________________
> jmsl mailing list
> jmsl at music.columbia.edu
> http://music.columbia.edu/mailman/listinfo/jmsl


More information about the jmsl mailing list