/* * Created by Nick on Jan 3, 2005 * */ package jmslexamples.jsyn2; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import com.softsynth.jmsl.DimensionNameSpace; import com.softsynth.jmsl.Instrument; import com.softsynth.jmsl.JMSL; import com.softsynth.jmsl.JMSLMixerContainer; import com.softsynth.jmsl.MusicJob; import com.softsynth.jmsl.MusicShape; import com.softsynth.jmsl.ParallelCollection; import com.softsynth.jmsl.jsyn2.JSynMusicDevice; import com.softsynth.jmsl.jsyn2.JSynUnitVoiceInstrument; /** * Use instrument.update() to gliss pitch * * Set two glisses going in opposite directions, both starting from pitch 60 * * This used to be a little clunky with the old JSyn API. The new JSyn2 API * makes it very easy to turn an instrument on(), update() its parameters, * including its pitch while it is sustaining, then turn it off(). JSyn2 and * JMSL use voice tokens to retrieve the UnitVoices allocated by the polyphonic * instrument when on() is called, so that update() and off() can reference the * proper voice. * * Updated to JSyn2 API Dec 2016 * * * @author Nick Didkovsky, (c) 2004 All rights reserved, Email: * nick@didkovsky.com * */ public class PitchGliss extends JFrame { JMSLMixerContainer mixer; Instrument ins; ParallelCollection par; public void start() { initJMSL(); initMusicDevices(); buildMixer(); buildInstrument(); buildGlisser(); launchGliss(); } private void buildGlisser() { GlissingMusicJob glisser = new GlissingMusicJob(); glisser.setRepeats(100); glisser.setInstrument(ins); glisser.setDirection(-1); double[] data1 = new MusicShape(ins.getDimensionNameSpace()).getDefaultArray(); data1[1] = 60; glisser.setData(data1); GlissingMusicJob glisser2 = new GlissingMusicJob(); glisser2.setRepeats(100); glisser2.setInstrument(ins); glisser2.setDirection(1); double[] data2 = new MusicShape(ins.getDimensionNameSpace()).getDefaultArray(); data2[1] = 60; glisser2.setData(data2); par = new ParallelCollection(); par.add(glisser); par.add(glisser2); } private void initJMSL() { JMSL.clock.setAdvance(0.3); } private void initMusicDevices() { JSynMusicDevice.instance().open(); } private void buildMixer() { mixer = new JMSLMixerContainer(); mixer.start(); } private void buildInstrument() { ins = new JSynUnitVoiceInstrument(8, com.softsynth.jmsl.jsyn2.unitvoices.FilteredSawtoothBL.class.getName()); 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 static void main(String[] args) { PitchGliss demo = new PitchGliss(); demo.start(); demo.pack(); demo.setVisible(true); demo.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { JMSL.closeMusicDevices(); System.exit(0); } }); } } /** * This musicjob is responsible for calling update() repeatedly on the * instrument to achieve one gliss. Maintains the voicetoken returned by on() so * update() and off() can retrieve the voice allocated by the polyphonic * instrument. */ class GlissingMusicJob extends MusicJob { double[] data; int direction; int myVoiceToken; public void setData(double[] d) { this.data = d; } public void setDirection(int i) { this.direction = i; } public double start(double playTime) { Object obj = getInstrument().on(playTime, 1.0, data); myVoiceToken = ((Integer) obj).intValue(); return playTime + 0.1; } public double repeat(double playTime) { // change pitch a little data[1] += 0.1 * direction; JMSL.printDoubleArray(data); ((JSynUnitVoiceInstrument) getInstrument()).update(playTime, 1.0, data, myVoiceToken); return playTime + 0.1; } public double stop(double playTime) { ((JSynUnitVoiceInstrument) getInstrument()).off(playTime, myVoiceToken); return playTime + 0.1; } }