/** * InsToot11.java * * Demonstrate SynthNoteAllPortsSP (Signal Processing) Instrument. * * Control all input ports of a SynthNote which has a SynthInput named "input" for signal processing * IMPORTANT: The Synthnote must have an input port defined called "input" * * This uses a SynthNote which defines a simple delay with feedback. * The SynthNote's frequency input is not connected and so, "pitch" dimension is ignored.* * * @author Nick Didkovsky * (C) 2003 Nick Didkovsky, All Rights Reserved * JMSL is based upon HMSL (C) Phil Burk, Larry Polansky and David Rosenboom. */ package jmsltutorial; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import com.softsynth.jmsl.*; import com.softsynth.jmsl.jsyn.*; import com.softsynth.jmsl.view.MusicShapeEditor; import com.softsynth.jsyn.AppletFrame; import com.softsynth.jsyn.SynthOutput; public class InsToot11 extends java.applet.Applet implements ActionListener { Button startButton; Button stopButton; String synthNoteClassName; String signalProcessingSynthNoteClassName; ParallelCollection parCol; MusicShape myShape; MusicShape signalProcessingMusicShape; SynthNoteAllPortsInstrument synthNoteInstrument; SynthNoteAllPortsInstrumentSP signalProcessingInstrument; JMSLMixerContainer mixer; public void init() { synthNoteClassName = "com.softsynth.jsyn.circuits.FilteredSawtoothBL"; signalProcessingSynthNoteClassName = "jmsltutorial.TootDelay"; } /** Handle some JSyn init's, build instruments and musicshapes */ public void start() { JMSL.setIsApplet(true); JSynMusicDevice.instance().open(); JMSL.clock.setAdvance(0.25); mixer = new JMSLMixerContainer(); mixer.start(); /* Instantiate instrument by specifying classname and polyphony */ synthNoteInstrument = new SynthNoteAllPortsInstrument(8, synthNoteClassName); synthNoteInstrument.setName("Source Ins"); // duration for each event randomly chosen up to 1.0 second myShape = buildShape(synthNoteInstrument, 1); /* Instantiate signal processing instrument by specifying classname and polyphony. Classname must have SynthInput named "input" defined */ signalProcessingInstrument = new SynthNoteAllPortsInstrumentSP(8, signalProcessingSynthNoteClassName); signalProcessingInstrument.setName("Signal Proc. Ins"); // duration for each event randomly chosen up to 6.0 seconds signalProcessingMusicShape = buildShape(signalProcessingInstrument, 6); // put both of these into a ParallelCollection parCol = new ParallelCollection(myShape, signalProcessingMusicShape); // connect the output of the instrument to the input of the signal processing instrument signalProcessingInstrument.addSignalSource((SynthOutput) synthNoteInstrument.getOutput()); mixer.addInstrument(synthNoteInstrument, 0, 0.5); // pan left, amp 0.5 mixer.addInstrument(signalProcessingInstrument, 1.0, 0.5); // pan right, amp 0.5 // now proceed with GUI layout: start / stop buttons and MusicShape editor setLayout(new BorderLayout()); Panel p = new Panel(); p.setLayout(new BorderLayout()); p.add(BorderLayout.WEST, startButton = new Button("START")); p.add(BorderLayout.EAST, stopButton = new Button("STOP")); add(BorderLayout.SOUTH, p); MusicShapeEditor se = new MusicShapeEditor(); se.addMusicShape(myShape); se.addMusicShape(signalProcessingMusicShape); add(BorderLayout.NORTH, se.getComponent()); add(BorderLayout.CENTER, mixer.getPanAmpControlPanel()); startButton.addActionListener(this); stopButton.addActionListener(this); /* Synchronize Java display. */ getParent().validate(); getToolkit().sync(); } /** Some JSyn term's, and shut down the MusicShape */ public void stop() { parCol.finishAll(); removeAll(); mixer.stop(); JMSL.closeMusicDevices(); } /** Build a MusicShape using standard names for dimensions: "duration", "pitch", "amplitude", "hold" * and randomize values for higher dimensions with values chosen between low and high limits for * these dimensions * */ MusicShape buildShape(Instrument instrument, double durationLimit) { // create a new MusicShape with the same DimensionNameSpace as the instrument MusicShape someShape = new MusicShape(instrument.getDimensionNameSpace()); someShape.print(); someShape.setRepeats(10000); someShape.setInstrument(instrument); for (int i = 0; i < 17; i++) { double[] data = new double[someShape.dimension()]; double duration = JMSLRandom.choose(durationLimit); double pitch = JMSLRandom.choose(40, 80); double amplitude = JMSLRandom.choose(0.5); double hold = duration * JMSLRandom.choose(2.0); data[0] = duration; data[1] = pitch; data[2] = amplitude; data[3] = hold; // we will choose random values for dimensions higher than 3 by using high/low limits for (int dim = 4; dim < someShape.dimension(); dim++) { double value = JMSLRandom.choose(someShape.getLowLimit(dim), someShape.getHighLimit(dim)); data[dim] = value; } someShape.add(data); } return someShape; } public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if (source == startButton) { parCol.launch(JMSL.now()); } if (source == stopButton) { parCol.finishAll(); } } /* Can be run as either an application or as an applet. */ public static void main(String args[]) { InsToot11 applet = new InsToot11(); AppletFrame frame = new AppletFrame("JMSL Tutorial", applet); frame.setSize(600, 500); frame.show(); frame.test(); } }