package SynthLang.sandbox;

/*Generated by MPS */

import com.jsyn.Synthesizer;
import com.jsyn.JSyn;
import com.jsyn.unitgen.SineOscillator;
import com.jsyn.unitgen.ImpulseOscillator;
import com.jsyn.unitgen.SawtoothOscillator;
import com.jsyn.unitgen.LineOut;
import com.jsyn.unitgen.Add;
import com.jsyn.ports.UnitInputPort;
import com.jsyn.ports.UnitPort;
import com.jsyn.unitgen.UnitGenerator;

public class SimpleSynthModel implements ISimpleSynth {

  private Synthesizer synth = JSyn.createSynthesizer();
  private SineOscillator sound_sine1 = new SineOscillator();
  private ImpulseOscillator sound_impulse = new ImpulseOscillator();
  private SawtoothOscillator sound_sound1 = new SawtoothOscillator();
  private LineOut sound_lineout = new LineOut();
  private SineOscillator sound_sound2 = new SineOscillator();
  private Add sound_add = new Add();
  private SineOscillator sound_sine2 = new SineOscillator();
  private SawtoothOscillator sound_saw = new SawtoothOscillator();
  private SineOscillator sound_sine3 = new SineOscillator();

  /**
   * The Synthesizer
   */
  public SimpleSynthModel() {
    init();
  }

  /**
   * Set up the synthesizer components
   */
  private void init() {

    synth.add(sound_sine1);
    synth.add(sound_impulse);
    synth.add(sound_sound1);
    synth.add(sound_lineout);
    synth.add(sound_sound2);
    synth.add(sound_add);
    synth.add(sound_sine2);
    synth.add(sound_saw);
    synth.add(sound_sine3);

    sound_sine1.frequency.setup(0.5f, 7.5f, 50.f);
    sound_sine1.amplitude.setup(0.f, 0.2f, 1.f);
    sound_impulse.frequency.setup(0.5f, 490.f, 5000.f);
    sound_sound1.frequency.setup(0.5f, 510.f, 5000.f);
    sound_sound1.amplitude.setup(0.f, 0.2f, 1.0f);
    sound_sound2.frequency.setup(0.5f, 500.f, 5000.f);
    sound_sound2.amplitude.setup(0.f, 0.2f, 1.f);
    sound_sine2.frequency.setup(0.5f, 1.7f, 20.f);
    sound_sine2.amplitude.setup(0.f, 500.f, 5000.f);
    sound_saw.frequency.setup(0.5f, 5.f, 50.f);
    sound_saw.amplitude.setup(0.f, 0.2f, 1.f);
    sound_sine3.frequency.setup(0.5f, 10.f, 500.f);
    sound_sine3.amplitude.setup(0.f, 600.f, 5000.f);

    sound_sine1.output.connect(sound_sound1.amplitude);
    sound_sine2.output.connect(sound_sound1.frequency);
    sound_sine3.output.connect(sound_sound2.frequency);
    sound_saw.output.connect(sound_sound2.amplitude);
    sound_sound1.output.connect(sound_add.inputA);
    sound_sound2.output.connect(sound_add.inputB);
    sound_add.output.connect(sound_lineout.input);
  }

  public void start() {
    synth.start();
    sound_lineout.start();
  }

  public void stop() {
    if (synth != null) {
      synth.stop();
    }
    if (sound_lineout != null) {
      sound_lineout.stop();
    }
  }

  /*package*/ UnitInputPort getInputPortByName(String generator, String portName) {
    try {
      Object o = this.getClass().getDeclaredField(generator).get(this);
      UnitPort port = ((UnitGenerator) o).getPortByName(portName);
      return (UnitInputPort) port;
    } catch (Exception e) {
      e.printStackTrace();
      // no such field --> null 
    }
    return null;
  }
}
