package com.jsyn.examples;
import java.awt.BorderLayout;
import java.awt.GridLayout;
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.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.LineOut;
import com.jsyn.unitgen.SineOscillator;
import com.jsyn.unitgen.SineOscillatorPhaseModulated;
/**
* Play a tone using a phase modulated sinewave oscillator.
* Phase modulation (PM) is very similar to frequency modulation (FM) but is easier to control.
*
* @author Phil Burk (C) 2010 Mobileer Inc
*
*/
public class HearSinePM extends JApplet
{
private static final long serialVersionUID = -2704222221111608377L;
private Synthesizer synth;
SineOscillatorPhaseModulated carrier;
SineOscillator modulator;
LineOut lineOut;
AudioScope scope;
public void init()
{
synth = JSyn.createSynthesizer();
// Add a tone generator.
synth.add( modulator = new SineOscillator() );
// Add a trigger.
synth.add( carrier = new SineOscillatorPhaseModulated() );
// Add an output mixer.
synth.add( lineOut = new LineOut() );
modulator.output.connect( carrier.modulation );
carrier.output.connect( 0, lineOut.input, 0 );
carrier.output.connect( 0, lineOut.input, 1 );
modulator.amplitude.setup( 0.0, 1.0, 10.0 );
carrier.amplitude.setup( 0.0, 1.0, 1.0 );
setupGUI();
}
private void setupGUI()
{
setLayout( new BorderLayout() );
add( new JLabel( "Show Phase Modulation in an AudioScope" ), BorderLayout.NORTH );
// Arrange the knob in a row.
JPanel knobPanel = new JPanel();
knobPanel.setLayout( new GridLayout( 1, 0 ) );
knobPanel.add( setupPortKnob( modulator.frequency, "MFreq" ) );
knobPanel.add( setupPortKnob( modulator.amplitude, "MAmp" ) );
knobPanel.add( setupPortKnob( carrier.frequency, "CFreq" ) );
knobPanel.add( setupPortKnob( carrier.amplitude, "CAmp" ) );
add( knobPanel, BorderLayout.SOUTH );
scope = new AudioScope( synth );
scope.addProbe( carrier.output );
scope.addProbe( modulator.output );
scope.setTriggerMode( AudioScope.TriggerMode.NORMAL );
scope.getView().setControlsVisible( true );
add( scope.getView(), BorderLayout.CENTER );
scope.start();
validate();
}
private RotaryTextController setupPortKnob( UnitInputPort port,
String label )
{
DoubleBoundedRangeModel model = PortModelFactory
.createExponentialModel( port );
RotaryTextController knob = new RotaryTextController( model, 10 );
knob.setBorder( BorderFactory.createTitledBorder( label ) );
knob.setTitle( label );
return knob;
}
public void start()
{
// Start synthesizer using default stereo output at 44100 Hz.
synth.start();
scope.start();
// We only need to start the LineOut. It will pull data from the
// oscillator.
lineOut.start();
}
public void stop()
{
scope.stop();
synth.stop();
}
/* Can be run as either an application or as an applet. */
public static void main( String args[] )
{
HearSinePM applet = new HearSinePM();
JAppletFrame frame = new JAppletFrame( "Hear Phase Modulation", applet );
frame.setSize( 640, 400 );
frame.setVisible( true );
frame.test();
}
}