package jmslexamples.jsyn; //SignalProcessingScore import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import com.softsynth.jmsl.*; import com.softsynth.jmsl.jsyn.*; import com.softsynth.jmsl.score.*; import com.softsynth.jmsl.util.Patch; import com.softsynth.jsyn.SynthOutput; /** * Demonstrates how a JMSL Score can have one instrument in one staff apply * signal processing to the output of other instrument(s) on other staff/ves * Here two instruments (FilteredSawtoothBL and RingModBell) are bussed to an * instrument with an interpolating delay line. Different notes in the delay * instrument have different values for feedback and delay time, so you will * hear delay values change. Note that a JSynSignalProcessingInstrument is a * "polyphonic" signal processor, so you can create a chord where each note has * different delay/feedback values (as is the case in this demo). * * @author Nick Didkovsky, July 9, 2002, (c) copyright 2002 Nick Didkovsky, all * rights reserved */ public class SignalProcessingScore { SynthNoteAllPortsInstrument ins1; SynthNoteAllPortsInstrument ins2; SynthNoteAllPortsInstrumentSP insSP; Score score; ScoreFrame scoreFrame; Orchestra orch; int[] prettyIntervals = { 0, 4, 7, 9 }; void build() { initMusicDevice(); initScore(); buildInstruments(); buildOrchestra(); buildComposition(); } void initMusicDevice() { JSynMusicDevice.instance().open(); JMSL.clock.setAdvance(0.1); } void initScore() { score = new Score(3, 800, 400); score.setName("Signal Processing Score"); } void buildInstruments() { // A signal source ins1 = new SynthNoteAllPortsInstrument(); ins1.setMaxVoices(4); ins1.setSynthNoteClassName(com.softsynth.jsyn.circuits.FilteredSawtoothBL.class.getName()); ins1.buildFromAttributes(); // A signal source ins2 = new SynthNoteAllPortsInstrument(); ins2.setMaxVoices(4); ins2.setSynthNoteClassName(com.softsynth.jsyn.circuits.RingModBell.class.getName()); ins2.buildFromAttributes(); // a signal processor insSP = new SynthNoteAllPortsInstrumentSP(); insSP.setMaxVoices(3); insSP.setSynthNoteClassName(com.softsynth.jmsl.jsyn.circuits.SimpleDelay.class.getName()); insSP.buildFromAttributes(); } void buildOrchestra() { orch = new Orchestra(); score.setOrchestra(orch); addInstrumentsToOrchestra(); patchSignals(); setupMix(); } private void setupMix() { // set up a custom mix JMSLMixerContainer mixer = orch.getJMSLMixerContainer(); mixer.panAmpChange(0, 0.0, 0.4); mixer.panAmpChange(1, 1.0, 0.4); mixer.panAmpChange(2, 0.5, 0.7); } private void patchSignals() { // bus signal sources to signal processor insSP.addSignalSource((SynthOutput) ins1.getOutput()); insSP.addSignalSource((SynthOutput) ins2.getOutput()); // Add to orchestra patch list. This way it will save/load to a score // xml file orch.addOrchPatch(new Patch(0, 2)); orch.addOrchPatch(new Patch(1, 2)); orch.patchInstruments(); } private void addInstrumentsToOrchestra() { orch.addInstrument(ins1, "Filtered Sawtooth BL"); orch.addInstrument(ins2, "Ring Mod Bell"); orch.addInstrument(insSP, "Variable Delay with Feedback"); } void buildComposition() { score.addMeasure(); buildFirstStaff(); buildSecondStaff(); buildThirdStaff(); } private void buildFirstStaff() { // insert some notes in first staff score.rewind(); score.setCurrentStaffNumber(0); for (int i = 0; i < 8; i++) { score.addNote(1.0, 60 + JMSLRandom.choose(prettyIntervals.length), 0.5, 0.2); } } private void buildSecondStaff() { // insert some notes in second staff score.rewind(); score.setCurrentStaffNumber(1); for (int i = 0; i < 16; i++) { score.addNote(0.5, 84 + JMSLRandom.choose(prettyIntervals.length), 0.5, 0.9); } } private void buildThirdStaff() { // insert signal processing notes in third staff score.rewind(); score.setCurrentStaffNumber(2); // third staff DimensionNameSpace spNameSpace = insSP.getDimensionNameSpace(); double[] spDouble = { 4.0, 60, 0.5, 3.9, 0.8, 0.1 }; score.addNote(spNameSpace, spDouble); spDouble[spNameSpace.getDimension("pitch")] = 72; spDouble[spNameSpace.getDimension("feedback")] = 0.2; spDouble[spNameSpace.getDimension("delay")] = 4.0 / 3.0; score.addInterval(spNameSpace, spDouble); spDouble[spNameSpace.getDimension("duration")] = 1.0; spDouble[spNameSpace.getDimension("pitch")] = 60; spDouble[spNameSpace.getDimension("hold")] = 1.0; spDouble[spNameSpace.getDimension("feedback")] = 0.5; spDouble[spNameSpace.getDimension("delay")] = 0.25; score.addNote(spNameSpace, spDouble); score.addNote(1.0, 0, 0, 0); spDouble[spNameSpace.getDimension("delay")] = 0.333 / 2; spDouble[spNameSpace.getDimension("feedback")] = 0.95; spDouble[spNameSpace.getDimension("amplitude")] = 0.4; score.addNote(spNameSpace, spDouble); score.addNote(1.0, 0, 0, 0); } void buildShowScoreFrame() { scoreFrame = new ScoreFrame(); scoreFrame.addScore(score); scoreFrame.setVisible(true); scoreFrame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { JMSL.closeMusicDevices(); scoreFrame.quit(); } }); } public static void main(String args[]) { JMSLRandom.randomize(); SignalProcessingScore signalProcessingScore = new SignalProcessingScore(); signalProcessingScore.build(); signalProcessingScore.buildShowScoreFrame(); } }