/* * Created by Nick on Jan 28, 2006 * */ package jmslexamples.simple; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JApplet; import javax.swing.JLabel; import com.jsyn.swing.JAppletFrame; import com.softsynth.jmsl.*; import com.softsynth.jmsl.jsyn2.JSynMusicDevice; import com.softsynth.jmsl.jsyn2.JSynUnitVoiceInstrument; import com.softsynth.jmsl.score.*; /** * One measure repeats 1000 times, changing its own tempo and the pitches of its * notes each repeat. * * Upgrade to JSyn2 API Dec 6, 2016 * * @author Nick Didkovsky, (c) 2009 All rights reserved, Email: * nick@didkovsky.com * */ public class SelfModifyingScore { Score score; ScoreFrame scoreFrame; Orchestra orchestra; public void start() { initJMSL(); initMusicDevices(); buildScore(); makeItSelfModifying(); buildOrchestra(); buildScoreFrame(); } private void initJMSL() { NoteFactory.useQuarterToneAccidentals(true); JMSL.scheduler = new EventScheduler(); JMSL.scheduler.start(); JMSL.clock.setAdvance(0.3); } private void initMusicDevices() { JMSL.clock = new DefaultMusicClock(); initJSynMusicDevice(); } private void initJSynMusicDevice() { MusicDevice dev = JSynMusicDevice.instance(); dev.edit(new java.awt.Frame()); dev.open(); } private void buildOrchestra() { orchestra = new Orchestra(); // use 8 voice polyphonic stereo JSyn instrument Instrument ins = new JSynUnitVoiceInstrument(8, com.softsynth.jmsl.jsyn2.unitvoices.AutoPanningSawtoothBL.class.getName()); orchestra.addInstrument(ins, "Stereo Autopanning JSyn Instrument"); score.setOrchestra(orchestra); if (ins.getNumOutputs() == 2) { // pan L/R score.getOrchestra().getJMSLMixerContainer().panAmpChange(0, 0, 0.5); score.getOrchestra().getJMSLMixerContainer().panAmpChange(1, 1, 0.5); } } /** build a measure with five notes. */ void buildPiece() { Measure m = score.addMeasure(5, 4); m.setRepeatStart(true); m.setRepeatEnd(true); m.setNumRepeats(999); m.setTempo(80); // duration (where 1.0 = qtr), pitch (where 60 = middle C), amp, sustain for (int i = 0; i < 5; i++) { double quarterTone = i * 0.5; // 0 first loop, 0.5 second loop, // etc double pitch = 60 + quarterTone; // duration 4 == whole note, pitch, amplitude, hold time Note n = score.addNote(1.0, pitch, 0.6, 3.9); } } /** Add a repeat playable to the measure */ void makeItSelfModifying() { Measure firstMeasure = score.getMeasure(0); firstMeasure.addRepeatPlayable(new Playable() { public double play(double time, Composable parent) throws InterruptedException { System.out.println("Repeating!"); Measure measure = (Measure) parent; Staff staff = measure.getStaff(0); Track track = staff.getTrack(0); for (int i = 0; i < track.size(); i++) { Note note = track.getNote(i); double newPitch = note.getPitchData() + JMSLRandom.choose(3); if (newPitch > 105) { newPitch -= 36; } note.setPitchData(newPitch); NoteFactory.update(note); } double bpm = measure.getTempo().getBPM(); bpm += 5; measure.setTempo(bpm); // need to render to force redisplay of notes with new pitches measure.getScore().render(); return time; } }); } void buildScore() { score = new Score(1, 800, 600, "Self Modifying Score"); buildPiece(); } void buildScoreFrame() { scoreFrame = new ScoreFrame(); scoreFrame.addScore(score); scoreFrame.pack(); scoreFrame.setVisible(true); } public static void main(String[] args) { SelfModifyingScore demo = new SelfModifyingScore(); demo.start(); } }