/* * Created by Nick on Dec 5, 2004 * */ package jmslexamples.jsyn2; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Hashtable; import java.util.Vector; import javax.swing.JFrame; import com.didkovsky.portview.PVCheckbox; import com.didkovsky.portview.PVPanel; import com.didkovsky.portview.swing.ViewFactorySwing; import com.softsynth.jmsl.JMSL; import com.softsynth.jmsl.JMSLMixerContainer; import com.softsynth.jmsl.jsyn2.JSynMusicDevice; import com.softsynth.jmsl.jsyn2.JSynUnitVoiceInstrument; import com.softsynth.jmsl.jsyn2.unitvoices.FilteredSawtoothBL; import com.softsynth.jmsl.util.TuningTable; import com.softsynth.jmsl.view.PVPanelAdapter; /** * A TuningTable is a Tuning which has frequencies specified. This demo uses * checkboxes as virtual keys for any TuningTable. Checkboxes show frequency. * Checking and unchecking a box turns that pitch on or off. From an idea by * Paul Reiners * * Upgraded to JSyn2 API Dec 2016 * * @author Nick Didkovsky, (c) 2004 All rights reserved, Email: * nick@didkovsky.com * */ public class CustomTuningVirtualKeyboard extends JFrame implements ItemListener { Vector virtualKeys; TuningTable tuning; JSynUnitVoiceInstrument instrument; JMSLMixerContainer mixer; private void buildTuning() { double[] frequencies = { 274.8, 298.8, 316.6, 330.0, 358.4, 368.2, 421.1, 452.4, 482.6, 533.9 }; tuning = new TuningTable(frequencies); } public void start() { JMSL.setViewFactory(new ViewFactorySwing()); JSynMusicDevice.instance().open(); setLayout(new BorderLayout()); buildTuning(); buildVirtualKeys(); buildInstrument(); buildMixer(); } private void buildMixer() { mixer = new JMSLMixerContainer(); mixer.start(); mixer.addInstrument(instrument); getContentPane().add(BorderLayout.SOUTH, mixer.getPanAmpControlPanel()); } public void stop() { removeAll(); JMSL.closeMusicDevices(); } private void buildInstrument() { instrument = new JSynUnitVoiceInstrument(16, FilteredSawtoothBL.class.getName()); instrument.setTuning(tuning); // !!!! instrument.setName("Band Limitted Sawtooth"); } private void buildVirtualKeys() { virtualKeys = new Vector(); PVPanel panel = new PVPanelAdapter(); panel.setLayout(new GridLayout(1, 0)); for (int i = 0; i < tuning.getStepsPerOctave(); i++) { double pitch = indexToPitch(i); double frequency = tuning.getFrequency(pitch); PVCheckbox cb = JMSL.getViewFactory().createCheckbox(frequency + ""); virtualKeys.add(cb); panel.add(cb.getComponent()); cb.addItemListener(this); } getContentPane().add(BorderLayout.NORTH, panel.getComponent()); } private double indexToPitch(int i) { return tuning.getReferencePitch() + i; } /** * JSyn2 API returns a voicetoken for each allocated voice. Easy to store and * look up for update() and off() * */ Hashtable pitchToVoiceTokenHash = new Hashtable(); public void itemStateChanged(ItemEvent ev) { Object source = ev.getSource(); boolean state = ((PVCheckbox) source).getState(); int index = virtualKeys.indexOf(source); double pitch = indexToPitch(index); double dur = 1.0; // not important since virtual key controls sustain double amplitude = 0.4; double hold = 1.0; // not important since virtual key controls sustain double[] data = { dur, pitch, amplitude, hold }; if (state) { Integer voiceToken = (Integer) instrument.on(JMSL.now(), 1.0, data); pitchToVoiceTokenHash.put(new Double(pitch), voiceToken); } else { if (pitchToVoiceTokenHash.containsKey(new Double(pitch))) { int voiceToken = pitchToVoiceTokenHash.get(new Double(pitch)).intValue(); ((JSynUnitVoiceInstrument) instrument).off(JMSL.realTime(), voiceToken); } } System.out.println("pitch = " + pitch + ", selected? " + state); } public static void main(String[] args) { CustomTuningVirtualKeyboard demo = new CustomTuningVirtualKeyboard(); demo.setSize(800, 250); demo.setVisible(true); demo.setLayout(new FlowLayout()); demo.start(); demo.pack(); demo.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { demo.stop(); System.exit(0); } }); } }