package com.jsyn.examples; import com.jsyn.JSyn; import com.jsyn.Synthesizer; import com.jsyn.data.SegmentedEnvelope; import com.jsyn.ports.QueueDataCommand; import com.jsyn.ports.QueueDataEvent; import com.jsyn.ports.UnitDataQueueCallback; import com.jsyn.unitgen.LineOut; import com.jsyn.unitgen.SawtoothOscillatorBL; import com.jsyn.unitgen.UnitOscillator; import com.jsyn.unitgen.VariableRateDataReader; import com.jsyn.unitgen.VariableRateMonoReader; /** * Use a UnitDataQueueCallback to notify us of the envelope's progress. * Modulate the amplitude of an oscillator using a segmented envelope. * * @author Phil Burk (C) 2010 Mobileer Inc * */ public class PlaySegmentedEnvelopeCallback { private Synthesizer synth; private UnitOscillator osc; private LineOut lineOut; private SegmentedEnvelope envelope; private VariableRateDataReader envelopePlayer; private void test() { // Create a context for the synthesizer. synth = JSyn.createSynthesizer(); // Add a tone generator. synth.add( osc = new SawtoothOscillatorBL() ); // Add an envelope player. synth.add( envelopePlayer = new VariableRateMonoReader() ); // Create an envelope consisting of (duration,value) pairs. double[] pairs = { 0.1, 1.0, 0.2, 0.5, 0.6, 0.0 }; envelope = new SegmentedEnvelope( pairs ); // Add an output mixer. synth.add( lineOut = new LineOut() ); envelopePlayer.output.connect( osc.amplitude ); // Connect the oscillator to the output. osc.output.connect( 0, lineOut.input, 0 ); osc.output.connect( 0, lineOut.input, 1 ); // Start synthesizer using default stereo output at 44100 Hz. synth.start(); // We only need to start the LineOut. It will pull data from the other // units. lineOut.start(); try { // Queue an envelope with callbacks. QueueDataCommand command = envelopePlayer.dataQueue.createQueueDataCommand( envelope, 0, envelope.getNumFrames() ); // Create an object to be called when the queued data is done. TestQueueCallback callback = new TestQueueCallback(); command.setCallback( callback ); command.setNumLoops( 2 ); envelopePlayer.rate.set( 0.2 ); synth.queueCommand( command ); synth.sleepFor( 20.0 ); } catch( InterruptedException e ) { e.printStackTrace(); } // Stop everything. synth.stop(); } class TestQueueCallback implements UnitDataQueueCallback { public void started( QueueDataEvent event ) { System.out.println("CALLBACK: Envelope started."); } public void looped( QueueDataEvent event ) { System.out.println("CALLBACK: Envelope looped."); } public void finished( QueueDataEvent event ) { System.out.println("CALLBACK: Envelope finished."); // Queue the envelope again at a faster rate. // (If this hangs we may have hit a deadlock.) envelopePlayer.rate.set( 2.0 ); envelopePlayer.dataQueue.queue( envelope ); } } public static void main( String[] args ) { new PlaySegmentedEnvelopeCallback().test(); } }