From jsyn at music.columbia.edu Sat Jan 10 23:41:17 2009 From: jsyn at music.columbia.edu (jsyn@music.columbia.edu) Date: Sat Jan 10 23:41:34 2009 Subject: [jsyn] Reverb tweaked for use in JSyn and JMSL Message-ID: <4969786D.5000104@mail.rockefeller.edu> Here's a revision of Reverb2 I posted earlier. This wraps Phil's Reverb1 wrapped up in a SynthNote, which addresses a few issues, so that now this works fine with JMSL. main() has two tests in it: one pure JSyn and another for JMSL Thanks Nick Didkovsky package com.punosmusic.circuitgrabbag; /** * SynthNote Reverb * * This is a SynthNote wrapper around Phil Burk's Reverb1 SynthCircuit * * This is suitable for use in JMSL's signal processing SynthNoteAllPortsInstrumentSP, which therefore also works in JMSL Score. * * See main() for testing as pure JSyn or JMSL test * * @author Nick Didkovsky 1/10/09 * */ import java.awt.Frame; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import com.softsynth.jmsl.*; import com.softsynth.jmsl.jsyn.*; import com.softsynth.jsyn.*; import com.softsynth.jsyn.circuits.FilteredSawtoothBL; import com.softsynth.jsyn.circuits.Reverb1; public class Reverb2 extends SynthNote { private Reverb1 reverb1; private BusWriter busWriter; public SynthInput input; public SynthInput dryGain; public SynthInput rate; SynthEnvelope env; EnvelopePlayer envPlayer; MultiplyUnit mult; public Reverb2() { add(reverb1 = new Reverb1()); add(envPlayer = new EnvelopePlayer()); add(busWriter = new BusWriter()); add(mult = new MultiplyUnit()); reverb1.busInput.connect(0, busWriter.busOutput, 0); envPlayer.output.connect(mult.inputA); reverb1.output.connect(mult.inputB); addPort(input = busWriter.input, "input"); addPort(dryGain = reverb1.dryGain); addPort(rate = envPlayer.rate, "envRate"); addPort(output = mult.output, "output"); addPort(amplitude = envPlayer.amplitude, "amplitude"); rate.setup(0.1, 1.0, 2.0); dryGain.setup(0, 0.15, 1.0); double[] envData = { 0.1, 1.0, 0.1, 0 }; env = new SynthEnvelope(envData); } public void setStage(int time, int stage) { switch (stage) { case 0: start(time); envPlayer.envelopePort.queue(time, env, 0, 1); break; case 1: envPlayer.envelopePort.queue(time, env, 1, 1, Synth.FLAG_AUTO_STOP); break; default: break; } } public static void main(String[] args) { boolean TEST_JSYN = true; if (TEST_JSYN) { System.out.println("Test Reverb2 with JSyn only"); Synth.startEngine(0); SynthObject.enableTracking(true); LineOut out = new LineOut(); out.start(); // sine for dry signal in left channel SineOscillator osc = new SineOscillator(); osc.amplitude.set(0.5); osc.start(); MultiplyUnit mult = new MultiplyUnit(); mult.start(); // toss a multiplier in to reduce dry signal level, cheap mixing... mult.inputA.set(0.5); osc.output.connect(mult.inputB); mult.output.connect(0, out.input, 0); // lag to sweep sine's frequency around so we can hear reverb ExponentialLag lag = new ExponentialLag(); lag.input.set(100); lag.halfLife.set(0.2); lag.output.connect(osc.frequency); lag.input.set(1000); lag.start(); // connect our reverb to right channel Reverb2 reverb2 = new Reverb2(); reverb2.output.connect(0, out.input, 1); reverb2.setStage(0); // connect dry signal to reverb osc.output.connect(reverb2.input); Frame f = new Frame(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { Synth.stopEngine(); System.exit(0); } }); f.setSize(320, 200); f.setVisible(true); // wake up every so often and sweep to a new frequency while (true) { try { Thread.sleep((long) (Math.random() * 3000 + 500)); } catch (InterruptedException e1) { } double freq = Math.random() * 2000; lag.input.set(freq); System.out.println("Sweeping to " + freq + " Hz"); } } else { System.out.println("Test Reverb2 with JMSL"); java.awt.Frame f = new java.awt.Frame("Test Reverb2 with JMSL"); f.setLayout(new java.awt.BorderLayout()); f.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent e) { JMSL.closeMusicDevices(); System.exit(0); } }); f.setSize(300, 200); f.setVisible(true); JSynMusicDevice.instance().edit(f); JSynMusicDevice.instance().open(); JMSL.clock.setAdvance(0.5); JMSLRandom.randomize(); // create two instruments, one to play dry melody and another to play reverb SynthNoteAllPortsInstrumentSP reverbIns = new SynthNoteAllPortsInstrumentSP(8, Reverb2.class.getName()); SynthNoteAllPortsInstrument melodicIns = new SynthNoteAllPortsInstrument(8, FilteredSawtoothBL.class.getName()); // patch output of melodic ins to input of reverb reverbIns.addSignalSource(melodicIns.getOutput()); // add instruments to mixer and pan them hard left/right JMSLMixerContainer mixer = new JMSLMixerContainer(); mixer.start(); mixer.addInstrument(melodicIns); mixer.addInstrument(reverbIns); mixer.panAmpChange(0, 0, 0.35); mixer.panAmpChange(1, 1, 0.75); f.add(java.awt.BorderLayout.NORTH, mixer.getPanAmpControlPanel()); // melody playing MusicShape MusicShape melodicShape = new MusicShape(melodicIns.getDimensionNameSpace()); melodicShape.setName("melody"); melodicShape.setInstrument(melodicIns); melodicShape.prefab(); melodicShape.setRepeats(1000); // reverb playing MusicShape MusicShape reverbMusicShape = new MusicShape(reverbIns.getDimensionNameSpace()); reverbMusicShape.setName("reverb"); reverbMusicShape.setInstrument(reverbIns); reverbMusicShape.setRepeats(1000); // stuff reverb shape with long durations double[] defaultData = MusicShape.getDefaultArray(reverbMusicShape); defaultData[0]=8; // long durations defaultData[2]=0.8; // amp defaultData[3]=7; // long hold time for reverb for (int i = 0; i < 5; i++) { reverbMusicShape.add(defaultData); } final com.softsynth.jmsl.view.MusicShapeEditor se = new com.softsynth.jmsl.view.MusicShapeEditor(); se.addMusicShape(reverbMusicShape); se.addMusicShape(melodicShape); f.add(java.awt.BorderLayout.SOUTH, se.getComponent()); f.pack(); melodicShape.addRepeatPlayable(new Playable() { public double play(double time, Composable parent) throws InterruptedException { MusicShape m = (MusicShape) parent; m.scramble(0, m.size() - 1, 0); m.scramble(0, m.size() - 1, 1); se.refresh(); return time; } }); ParallelCollection col = new ParallelCollection(melodicShape, reverbMusicShape); col.launch(JMSL.now() + 3); } } } From jsyn at music.columbia.edu Fri Jan 16 18:03:57 2009 From: jsyn at music.columbia.edu (jsyn@music.columbia.edu) Date: Fri Jan 16 18:04:14 2009 Subject: [jsyn] AlgoJazz Revisited Message-ID: <8CB4645D839CC65-7C4-AB2@MBLK-M14.sysops.aol.com> Hi all Jsyn people, I have finally re-focused my brain back into Jsyn. My latest work is called "Winter". It is near the top of the page on my website. http://www.algorithmicjazz.com/?? I compiled it with Java 1.4 so it should run on Java 1.5 and 1.6. I tested it on an XP machine and a MacBook. Phil Burk helped me get my timing correct. Thanks Phil. while ( Winter1.go ) { ? trackIndex = 0; ? while ( (trackA[trackIndex] != trackEnd) && Winter1.go ) ? { ??? if( trackA[trackIndex] != noteRest ) ??? { ???? ?freq = F.frequency[trackA[trackIndex]]; ????? sinOsc.frequency.set( time, freq );???????? // "time" was added here. ????? envPlay.envelopePort.clear( time ); ????? envPlay.envelopePort.queue( time, envelope ); ??? } ??? trackIndex++; ??? time = time + trackA[trackIndex]; ??? trackIndex++; ??? Synth.sleepUntilTick(time - 160);??????? // Minus time increased to 160 jsyn ticks. ? } } I think that the only interesting code is the rhythm pattern generator. int[] GenPattern4Beats() // 1 measure: pattern number - to ref chord notes, time - in jsyn ticks { int patternIndex = 0; int overLength = 0; int accumulateTime = 0; boolean endPatternFlag = false; int rhythmPattern[] = new int[36]; while ( endPatternFlag == false ) { ? rhythmPattern[patternIndex] = StaticRandom.nextIntNo2Rep(5); ? patternIndex++; ? if( 30 > StaticRandom.sNextInt(120)) ??? rhythmPattern[patternIndex] = n8;? 1/8th note ??else ??? rhythmPattern[patternIndex] = n16;? 1/16th note ??accumulateTime = accumulateTime + rhythmPattern[patternIndex]; ? if ( accumulateTime == measureLength ) ? { ??? endPatternFlag = true; ??? accumulateTime = 0; ? } ? else if ( accumulateTime > measureLength ) ? { ??? overLength = accumulateTime - measureLength; ??? rhythmPattern[patternIndex] = rhythmPattern[patternIndex] - overLength; ??? endPatternFlag = true; ??? accumulateTime = 0; ? } ? patternIndex++; } rhythmPattern[patternIndex] = patternEnd; endPatternFlag = false; return rhythmPattern; } John Clavin { int patternIndex = 0; int overLength = 0; int accumulateTime = 0; boolean endPatternFlag = false; int rhythmPattern[] = new int[36]; while ( endPatternFlag == false ) { ? rhythmPattern[patternIndex] = StaticRandom.nextIntNo2Rep(5); ? patternIndex++; ? if( 30 > StaticRandom.sNextInt(120)) ??? rhythmPattern[patternIndex] = n8;? 1/8th note ??else ??? rhythmPattern[patternIndex] = n16;? 1/16th note ??accumulateTime = accumulateTime + rhythmPattern[patternIndex]; ? if ( accumulateTime == measureLength ) ? { ??? endPatternFlag = true; ??? accumulateTime = 0; ? } ? else if ( accumulateTime > measureLength ) ? { ??? overLength = accumulateTime - measureLength; ??? rhythmPattern[patternIndex] = rhythmPattern[patternIndex] - overLength; ??? endPatternFlag = true; ??? accumulateTime = 0; ? } ? patternIndex++; } rhythmPattern[patternIndex] = patternEnd; endPatternFlag = false; return rhythmPattern; } John Clavin