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();
}
}