/* * Created by Nick on May 16, 2005 * */ package jmsltestsuite; import java.util.Enumeration; import java.util.Hashtable; import com.softsynth.jmsl.*; import com.softsynth.jmsl.jsyn.SampleLoopRegioner; import com.softsynth.jmsl.jsyn.TransposingSampleSustainingInstrument; import com.softsynth.jsyn.SynthSample; /** * This subclass of TransposingSampleSustainingInstrument overrides * getAlternativeSampleIndex() to map note 60 to three different samples based * on amplitude. Notice that one sample is mapped to 60. Two additional samples * are mapped to pitches 200 and 201, which we never expect to play directly. * They serve as convenient places to stash alternative samples within the * existing API. * * The logic of mapping quiet, medium, loud versions of middle c is implemented * in getAlternativeSampleIndex() * * @author Nick Didkovsky, (c) 2004 All rights reserved, Email: * didkovn@mail.rockefeller.edu * */ public class TransposingSampleSustainingInstrumentWithAmplitudeMap extends TransposingSampleSustainingInstrument { public TransposingSampleSustainingInstrumentWithAmplitudeMap(String dir) { super(dir); } /** * Precondition: pitchIndex points to a valid sample, previously loaded with * addSamplePitch(). Override this method to point to a different valid * sample index. For example, you might store a loud sample at pitchIndex 60 * and quiet sample at index 200 (ie some pitch index you'd never bang * directly), and if the amplitude of data[] < 0.3 return 200 for this * pitchIndex, else return 60) * *
*
*
* public int getAlternativeSampleIndex(int pitchIndex, double timeStretch, double[] data) {
* double amp = data[2];
* if (pitchIndex == 60 && amp < 0.4) {
* return 201;
* }
* if (pitchIndex == 60 && amp > 0.7) {
* return 200;
* }
* return pitchIndex;
* }
*
*
*
*
* @return valid index to use instead of pitchIndex.
*/
public int getAlternativeSampleIndex(int pitchIndex, double timeStretch, double[] data) {
double amp = data[2];
if (pitchIndex == 60 && amp < 0.4) {
return 201;
}
if (pitchIndex == 60 && amp > 0.7) {
return 200;
}
return pitchIndex;
}
public static void main(String args[]) {
java.awt.Frame f = new java.awt.Frame(
"TransposingSampleSustainingInstrument with alternative samples mapped to amplitude");
f.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
JMSL.closeMusicDevices();
System.exit(0);
}
});
String mySampleDirectory = "E:/JMSLScoreWork/JMSLScoreSamples/";
TransposingSampleSustainingInstrumentWithAmplitudeMap ins = new TransposingSampleSustainingInstrumentWithAmplitudeMap(
mySampleDirectory);
ins.getMusicDevice().open();
ins.addSamplePitch("voice/c4_mf.wav", 60);
ins.addSamplePitch("voice/c4_ff.wav", 200);
ins.addSamplePitch("voice/c4_p.wav", 201);
ins.buildFromAttributes();
JMSLMixerContainer mixer = new JMSLMixerContainer();
mixer.addInstrument(ins);
mixer.start();
JMSL.clock.setAdvance(0.5);
MusicShape s = new MusicShape(4);
s.add(2.0, 60, 0.5, 1.85); // mf
s.add(2.0, 60, 0.75, 1.85); // ff
s.add(2.0, 60, 0.25, 1.85); // p
s.add(2.0, 61, 0.5, 1.85); // mf
s.add(2.0, 61, 0.75, 1.85); // ff
s.add(2.0, 61, 0.25, 1.85); // p
s.add(2.0, 59, 0.5, 1.85); // mf
s.add(2.0, 59, 0.75, 1.85); // ff
s.add(2.0, 59, 0.25, 1.85); // p
s.setInstrument(ins);
s.setRepeats(13);
s.launch(JMSL.now() + 0.5);
f.add(mixer.getPanAmpControlPanel());
f.pack();
f.setVisible(true);
Hashtable sampleHash = ins.getSynthSamples();
for (Enumeration e = sampleHash.keys(); e.hasMoreElements();) {
Integer key = (Integer) e.nextElement();
int pitchIndex = key.intValue();
SynthSample synthSample = (SynthSample) sampleHash.get(key);
System.out.println("Pitch index " + pitchIndex + " is mapped to " + synthSample);
}
System.out.println("---");
Hashtable sampleLoopRegionerHash = ins.getSampleLoopRegioners();
for (Enumeration e = sampleLoopRegionerHash.keys(); e.hasMoreElements();) {
Integer key = (Integer) e.nextElement();
int pitchIndex = key.intValue();
SampleLoopRegioner regioner = (SampleLoopRegioner)sampleLoopRegionerHash.get(key);
System.out.println("Pitch index " + pitchIndex + " is mapped to a sample with the following loop region info:\n " + regioner.getSampleRegion());
}
}
}