/* * Created on Nov 24, 2005 by Nick Didkovsky * */ package jmslexamples.jsyn; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import com.softsynth.jmsl.*; import com.softsynth.jmsl.jsyn.JSynMusicDevice; import com.softsynth.jmsl.jsyn.SimpleSamplePlayingInstrument; import com.softsynth.jmsl.score.Tempo; /** * Use QueueCollection to queue up three different drum beats interactively. Each click of a button * queues up one of the drum beats. The QueueCollection keeps playing these beats as they are added, * looping on the last one added. * * DrumInstrument plays drums samples that ship with JMSL, using MusicShapes that were exported from * JMSL Score. * * A QueueCollection plays composables in the order they are added, and removes each after being * played. It loops the last Composable rather than emptying itself completely. * * The drum beats in this example are excerpted from "Overlife #1", composed by Nick Didkovsky for * Steven Schick and ND, commissioned by John Malashock Dance Company. These drum excerpts are (c) * 2000 Nick Didkovsky / Punos Music (BMI). Recorded by John Roulat, Hugh Hopper, and ND on the CD * BONE, "Uses Wrist Grab", Cuneiform Records www.cuneiformrecords.com * * @author Nick Didkovsky, (c) 2005 Nick Didkovsky, didkovn@mail.rockefeller.edu * * @see jmslexamples.jsyn.QueueCollectionDemo */ public class QueueCollectionDrumBeats extends java.applet.Applet implements ActionListener { MusicShape beat1; MusicShape beat2; MusicShape beat3; QueueCollection queueCollection; SimpleSamplePlayingInstrument drumInstrument; Button queueBeat0Button; Button queueBeat1Button; Button queueBeat2Button; Button launchButton; Button finishButton; JMSLMixerContainer mixer; Label queueSizeLabel; /** Applet.start() */ public void start() { synchronized (JMSL.class) { initJMSL(); initMusicDevices(); buildGUI(); buildDrumInstrument(); buildMixer(); buildComposables(); } } private void buildGUI() { setLayout(new BorderLayout()); Panel p = new Panel(); p.setLayout(new FlowLayout(FlowLayout.CENTER)); p.add(queueBeat0Button = new Button("Queue Beat 1")); p.add(queueBeat1Button = new Button("Queue Beat 2")); p.add(queueBeat2Button = new Button("Queue Beat 3")); p.add(launchButton = new Button("Launch")); p.add(finishButton = new Button("Finish")); finishButton.setEnabled(false); add(BorderLayout.NORTH, p); add(BorderLayout.SOUTH, queueSizeLabel = new Label("queue size = 1")); queueBeat0Button.addActionListener(this); queueBeat1Button.addActionListener(this); queueBeat2Button.addActionListener(this); launchButton.addActionListener(this); finishButton.addActionListener(this); } private void initJMSL() { JMSL.setIsApplet(true); JMSL.clock.setAdvance(0.1); JMSL.scheduler = new EventScheduler(); JMSL.scheduler.start(); JMSL.setIsApplet(true); JMSL.setCodeBase(this.getCodeBase()); } void initMusicDevices() { JSynMusicDevice.instance().edit(new Frame()); JSynMusicDevice.instance().open(); } private void buildMixer() { mixer = new JMSLMixerContainer(); mixer.start(); mixer.addInstrument(drumInstrument); mixer.panAmpChange(0, 0, 1); mixer.panAmpChange(1, 1, 1); } private void buildDrumInstrument() { drumInstrument = new SimpleSamplePlayingInstrument(); drumInstrument.setNumChannels(2); drumInstrument.addSamplePitch("LeoDidkovskyDrums_stereo/LeoKick.aif", 62); drumInstrument.addSamplePitch("LeoDidkovskyDrums_stereo/LeoFloorTom.aif", 69); drumInstrument.addSamplePitch("LeoDidkovskyDrums_stereo/LeoSnare.aif", 72); drumInstrument.addSamplePitch("LeoDidkovskyDrums_stereo/LeoHalfOpenHihat.aif", 81); drumInstrument.addSamplePitch("LeoDidkovskyDrums_stereo/LeoCrash.aif", 84); drumInstrument.buildFromAttributes(); } private void buildComposables() { buildBeats(); buildQueueCollection(); setTempo(); } private void buildBeats() { buildBeat1(); buildBeat2(); buildBeat3(); } private void buildQueueCollection() { queueCollection = new QueueCollection(); queueCollection.setRepeats(Integer.MAX_VALUE); // play forever queueCollection.add(beat1); // update a Label indicating how many children are in queueCollection every time it repeats queueCollection.addRepeatPlayable(new Playable() { public double play(double time, Composable parent) throws InterruptedException { updateQueueLabel(); return time; } }); } /** * convert from 90 beats per minute to a timeStretch value to queueCollection plays at desired * tempo */ private void setTempo() { Tempo tempo = new Tempo(90); double timeStretch = tempo.getTimeStretch(); queueCollection.setTimeStretch(timeStretch); System.out.println("timeStretch=" + timeStretch); } /** * Drum beat from Overlife #1 composed by Nick Didkovsky, commissioned by John Malashock Dance * Company, (C) 2000 Nick Didkovsky / Punos Music (BMI) Recorded on the CD BONE, "Uses Wrist * Grab", Cuneiform Records www.cuneiformrecords.com */ void buildBeat1() { beat1 = new MusicShape(4); beat1.setDimensionName(0, "duration"); beat1.setDimensionName(1, "pitch"); beat1.setDimensionName(2, "amplitude"); beat1.setDimensionName(3, "hold"); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.25, 0.0, 0.0, 0.2); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.25, 0.0, 0.0, 0.2); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.5, 69.0, 0.8, 0.4); beat1.add(0.75, 69.0, 0.8, 0.6000000000000001); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.5, 69.0, 0.8, 0.4); beat1.add(0.5, 69.0, 0.8, 0.4); beat1.add(0.3333333333333333, 69.0, 0.8, 0.26666666666666666); beat1.add(0.3333333333333333, 69.0, 0.8, 0.26666666666666666); beat1.add(0.3333333333333333, 69.0, 0.8, 0.26666666666666666); beat1.add(0.75, 69.0, 0.8, 0.6000000000000001); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.25, 69.0, 0.8, 0.2); beat1.add(0.75, 69.0, 0.8, 0.6000000000000001); beat1.setInstrument(drumInstrument); beat1.setName("Beat 1"); } /** * Drum beat from Overlife #1 composed by Nick Didkovsky, commissioned by John Malashock Dance * Company, (C) 2000 Nick Didkovsky / Punos Music (BMI) Recorded on the CD BONE, "Uses Wrist * Grab", Cuneiform Records www.cuneiformrecords.com */ void buildBeat2() { beat2 = new MusicShape(4); beat2.setDimensionName(0, "duration"); beat2.setDimensionName(1, "pitch"); beat2.setDimensionName(2, "amplitude"); beat2.setDimensionName(3, "hold"); beat2.add(0.0, 69.0, 0.8, 0.2); beat2.add(0.0, 84.0, 0.8, 0.2); beat2.add(0.25, 62.0, 0.8, 0.2); beat2.add(0.25, 69.0, 0.8, 0.2); beat2.add(0.25, 69.0, 0.8, 0.2); beat2.add(0.25, 69.0, 0.8, 0.2); beat2.add(0.0, 81.0, 0.8, 0.2); beat2.add(0.25, 72.0, 0.8, 0.2); beat2.add(0.25, 69.0, 0.8, 0.2); beat2.add(0.25, 69.0, 0.8, 0.2); beat2.add(0.0, 69.0, 0.8, 0.2); beat2.add(0.25, 62.0, 0.8, 0.2); beat2.add(0.25, 81.0, 0.8, 0.2); beat2.add(0.0, 69.0, 0.8, 0.2); beat2.add(0.25, 62.0, 0.8, 0.2); beat2.add(0.25, 69.0, 0.8, 0.2); beat2.add(0.25, 62.0, 0.8, 0.2); beat2.add(0.0, 72.0, 0.8, 0.2); beat2.add(0.0, 81.0, 0.8, 0.2); beat2.add(0.25, 69.0, 0.8, 0.2); beat2.add(0.5, 62.0, 0.8, 0.4); beat2.add(0.25, 69.0, 0.8, 0.2); beat2.add(0.0, 69.0, 0.8, 0.4); beat2.add(0.0, 81.0, 0.8, 0.4); beat2.add(0.5, 62.0, 0.8, 0.4); beat2.add(0.5, 69.0, 0.8, 0.4); beat2.add(0.0, 72.0, 0.8, 0.26666666666666666); beat2.add(0.0, 81.0, 0.8, 0.26666666666666666); beat2.add(0.3333333333333333, 69.0, 0.8, 0.26666666666666666); beat2.add(0.3333333333333333, 69.0, 0.8, 0.26666666666666666); beat2.add(0.3333333333333333, 69.0, 0.8, 0.26666666666666666); beat2.add(0.0, 72.0, 0.8, 0.2); beat2.add(0.0, 81.0, 0.8, 0.2); beat2.add(0.25, 69.0, 0.8, 0.2); beat2.add(0.5, 62.0, 0.8, 0.4); beat2.add(0.0, 69.0, 0.8, 0.2); beat2.add(0.25, 62.0, 0.8, 0.2); beat2.add(0.0, 81.0, 0.8, 0.2); beat2.add(0.25, 69.0, 0.8, 0.2); beat2.add(0.0, 69.0, 0.8, 0.2); beat2.add(0.25, 62.0, 0.8, 0.2); beat2.add(0.5, 72.0, 0.8, 0.4); beat2.setInstrument(drumInstrument); beat2.setName("Beat 2"); } /** * Drum beat from Overlife #1 composed by Nick Didkovsky, commissioned by John Malashock Dance * Company, (C) 2000 Nick Didkovsky / Punos Music (BMI) Recorded on the CD BONE, "Uses Wrist * Grab", Cuneiform Records www.cuneiformrecords.com */ void buildBeat3() { beat3 = new MusicShape(4); beat3.setDimensionName(0, "duration"); beat3.setDimensionName(1, "pitch"); beat3.setDimensionName(2, "amplitude"); beat3.setDimensionName(3, "hold"); beat3.add(0.0, 69.0, 0.8, 0.2); beat3.add(0.0, 84.0, 0.8, 0.2); beat3.add(0.25, 62.0, 0.8, 0.2); beat3.add(0.5, 69.0, 0.8, 0.4); beat3.add(0.25, 69.0, 0.8, 0.2); beat3.add(0.0, 72.0, 0.8, 0.6000000000000001); beat3.add(0.0, 81.0, 0.8, 0.6000000000000001); beat3.add(0.75, 69.0, 0.8, 0.6000000000000001); beat3.add(0.25, 62.0, 0.8, 0.2); beat3.add(0.0, 81.0, 0.8, 0.2); beat3.add(0.25, 69.0, 0.8, 0.2); beat3.add(0.0, 69.0, 0.8, 0.4); beat3.add(0.5, 62.0, 0.8, 0.4); beat3.add(0.0, 69.0, 0.8, 0.2); beat3.add(0.25, 62.0, 0.8, 0.2); beat3.add(0.0, 72.0, 0.8, 0.26666666666666666); beat3.add(0.0, 81.0, 0.8, 0.26666666666666666); beat3.add(0.3333333333333333, 69.0, 0.8, 0.26666666666666666); beat3.add(0.3333333333333333, 69.0, 0.8, 0.26666666666666666); beat3.add(0.3333333333333333, 69.0, 0.8, 0.26666666666666666); beat3.setInstrument(drumInstrument); beat3.setName("Beat 3"); } private void termJMSL() { JMSL.scheduler.stop(); JMSL.closeMusicDevices(); } /** Applet stop(), finish the queue collection, wait for it to be done, terminate JMSL */ public void stop() { synchronized (JMSL.class) { queueCollection.finishAll(); try { queueCollection.waitForDone(); } catch (InterruptedException e) { e.printStackTrace(); } removeAll(); termJMSL(); } } private void updateQueueLabel() { StringBuffer buf = new StringBuffer(); buf.append("queue size=" + queueCollection.size() + ": "); for (int i = 0; i < queueCollection.size(); i++) { buf.append(" " + queueCollection.get(i).getName()); if (i < queueCollection.size() - 1) { buf.append(","); } } queueSizeLabel.setText(buf.toString()); } public void actionPerformed(ActionEvent ev) { Object source = ev.getSource(); if (source == queueBeat0Button) { queueCollection.add(beat1); } if (source == queueBeat1Button) { queueCollection.add(beat2); } if (source == queueBeat2Button) { queueCollection.add(beat3); } if (source == launchButton) { queueCollection.launch(JMSL.now()); launchButton.setEnabled(false); finishButton.setEnabled(true); } if (source == finishButton) { queueCollection.finishAll(); launchButton.setEnabled(true); finishButton.setEnabled(false); } updateQueueLabel(); } }