/* * Created on May 12, 2004 * */ package jmsltutorial; import java.awt.BorderLayout; import java.awt.Button; import java.awt.GridLayout; import java.awt.Label; import java.awt.Panel; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import com.softsynth.jmsl.JMSL; import com.softsynth.jmsl.JMSLMixerContainer; import com.softsynth.jmsl.MusicShape; import com.softsynth.jmsl.jsyn2.JSynMusicDevice; import com.softsynth.jmsl.jsyn2.JSynUnitVoiceInstrument; import com.softsynth.jmsl.util.TuningET; /** * @author Nick Didkovsky, email: nick@didkovsky.com, (c) 2004 Nick Didkovsky, * all rights reserved. * */ public class TuningETToot extends JFrame implements ActionListener { protected int octaveStretchInCents = 0; private double octaveRatio = 2.0; protected double referencePitch = TuningET.MIDDLE_C_PITCH; protected double referenceFrequency = TuningET.MIDDLE_C_FREQ; protected int stepsPerOctave = 12; protected double interval1 = -12; protected double interval2 = 12; TextField referencePitchTextField; TextField referenceFrequencyTextField; TextField stepsPerOctaveTextField; TextField octaveStretchInCentsTextField; TextField octaveRatioTextField; TextField interval1TextField; TextField interval2TextField; Button goButton; Button stopButton; Button changeTuningButton; MusicShape musicShape; JSynUnitVoiceInstrument instrument; JMSLMixerContainer mixer; String synthNoteClassName = com.softsynth.jmsl.jsyn2.unitvoices.FilteredSawtoothBL.class.getName(); public void start() { JMSL.clock.setAdvance(0.1); JSynMusicDevice dev = JSynMusicDevice.instance(); dev.open(); musicShape = new MusicShape(4); musicShape.setRepeats(Integer.MAX_VALUE); buildMusicShape(); instrument = new JSynUnitVoiceInstrument(8, synthNoteClassName); musicShape.setInstrument(instrument); mixer = new JMSLMixerContainer(); mixer.start(); mixer.addInstrument(instrument); buildGUI(); pack(); setVisible(true); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } void buildGUI() { setLayout(new BorderLayout(10, 10)); buildButtonPanel(); buildTextFields(); buildTextFieldPanel(); } protected void buildTextFieldPanel() { Panel p = new Panel(); p.setLayout(new GridLayout(0, 3, 5, 10)); p.add(gimmeLabelTextFieldPanel("reference pitch", referencePitchTextField)); p.add(gimmeLabelTextFieldPanel("reference frequency", referenceFrequencyTextField)); p.add(new Label()); p.add(gimmeLabelTextFieldPanel("steps per octave", stepsPerOctaveTextField)); p.add(gimmeLabelTextFieldPanel("octave ratio", octaveRatioTextField)); p.add(gimmeLabelTextFieldPanel("octave stretch in cents", octaveStretchInCentsTextField)); p.add(gimmeLabelTextFieldPanel("Interval 1", interval1TextField)); p.add(gimmeLabelTextFieldPanel("Interval 2", interval2TextField)); add(BorderLayout.SOUTH, p); } protected void buildTextFields() { referencePitchTextField = new TextField("" + referencePitch); referenceFrequencyTextField = new TextField("" + referenceFrequency); stepsPerOctaveTextField = new TextField("" + stepsPerOctave); octaveStretchInCentsTextField = new TextField("" + octaveStretchInCents); octaveRatioTextField = new TextField("" + octaveRatio); interval1TextField = new TextField("" + interval1); interval2TextField = new TextField("" + interval2); } protected void buildButtonPanel() { Panel p = new Panel(); p.setLayout(new GridLayout(0, 1)); p.add(goButton = new Button("GO")); p.add(stopButton = new Button("STOP")); stopButton.setEnabled(false); p.add(changeTuningButton = new Button("Use new values")); add(BorderLayout.NORTH, p); goButton.addActionListener(this); stopButton.addActionListener(this); changeTuningButton.addActionListener(this); } Panel gimmeLabelTextFieldPanel(String text, TextField tf) { Panel p = new Panel(); p.setLayout(new BorderLayout()); p.add(BorderLayout.NORTH, new Label(text)); p.add(BorderLayout.SOUTH, tf); return p; } void buildMusicShape() { musicShape.removeAll(); for (int i = 0; i <= stepsPerOctave; i++) { double duration = 0.75; double pitch = referencePitch + i; double amp = 0.4; double hold = duration * 0.9; musicShape.add(0, pitch + interval1, amp, hold); musicShape.add(0, pitch + interval2, amp, hold); musicShape.add(duration, pitch, amp, hold); } musicShape.set(2 * musicShape.get(musicShape.size() - 1, 0), musicShape.size() - 1, 0); musicShape.print(); } void changeTuning() { try { stepsPerOctave = new Integer(stepsPerOctaveTextField.getText()).intValue(); referenceFrequency = new Double(referenceFrequencyTextField.getText()).doubleValue(); referencePitch = new Double(referencePitchTextField.getText()).doubleValue(); octaveStretchInCents = new Integer(octaveStretchInCentsTextField.getText()).intValue(); octaveRatio = new Double(octaveRatioTextField.getText()).doubleValue(); interval1 = new Double(interval1TextField.getText()).doubleValue(); interval2 = new Double(interval2TextField.getText()).doubleValue(); TuningET tuning = new TuningET(stepsPerOctave, referenceFrequency, referencePitch, octaveStretchInCents); tuning.setOctaveRatio(octaveRatio); instrument.setTuning(tuning); buildMusicShape(); // FIX ME REMOVE ME System.out.println(tuning.getFrequency(60) + ", " + tuning.getFrequency(60 + stepsPerOctave) + ", a/b=" + (tuning.getFrequency(60 + stepsPerOctave) / tuning.getFrequency(60))); } catch (NumberFormatException e) { System.out.println("Bad Number"); } } public void stop() { removeAll(); mixer.stop(); musicShape.finishAll(); JMSL.closeMusicDevices(); } public void actionPerformed(ActionEvent ev) { Object source = ev.getSource(); if (source == goButton) { musicShape.launch(JMSL.now()); goButton.setEnabled(false); stopButton.setEnabled(true); } if (source == stopButton) { musicShape.finishAll(); goButton.setEnabled(true); stopButton.setEnabled(false); } if (source == changeTuningButton) { changeTuning(); } } public static void main(String[] args) { new TuningETToot().start(); } }