/** * bentPitchFactory.java * * Generates a bentPitch object. * * The MIDI pitch bend event stores the bend amount as a 14 - bit * number, in two 7-bit status bytes, least significant first. * * Pitch bend has a range of 0x0000 - 0x3F01 hex, or 0 - 16129 decimal * The center value (no pitch bend) is 0x2000 or 8192 decimal: * this is expressed as status byte values 0x00 (lsb) and (0x40) msb * * The minimum value (0) normally corresponds to a pitch two semitomes * below the base pitch; the status byte vales are 0x00 (lsb) and (0x00) msb * * The maximimum value (0x3F01) normally corresponds to a pitch two semitomes * above the base pitch; the byte vales are 0x7F (lsb) and (0x7F) msb * * Given the bend amount relative to the centered value, * this class returns a bentPitch object with the two * status bytes set correctly* * * This module is part of Karl Brown's MIDI programming project. * */ package MidiApps; import java.io.*; import java.util.*; import javax.sound.midi.*; /** * * @author Karl Brown * @version 1.0 * last updated 2/16/2003 */ public class bentPitchFactory { protected tracer tr; private short PITCH_BEND_CENTER = ((0x40)*(0x80)); private short PITCH_BEND_MIN_VALUE= (0x00); private short PITCH_BEND_MAX_VALUE = ( ((0x80)*(0x80)) - (0x01) ) ; private bentPitch bentPitchOut; private byte midiPitchIn; private byte midiPitchOut; private byte statusMSB = 0x00; private byte statusLSB = 0x00; private int bendAmount; public void setTracer(tracer trc) { tr = trc; } public void setMidiPitchIn (byte pitch) { midiPitchIn = pitch; setMidiPitchOut(pitch); } protected void setMidiPitchOut (byte pitch) { midiPitchOut = pitch; } public void setMidiPitch (int pitch) throws Exception { if ( (pitch > 127) || (pitch < 0) ) { throw new Exception("Midi pitch out of range"); } setMidiPitchIn((byte)pitch); } public void setBendAmount (int amt) { bendAmount = amt; } private void setStatusMSB (byte b) { statusMSB = b; } private void setStatusLSB (byte b) { statusLSB = b; } public byte getMidiPitchIn() { return midiPitchIn; } public byte getMidiPitchOut() { return midiPitchOut; } public byte getStatusMSB() { return statusMSB; } public byte getStatusLSB() { return statusLSB; } public int getBendAmount() { return bendAmount; } /** * * returns the bentPitch object. * after the bend bytes have been set */ public bentPitch getBentPitch() { bentPitchOut = new bentPitch(); bentPitchOut.setMidiPitch(getMidiPitchOut()); bentPitchOut.setStatusLSB(getStatusLSB()); bentPitchOut.setStatusMSB(getStatusMSB()); return bentPitchOut; } /** * * calculate status bytes of pitch bend event * from bend amount relative to pitch bend center * */ protected void calculateBendBytes() throws Exception { // calculate offset from minimum pitch bend value (0) short adjustAmount = (short) ( getBendAmount() + PITCH_BEND_CENTER); int adjustInt = (int)adjustAmount; //value must fit within 14 bits (two 7-bit bytes) int testBend = adjustInt/128; // tr.trace("BendAmount: " + getBendAmount() // + " adjustAmount: " + adjustAmount // + " adjustInt: " +adjustInt // + " testBend: " + testBend); if ( (testBend > 127) || (testBend < 0) ) { throw new Exception("Bend amount out of range"); } //low order 7 bits go in least significant byte setStatusLSB((byte)(adjustInt % 128)); //high order 7 bits go in most significant byte setStatusMSB((byte)(adjustInt / 128)); // tr.trace("StatusMSB: " + getStatusMSB() // + " StatusLSB: " +getStatusLSB()); } }