/* * Created on Jan 3, 2005 * */ package jmslexamples.simple; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JLabel; import com.softsynth.jmsl.EventScheduler; import com.softsynth.jmsl.Instrument; import com.softsynth.jmsl.JMSL; import com.softsynth.jmsl.JMSLMixerContainer; import com.softsynth.jmsl.JMSLRandom; import com.softsynth.jmsl.MusicShape; import com.softsynth.jmsl.jsyn2.JSynMusicDevice; import com.softsynth.jmsl.jsyn2.JSynUnitVoiceInstrument; /** * Play timbral input ports of a JSyn UnitVoice with a MusicShape * * Upgraded to JSyn2 API Dec 6, 2016 * * @author Nick Didkovsky, nick@didkovsky.com * */ public class TimbralMusicShape extends JFrame { JMSLMixerContainer mixer; Instrument instrument; MusicShape myMusicShape; public void start() { initJMSL(); initMusicDevices(); buildMixer(); buildInstrument(); buildMusicShape(); launchMusicShape(); } private void launchMusicShape() { myMusicShape.launch(JMSL.now()); } private void buildInstrument() { instrument = new JSynUnitVoiceInstrument(8, com.jsyn.instruments.SubtractiveSynthVoice.class.getName()); mixer.addInstrument(instrument); } private void initMusicDevices() { JSynMusicDevice.instance().open(); } private void buildMixer() { mixer = new JMSLMixerContainer(); mixer.start(); } private void initJMSL() { JMSL.scheduler = new EventScheduler(); JMSL.scheduler.start(); JMSL.clock.setAdvance(0.3); } void buildMusicShape() { myMusicShape = new MusicShape(instrument.getDimensionNameSpace()); myMusicShape.setInstrument(instrument); myMusicShape.print(); // we happen to know that some of the timbral ports of SubtractiveSynthVoice are // named "FilterAttack", // "AmpAttack", "Q", and "Cutoff",but we don't know which dimension numbers they // are mapped to. // That's ok because we can use getDimension(dimname) to retrieve the dim #. // // Note that if you don't know the names of the dimensions and their ranges, // just print() the MusicShape after you create it from the instrument's // dimensionNameSpace as is done above int dimensionOfAmpAttack = myMusicShape.getDimension("AmpAttack"); int dimensionOfFilterAttack = myMusicShape.getDimension("FilterAttack"); int dimensionOfCutoff = myMusicShape.getDimension("Cutoff"); int dimensionOfQ = myMusicShape.getDimension("Q"); for (int i = 0; i < 25; i++) { double duration = 1.0; double pitch = JMSLRandom.choose(40.0, 45.0); double amplitude = 0.5; double hold = 3.0; double ampAttack = JMSLRandom.choose(0.5, 7.9); double filterAttack = JMSLRandom.choose(0.5, 7.9); double q = JMSLRandom.choose(0.05, 10.0); double cutoff = JMSLRandom.choose(500, 5000); // we don't want to specify every dimension, so get the default array // and poke values into it for the dimensions we want. The rest will have good // preset values. double[] data = myMusicShape.getDefaultArray(); data[0] = duration; data[1] = pitch; data[2] = amplitude; data[3] = hold; data[dimensionOfCutoff] = cutoff; data[dimensionOfAmpAttack] = ampAttack; data[dimensionOfFilterAttack] = filterAttack; data[dimensionOfQ] = q; myMusicShape.add(data); } myMusicShape.print(); myMusicShape.setRepeatPause(5); myMusicShape.setRepeats(5); } public void stop() { myMusicShape.finishAll(); try { myMusicShape.waitForDone(); } catch (InterruptedException e) { e.printStackTrace(); } JMSL.scheduler.stop(); JMSL.closeMusicDevices(); } public static void main(String[] args) { TimbralMusicShape demo = new TimbralMusicShape(); demo.add(new JLabel("There is no GUI for this demo.", JLabel.CENTER)); demo.setSize(800, 200); demo.setVisible(true); demo.start(); demo.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { demo.stop(); System.exit(0); } }); } }