/* * Created on May 14, 2004 * */ package jmsltutorial; import java.awt.BorderLayout; import java.awt.Button; import java.awt.GridLayout; import java.awt.Panel; 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.JMSLRandom; import com.softsynth.jmsl.MusicJob; import com.softsynth.jmsl.jsyn2.JSynMusicDevice; import com.softsynth.jmsl.jsyn2.JSynUnitVoiceInstrument; import com.softsynth.jmsl.jsyn2.unitvoices.FilteredSawtoothBL; import com.softsynth.jmsl.util.WeightedIntegerSequence; /** * Plays a MusicJob which consults a WeightedIntegerSequence to play a random * walk melody. TextFields allow the user to set the relative weights of * choosing intervals -1, 0, 1
* * Thanks to Larry Polansky for suggesting WeightedIntegerSequence. * * @author Nick Didkovsky, email: nick@didkovsky.com, (c) 2004 Nick Didkovsky, * all rights reserved. * */ public class WeightedIntegerToot extends JFrame implements ActionListener { double[] weights = { 1, 1, 1 }; WeightedIntegerSequence weightedIntegerSequence; WeightedMelodyMusicJob job; Button startButton; Button stopButton; Button applyButton; ArrayEditorPanel arrayEditorPanel; JMSLMixerContainer mixer; public void start() { JMSLRandom.randomize(); JMSL.clock.setAdvance(0.1); weightedIntegerSequence = new WeightedIntegerSequence(weights); job = new WeightedMelodyMusicJob(); job.setWeightedIntegerSequence(weightedIntegerSequence); job.setRepeats(Integer.MAX_VALUE); JSynMusicDevice.instance().open(); JSynUnitVoiceInstrument ins = new JSynUnitVoiceInstrument(4, FilteredSawtoothBL.class.getName()); mixer = new JMSLMixerContainer(); mixer.start(); mixer.addInstrument(ins); job.setInstrument(ins); buildGUI(); pack(); setVisible(true); } void buildGUI() { setLayout(new BorderLayout()); Panel p = new Panel(); p.setLayout(new GridLayout(0, 1)); p.add(startButton = new Button("START")); p.add(stopButton = new Button("STOP")); p.add(applyButton = new Button("APPLY WEIGHTS")); add(BorderLayout.NORTH, p); arrayEditorPanel = new ArrayEditorPanel(); arrayEditorPanel.setArray(weightedIntegerSequence.getWeights()); add(BorderLayout.SOUTH, arrayEditorPanel); startButton.addActionListener(this); stopButton.addActionListener(this); applyButton.addActionListener(this); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } public void actionPerformed(ActionEvent ev) { Object source = ev.getSource(); if (source == startButton) { startButton.setEnabled(false); stopButton.setEnabled(true); job.launch(JMSL.now()); } if (source == stopButton) { stopButton.setEnabled(false); startButton.setEnabled(true); job.finish(); } if (source == applyButton) { arrayEditorPanel.setArrayFromTextFields(); } } public static void main(String[] args) { WeightedIntegerToot toot = new WeightedIntegerToot(); toot.start(); } } class WeightedMelodyMusicJob extends MusicJob { WeightedIntegerSequence weightedIntegerSequence; double pitch = 60; double duration = 0.25; public WeightedIntegerSequence getWeightedIntegerSequence() { return weightedIntegerSequence; } public void setWeightedIntegerSequence(WeightedIntegerSequence sequence) { weightedIntegerSequence = sequence; } public double repeat(double playTime) { int interval = weightedIntegerSequence.next(); // 0, 1, 2 int change = interval - 1; // -1, 0, 1 System.out.println("change=" + change); pitch += change; // System.out.println(pitch); double[] data = { duration, pitch, 0.6, duration * 0.8 }; return getInstrument().play(playTime, 1, data); } }