/* * Created on Oct 5, 2003 * */ package jmslexamples.jsyn; import java.awt.*; import java.awt.event.*; import com.didkovsky.portview.PVButton; import com.didkovsky.portview.PVPanel; import com.softsynth.jmsl.*; import com.softsynth.jmsl.jsyn.JSynMusicDevice; import com.softsynth.jmsl.jsyn.SynthNoteAllPortsInstrument; import com.softsynth.jmsl.view.PVFrameAdapter; import com.softsynth.jmsl.view.PVPanelAdapter; /** * Full featured example of using JSyn SynthNote to play in JMSL. Note-by-note * control over SynthNote * * Play with MusicShapes generated randomly from synthnote's dimension name * space * * Also shows instrument with stereo output patched into mixer * * You will hear note-by-note autopanning rate changes and note-by-note timbral * changes * * @author Nick Didkovsky, email: didkovn@mail.rockefeller.edu, (c) 2003 Nick * Didkovsky, all rights reserved. * */ public class FullFeaturedSynthNoteSupport extends PVFrameAdapter implements ActionListener { MusicShape s1; MusicShape s2; ParallelCollection col; SynthNoteAllPortsInstrument ins1; SynthNoteAllPortsInstrument ins2; JMSLMixerContainer mixer; PVButton startButton; PVButton stopButton; public FullFeaturedSynthNoteSupport() { super("FullFeaturedSynthNoteSupport, (C) Nick Didkovsky, Close to quit"); setFrameLayout(new GridLayout(1, 0, 10, 10)); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { JMSL.closeMusicDevices(); System.exit(0); } }); } void initMusicDevices() { JSynMusicDevice.instance().edit((Frame) this.getComponent()); JSynMusicDevice.instance().open(); } void buildInstruments() { ins1 = new SynthNoteAllPortsInstrument(8, com.softsynth.jmsl.jsyn.circuits.AutopanningSawtooth.class.getName()); ins1.setName("Autopanner"); ins2 = new SynthNoteAllPortsInstrument(8, com.softsynth.jsyn.circuits.FilteredSawtoothBL.class.getName()); ins2.setName("Sawtooth"); } void buildMixer() { // add all your instruments to a generic mixer mixer = new JMSLMixerContainer(); mixer.addInstrument(ins1); mixer.addInstrument(ins2); // Here's how you can set pan/amp by hand // Note this the first instrument happens to be a stereo instrument, // so we pan faders 0 and 1 hard left, right mixer.panAmpChange(0, 0.0, 0.5); // faderIndex, pan value 0..1, amp 0..1 mixer.panAmpChange(1, 1.0, 0.5); mixer.start(); } void buildPerformance() { // Build a ParallelCollection of randomMusicShapes s1 = generateRandomMusicShape(ins1); s2 = generateRandomMusicShape(ins2); col = new ParallelCollection(); col.add(s1); col.add(s2); } void buildGUI() { PVPanel p = new PVPanelAdapter(); p.setLayout(new FlowLayout()); p.add((startButton = JMSL.getViewFactory().createButton("Start")).getComponent()); p.add((stopButton = JMSL.getViewFactory().createButton("Stop")).getComponent()); startButton.addActionListener(this); stopButton.addActionListener(this); stopButton.setEnabled(false); add(BorderLayout.SOUTH, p.getComponent()); add(BorderLayout.NORTH, mixer.getPanAmpControlPanel()); } /** * Generate a MusicShape with random data chosen between low and high limits * of upper dimensions */ public MusicShape generateRandomMusicShape(SynthNoteAllPortsInstrument ins) { MusicShape s = new MusicShape(ins.getDimensionNameSpace()); // add algorithmic data without knowing anything about the // DimensionNameSpace // if you *did* know the DimensionnameSpace of this instrument, you // could just do this: // s.add(dur, pitch, amp, hold, whatever1, whatever2, whatever3, etc); double basePitch = JMSLRandom.choose(60, 72); double duration = 0.5 * JMSLRandom.choose(1, 6); for (int i = 0; i < 17; i++) { // We know dimensions 0..3 are the standard ones double[] data = new double[s.dimension()]; data[0] = duration; // duration data[1] = basePitch + i; // pitch data[2] = 0.4; // amplitude data[3] = duration * 2; // hold // iterate through each dimension above 3; there are controls unique // for the SynthNote for (int d = 4; d < s.dimension(); d++) { double loLimit = s.getLowLimit(d); double hiLimit = s.getHighLimit(d); double value = JMSLRandom.choose(loLimit, hiLimit); data[d] = value; System.out.println("Added value " + value + " to dimension " + s.getDimensionName(d)); } s.add(data); } s.setRepeats(15); s.setInstrument(ins); return s; } public void actionPerformed(ActionEvent ev) { Object source = ev.getSource(); if (source == startButton) { col.launch(JMSL.now()); stopButton.setEnabled(true); startButton.setEnabled(false); } if (source == stopButton) { col.finishAll(); stopButton.setEnabled(false); startButton.setEnabled(true); } } public static void main(String[] args) { JMSLRandom.randomize(); JMSL.setViewFactory(new com.didkovsky.portview.swing.ViewFactorySwing()); FullFeaturedSynthNoteSupport f = new FullFeaturedSynthNoteSupport(); f.initMusicDevices(); f.buildInstruments(); f.buildMixer(); f.buildPerformance(); f.buildGUI(); f.pack(); f.setVisible(true); } }