/* * Created by Nick on Apr 11, 2005 * */ package jmslexamples.jsyn2; import java.awt.Frame; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import com.softsynth.jmsl.*; import com.softsynth.jmsl.jsyn2.JSynMusicDevice; import com.softsynth.jmsl.jsyn2.JSynUnitVoiceInstrument; import com.softsynth.jmsl.jsyn2.unitvoices.FMVoice; import com.softsynth.jmsl.util.Tunable; import com.softsynth.jmsl.util.TuningET; /** * * Use a DataTranslator to convert data from frequencies to pitches so pitch * based instruments can perform a MusicShape where frequencies are specified. * * This way you can think in terms of frequencies if that's what makes sense for * your composition * * @author Nick Didkovsky, (c) 2004 All rights reserved, Email: * nick@didkovsky.com * */ public class FrequencyDataTranslatorDemo { JMSLMixerContainer mixer; JSynUnitVoiceInstrument ins; MusicShape musicShape; public FrequencyDataTranslatorDemo() { initJMSLJSyn(); buildMixer(); buildInstrument(); buildMusicShape(); } public void initJMSLJSyn() { JMSL.clock.setAdvance(0.1); JSynMusicDevice.instance().open(); } void buildMixer() { mixer = new JMSLMixerContainer(); mixer.start(); } void buildInstrument() { ins = new JSynUnitVoiceInstrument(8, FMVoice.class.getName(), FMVoice.PRESET_BRASS); mixer.addInstrument(ins); } public void buildMusicShape() { musicShape = new MusicShape(4); musicShape.setDataTranslator(new FrequencyDataTranslator()); musicShape.useStandardDimensionNameSpace(); musicShape.setDimensionName(1, "frequency"); musicShape.setDefault(1, 440); musicShape.setLimits(1, 20, 3000); double baseFrequency = 110; double pythagoreanMajorThird = baseFrequency * 81 / 64; double justFifth = baseFrequency * 3 / 2; double pythagoreanMinor7th = baseFrequency * 16 / 9; System.out.println("baseFrequency=" + baseFrequency); System.out.println("pythagoreanMajorThird=" + pythagoreanMajorThird); System.out.println("justFifth=" + justFifth); System.out.println("pythagoreanMinor7th=" + pythagoreanMinor7th); musicShape.add(1.0, baseFrequency, 0.5, 10); musicShape.add(1.0, pythagoreanMajorThird, 0.5, 9); // Pythagorean major third musicShape.add(1.0, justFifth, 0.5, 8); musicShape.add(7.0, pythagoreanMinor7th, 0.5, 7); // Pythagorean minor 7th TuningET twelveTet = new TuningET(); twelveTet.setReferenceFrequency(baseFrequency); twelveTet.setReferencePitch(60); double freqOfBase = twelveTet.getFrequency(60); double etMajorThird = twelveTet.getFrequency(64); double etFifth = twelveTet.getFrequency(67); double etMinor7th = twelveTet.getFrequency(70); System.out.println("freqOfBase=" + freqOfBase); System.out.println("etMajorThird=" + etMajorThird); System.out.println("etFifth=" + etFifth); System.out.println("etMinor7th=" + etMinor7th); musicShape.add(1.0, baseFrequency, 0.5, 10); musicShape.add(1.0, etMajorThird, 0.5, 9); // 12tet major third musicShape.add(1.0, etFifth, 0.5, 8); musicShape.add(7.0, etMinor7th, 0.5, 7); // 12tet minor 7th musicShape.add(1.0, baseFrequency, 0.5, 15); musicShape.add(1.0, etMajorThird, 0.5, 3); // 12tet major third musicShape.add(4.0, pythagoreanMajorThird, 0.5, 3); // Pythagorean major third musicShape.add(1.0, justFifth, 0.5, 3); // 12tet major third musicShape.add(4.0, etFifth, 0.5, 3); // Pythagorean major third musicShape.add(1.0, pythagoreanMinor7th, 0.5, 3); // 12tet major third musicShape.add(4.0, etMinor7th, 0.5, 3); // Pythagorean major third musicShape.setInstrument(ins); musicShape.setRepeats(10); } public MusicShape getMusicShape() { return musicShape; } public static void main(String[] args) { Frame f = new Frame("Pythagorean major third and Pythagorean minor 7th using frequencies in a MusicShape"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { JMSL.closeMusicDevices(); System.exit(0); } }); f.setSize(320, 200); // Amiga res for max cross platform f.setVisible(true); FrequencyDataTranslatorDemo demo = new FrequencyDataTranslatorDemo(); demo.getMusicShape().launch(JMSL.now() + 3); } } class FrequencyDataTranslator implements DataTranslator { public FrequencyDataTranslator() { } /** * data[1] contains frequency. translate to pitch using the tuning from the * instrument. This way the instrument will simply convert back. */ public double[] translate(MusicJob job, double[] data) { // make a copy of the incoming double[] double[] dataCopy = new double[data.length]; System.arraycopy(data, 0, dataCopy, 0, data.length); // this will fail if instrument is not of type TunedSynthNoteInstrument // and tuning is not equal tempered // Note that the tuning "falls out" of this process and is completely arbitrary. // it just needs to be the same when used here to go from freq to pitch as it is // in the instrument // when it goes from pitch back to freq TuningET tuning = (TuningET) ((Tunable) job.getInstrument()).getTuning(); double pitch = tuning.getPitch(dataCopy[1]); dataCopy[1] = pitch; return dataCopy; } }