/* * Created by Nick on Jan 3, 2005 * */ package jmslexamples.jsyn; import com.softsynth.jmsl.*; import com.softsynth.jmsl.jsyn.*; /** * Use instrument.update() to gliss pitch * * This is a little unusual because JMSL by default uses the pitch dimension to retrieve allocated * voices when ins.update() is called. So how to retrieve an allocated voice to change its pitch? * Use a different dimension to retrieve allocated synthnotes (here we use dim 0 which is normally * used for duration) as the 'update dimension', and plug your own lookup indexes into this * dimension * * Requires setting update dimension to something other than 1 (pitch). Here we use 0 (duration) * since we do not use duration in a meanigful way - we just call ins.on() , launch a music job that * updates pitch every repeat, and call ins.off() * * Set two glisses going in opposite directions, both starting from pitch 60 * * @author Nick Didkovsky, (c) 2004 All rights reserved, Email: didkovn@mail.rockefeller.edu * */ public class PitchGliss extends java.applet.Applet { JMSLMixerContainer mixer; Instrument ins; ParallelCollection par; public void init() { JMSL.setIsApplet(true); } public void start() { synchronized (JMSL.class) { initJMSL(); initMusicDevices(); buildMixer(); buildInstrument(); buildGlisser(); launchGliss(); } } private void buildGlisser() { GlissingMusicJob glisser = new GlissingMusicJob(); glisser.setRepeats(100); glisser.setInstrument(ins); glisser.setDirection(-1); double[] data1 = { 1, 60, 0.5, 0.1, 2000, 0.3, 1.0 }; // 1 in duration dimension as a lookup index!!! glisser.setData(data1); GlissingMusicJob glisser2 = new GlissingMusicJob(); glisser2.setRepeats(100); glisser2.setInstrument(ins); glisser2.setDirection(1); double[] data2 = { 2, 60, 0.5, 0.1, 3000, 0.2, 1.0 }; // 2 in duration dimension as a lookup index!!! glisser2.setData(data2); par = new ParallelCollection(); par.add(glisser); par.add(glisser2); } private void initJMSL() { JMSL.scheduler = new EventScheduler(); JMSL.scheduler.start(); JMSL.clock.setAdvance(0.1); } private void initMusicDevices() { JSynMusicDevice.instance().open(); } private void buildMixer() { mixer = new JMSLMixerContainer(); mixer.start(); } private void buildInstrument() { ins = new SynthNoteAllPortsInstrument(8, com.softsynth.jsyn.circuits.FilteredSawtoothBL.class.getName()); ((FreqSynthNoteInstrument) ins).setUpdateDimension(0); mixer.addInstrument(ins); DimensionNameSpace dns = ins.getDimensionNameSpace(); for (int i = 0; i < dns.dimension(); i++) { System.out.println(i + ", " + dns.getDimensionName(i)); } } private void launchGliss() { par.launch(JMSL.now()); } public void stop() { synchronized (JMSL.class) { par.finishAll(); try { par.waitForDone(); } catch (InterruptedException e) { e.printStackTrace(); } JMSL.scheduler.stop(); JMSL.closeMusicDevices(); } } } /** * This musicjob is responsible for calling update() repeatedly on the instrument to achieve one * gliss */ class GlissingMusicJob extends MusicJob { double[] data; int direction; public void setData(double[] d) { this.data = d; } public void setDirection(int i) { this.direction = i; } public double start(double playTime) { getInstrument().on(playTime, 1.0, data); return playTime + 0.1; } public double repeat(double playTime) { // change pitch a little data[1] += 0.1 * direction; JMSL.printDoubleArray(data); getInstrument().update(playTime, 1.0, data); return playTime + 0.1; } public double stop(double playTime) { getInstrument().off(playTime, 1.0, data); return playTime + 0.1; } }