/* * Created by Nick on Nov 8, 2004 * */ package jmslexamples.jsyn; import com.softsynth.jmsl.*; import com.softsynth.jmsl.jsyn.JSynMusicDevice; import com.softsynth.jmsl.jsyn.SynthNoteAllPortsInstrument; import com.softsynth.jmsl.jsyn.circuits.FilteredSawtoothExpLag; /** * This examples shows how to use Instrument on(), update() and off() to start a sound, update its * timbre over time, then shut it down. Uses a MusicJob subclass to implement this by calling on() * in start(), update() in repeat(), and off() in stop() * * Notice that this sounds smooth even when update()s sends abruptly changing values because the * circuit has exponential lags before some of its input ports. * * @author Nick Didkovsky, (c) 2004 All rights reserved, Email: didkovn@mail.rockefeller.edu * */ public class SimpleTimbralEvolution extends java.applet.Applet { JMSLMixerContainer mixer; public void init() { } public void start() { JMSL.clock.setAdvance(0.1); MusicDevice dev = JSynMusicDevice.instance(); dev.edit(new java.awt.Frame()); dev.open(); mixer = new JMSLMixerContainer(); mixer.start(); makeAndLaunchJob(30); makeAndLaunchJob(30.5); } private void makeAndLaunchJob(double pitch) { SynthNoteAllPortsInstrument ins = new SynthNoteAllPortsInstrument(1, FilteredSawtoothExpLag.class.getName()); mixer.addInstrument(ins, JMSLRandom.choose(), 0.4); TimbreJob job = new TimbreJob(); job.setInstrument(ins); job.setPitch(pitch); job.setRepeats(100); job.setRepeatPause(1.0); job.launch(JMSL.now() + JMSLRandom.choose(2.0)); } public void stop() { JMSL.closeMusicDevices(); } } class TimbreJob extends MusicJob { // hold a copy of data to change on each repeat() double[] data; double pitch = 60; public void setPitch(double pitch) { this.pitch = pitch; } public double start(double playTime) { System.out.print(getName() + " start() calling instrument.on() " + playTime + " with data: "); if (getInstrument() != null && getInstrument().getDimensionNameSpace() != null) { data = MusicShape.getDefaultArray(getInstrument().getDimensionNameSpace()); int indexOfPitch = getInstrument().getDimensionNameSpace().getDimension("pitch"); data[indexOfPitch] = pitch; getInstrument().on(playTime, 1.0, data); JMSL.printDoubleArray(data); } return playTime; } public double repeat(double playTime) { System.out.print(getName() + " repeat() calling instrument.update() at playtime=" + playTime + ", data: "); if (data != null) { // update timbral dimensions for (int i = 4; i < data.length; i++) { double lowLimit = getInstrument().getDimensionNameSpace().getLowLimit(i); double highLimit = getInstrument().getDimensionNameSpace().getHighLimit(i); data[i] = JMSLRandom.choose(lowLimit, highLimit); } getInstrument().update(playTime, 1.0, data); JMSL.printDoubleArray(data); } return playTime; } public double stop(double playTime) { System.out.print(getName() + " stop() calling instrument.off() at playtime " + playTime); if (getInstrument() != null) { getInstrument().off(playTime, 1.0, data); } return playTime; } }