package com.jsyn.examples; import java.awt.BorderLayout; import java.awt.GridLayout; import java.io.File; import java.io.IOException; import javax.sound.sampled.UnsupportedAudioFileException; import javax.swing.BorderFactory; import javax.swing.JApplet; import javax.swing.JLabel; import javax.swing.JPanel; import com.jsyn.JSyn; import com.jsyn.Synthesizer; import com.jsyn.data.FloatSample; import com.jsyn.ports.UnitInputPort; import com.jsyn.scope.AudioScope; import com.jsyn.swing.DoubleBoundedRangeModel; import com.jsyn.swing.JAppletFrame; import com.jsyn.swing.PortModelFactory; import com.jsyn.swing.RotaryTextController; import com.jsyn.unitgen.ContinuousRamp; import com.jsyn.unitgen.GrainFarm; import com.jsyn.unitgen.LineOut; import com.jsyn.unitgen.SampleGrainFarm; import com.jsyn.util.SampleLoader; import com.jsyn.util.WaveRecorder; /** * Play with Granular Synthesis tools. * * @author Phil Burk (C) 2011 Mobileer Inc * */ public class PlayGrains extends JApplet { private static final long serialVersionUID = -8315903842197137926L; private Synthesizer synth; private LineOut lineOut; private AudioScope scope; private GrainFarm grainFarm; private ContinuousRamp ramp; private static final int NUM_GRAINS = 32; private FloatSample sample; private WaveRecorder recorder; private static final boolean useSample = false; private final static boolean useRecorder = false; // File sampleFile = new File( "samples/instructions.wav" ); File sampleFile = new File( "/Users/phil/Work/jsyn/guitar100/Guitar100_Ocean_1#02.aif" ); /* Can be run as either an application or as an applet. */ public static void main( String args[] ) { PlayGrains applet = new PlayGrains(); JAppletFrame frame = new JAppletFrame( "PlayGrains", applet ); frame.setSize( 840, 500 ); frame.setVisible( true ); frame.test(); } private void setupGUI() { setLayout( new BorderLayout() ); add( BorderLayout.NORTH, new JLabel( "PlayGrains in an AudioScope - JSyn V" + synth.getVersion() ) ); scope = new AudioScope( synth ); // scope.addProbe( osc.output ); scope.addProbe( grainFarm.output ); scope.setTriggerMode( AudioScope.TriggerMode.NORMAL ); scope.getView().setControlsVisible( true ); add( BorderLayout.CENTER, scope.getView() ); scope.start(); // Arrange the knob in a row. JPanel knobPanel = new JPanel(); knobPanel.setLayout( new GridLayout( 1, 0 ) ); if( useSample ) { SampleGrainFarm sampleGrainFarm = (SampleGrainFarm) grainFarm; knobPanel.add( setupLinearPortKnob( ramp.time, 0.0, 10.0, "Time" ) ); knobPanel.add( setupLinearPortKnob( ramp.input, -1.0, 1.0, "Position" ) ); knobPanel.add( setupLinearPortKnob( sampleGrainFarm.positionRange, 0.0, 0.5, "PosRange" ) ); } knobPanel.add( setupPortKnob( grainFarm.density, 1.0, "Density" ) ); knobPanel.add( setupPortKnob( grainFarm.rate, 4.0, "Rate" ) ); knobPanel.add( setupPortKnob( grainFarm.rateRange, 3.0, "RateRange" ) ); knobPanel.add( setupPortKnob( grainFarm.duration, 0.1, "Duration" ) ); knobPanel .add( setupPortKnob( grainFarm.durationRange, 3.0, "DurRange" ) ); knobPanel.add( setupPortKnob( grainFarm.amplitude, 6.0, "Amplitude" ) ); knobPanel .add( setupPortKnob( grainFarm.amplitudeRange, 1.0, "AmpRange" ) ); add( knobPanel, BorderLayout.SOUTH ); validate(); } private RotaryTextController setupLinearPortKnob( UnitInputPort port, double min, double max, String label ) { port.setMinimum( min ); port.setMaximum( max ); DoubleBoundedRangeModel model = PortModelFactory .createLinearModel( port ); RotaryTextController knob = new RotaryTextController( model, 10 ); knob.setBorder( BorderFactory.createTitledBorder( label ) ); knob.setTitle( label ); return knob; } private RotaryTextController setupPortKnob( UnitInputPort port, double max, String label ) { port.setMinimum( 0.0 ); port.setMaximum( max ); DoubleBoundedRangeModel model = PortModelFactory .createExponentialModel( port ); RotaryTextController knob = new RotaryTextController( model, 10 ); knob.setBorder( BorderFactory.createTitledBorder( label ) ); knob.setTitle( label ); return knob; } public void start() { synth = JSyn.createSynthesizer(); try { if( useRecorder ) { File waveFile = new File( "temp_recording.wav" ); // Record mono 16 bits. recorder = new WaveRecorder( synth, waveFile, 1 ); System.out.println( "Writing to WAV file " + waveFile.getAbsolutePath() ); } if( useSample ) { sample = SampleLoader.loadFloatSample( sampleFile ); SampleGrainFarm sampleGrainFarm = new SampleGrainFarm(); synth.add( ramp = new ContinuousRamp() ); sampleGrainFarm.setSample( sample ); ramp.output.connect( sampleGrainFarm.position ); grainFarm = sampleGrainFarm; } else { GrainFarm sampleGrainFarm = new GrainFarm(); grainFarm = sampleGrainFarm; } synth.add( grainFarm ); grainFarm.allocate( NUM_GRAINS ); // Add an output so we can hear the grains. synth.add( lineOut = new LineOut() ); grainFarm.getOutput().connect( 0, lineOut.input, 0 ); grainFarm.getOutput().connect( 0, lineOut.input, 1 ); // Start synthesizer using default stereo output at 44100 Hz. synth.start(); // Start lineOut so it can pull data from other units. lineOut.start(); if( useRecorder ) { grainFarm.output.connect( 0, recorder.getInput(), 0 ); // When we start the recorder it will pull data from the // oscillator // and sweeper. recorder.start(); } setupGUI(); // We only need to start the LineOut. It will pull data from the // oscillator. lineOut.start(); } catch( IOException e ) { // TODO Auto-generated catch block e.printStackTrace(); } } public void stop() { try { if( recorder != null ) { recorder.stop(); recorder.close(); } } catch( IOException e ) { e.printStackTrace(); } scope.stop(); synth.stop(); } }