/* * Created by Nick on Nov 12, 2004 * */ package jmslexamples.jsyn2; import java.awt.BorderLayout; import java.awt.Button; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JPanel; import com.jsyn.swing.JAppletFrame; import com.softsynth.jmsl.Instrument; import com.softsynth.jmsl.JMSL; import com.softsynth.jmsl.JMSLMixerContainer; import com.softsynth.jmsl.JMSLRandom; import com.softsynth.jmsl.MusicDevice; import com.softsynth.jmsl.MusicJob; import com.softsynth.jmsl.MusicShape; import com.softsynth.jmsl.PlayLurker; import com.softsynth.jmsl.jsyn2.JSynMusicDevice; import com.softsynth.jmsl.jsyn2.JSynUnitVoiceInstrument; import com.softsynth.jmsl.jsyn2.unitvoices.FilteredSawtoothBL; import jmslexamples.jsyn2.unitvoices.FMVoice; /** * PlayLurker is notified of the elements of a MusicShape as it is being played. * * This example uses a PlayLurker to listen in on elements of a MusicShape being * played, and for each element played, PlayLurker generates and launches a * MusicShape of its own based on the pitch of the element is being notified * about. * * @author Nick Didkovsky, (c) 2004 All rights reserved, Email: * nick@didkovsky.com * */ public class PlayLurkingArpeggiatorExample extends JFrame implements ActionListener { JMSLMixerContainer mixer; Button launchButton; Button finishButton; MusicShape melodyMusicShape; public void start() { initJMSL(); // melody JSynUnitVoiceInstrument ins = new JSynUnitVoiceInstrument(8, FilteredSawtoothBL.class.getName()); melodyMusicShape = new MusicShape(ins.getDimensionNameSpace()); melodyMusicShape.setInstrument(ins); melodyMusicShape.prefab(); melodyMusicShape.setRepeats(Integer.MAX_VALUE); melodyMusicShape.setTimeStretch(3); melodyMusicShape.print(); // arpeggiating PlayLurker ArpeggiatingPlayLurker lurker = new ArpeggiatingPlayLurker(); melodyMusicShape.addPlayLurker(lurker); lurker.setInstrument(new JSynUnitVoiceInstrument(8, FMVoice.class.getName(), FMVoice.PRESET_WOODDRUM)); // pan instruments L/R mixer = new JMSLMixerContainer(); mixer.start(); mixer.addInstrument(ins, 0, 0.3); mixer.addInstrument(lurker.getInstrument(), 1, 0.8); JPanel p = new JPanel(); p.setLayout(new FlowLayout()); p.add(launchButton = new Button("Launch")); p.add(finishButton = new Button("Finish")); setLayout(new BorderLayout()); add(BorderLayout.NORTH, p); add(BorderLayout.SOUTH, mixer.getPanAmpControlPanel()); launchButton.addActionListener(this); finishButton.addActionListener(this); } private void initJMSL() { JMSLRandom.randomize(); JMSL.clock.setAdvance(0.3); MusicDevice dev = JSynMusicDevice.instance(); dev.open(); } public void stop() { melodyMusicShape.finishAll(); JMSL.closeMusicDevices(); } public void actionPerformed(ActionEvent ev) { Object source = ev.getSource(); if (source == launchButton) { melodyMusicShape.launch(JMSL.now()); launchButton.setEnabled(false); finishButton.setEnabled(true); } if (source == finishButton) { melodyMusicShape.finishAll(); launchButton.setEnabled(true); finishButton.setEnabled(false); } } public static void main(String[] args) { PlayLurkingArpeggiatorExample demo = new PlayLurkingArpeggiatorExample(); demo.start(); demo.pack(); demo.setVisible(true); demo.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { JMSL.closeMusicDevices(); System.exit(0); } }); } } class ArpeggiatingPlayLurker implements PlayLurker { private Instrument instrument; /** Pull the pitch from the MusicShape's element and arpeggiate it */ public void notifyPlayLurker(double playTime, MusicJob list, int index) { System.out.println("PlayLurker notified of element " + index + ", and is launching a flourish"); MusicShape s = (MusicShape) list; double[] data = s.get(index); double pitch = data[1]; double amp = data[2]; MusicShape gesture = new MusicShape(4); int numArps = JMSLRandom.choose(2, 8); double dur = JMSLRandom.choose(0.1, 0.15); gesture.setStartDelay(dur); int direction = JMSLRandom.choose() < 0.5 ? 1 : -1; for (int i = 0; i <= numArps; i++) { pitch += 12.0 / numArps * direction; gesture.add(dur, pitch, amp - (amp / numArps * i), dur * 0.8); } gesture.setInstrument(instrument); gesture.launch(playTime); } public Instrument getInstrument() { return instrument; } public void setInstrument(Instrument instrument) { this.instrument = instrument; } }