m_masterTempo = m_currentTempo =
new Float(score.getTempo()).floatValue();
//System.out.println("jMusic MidiSynth notification: Score TempoEvent (BPM) = " + score.getTempo());
Track longestTrack = null;
double longestTime = 0.0;
double longestRatio = 1.0;
Enumeration parts = score.getPartList().elements();
while (parts.hasMoreElements()) {
Part inst = (Part) parts.nextElement();
int currChannel = inst.getChannel();
if (currChannel > 16) {
throw new
InvalidMidiDataException(inst.getTitle() +
" - Invalid Channel Number: " +
currChannel);
}
m_tempoHistory.push(new Float(m_currentTempo));
float tempo = new Float(inst.getTempo()).floatValue();
//System.out.println("jMusic MidiSynth notification: Part TempoEvent (BPM) = " + tempo);
if (tempo != Part.DEFAULT_TEMPO) {
m_currentTempo = tempo;
} else if (tempo < Part.DEFAULT_TEMPO)
System.out.println("jMusic MidiSynth error: Part TempoEvent (BPM) too low = " + tempo);
trackTempoRatio = m_masterTempo / m_currentTempo;
int instrument = inst.getInstrument();
if (instrument == NO_INSTRUMENT) instrument = 0;
Enumeration phrases = inst.getPhraseList().elements();
double max = 0;
double currentTime = 0.0;
//
// One track per Part
/////////////
Track currTrack = sequence.createTrack();
while (phrases.hasMoreElements()) {
/////////////////////////////////////////////////
// Each phrase represents a new Track element
// Err no
// There is a 65? track limit
// ////////////////////////////
Phrase phrase = (Phrase) phrases.nextElement();
//Track currTrack = sequence.createTrack();
currentTime = phrase.getStartTime();
long phraseTick = (long) (currentTime * m_ppqn * trackTempoRatio);
MidiEvent evt;
if (phrase.getInstrument() != NO_INSTRUMENT) instrument = phrase.getInstrument();
evt = createProgramChangeEvent(currChannel, instrument, phraseTick);
currTrack.add(evt);
m_tempoHistory.push(new Float(m_currentTempo));
tempo = new Float(phrase.getTempo()).floatValue();
if (tempo != Phrase.DEFAULT_TEMPO) {
m_currentTempo = tempo;
//System.out.println("jMusic MidiSynth notification: Phrase TempoEvent (BPM) = " + tempo);
}
elementTempoRatio = m_masterTempo / m_currentTempo;
double lastPanPosition = -1.0;
int offSetTime = 0;
/// Each note
Enumeration notes = phrase.getNoteList().elements();
while (notes.hasMoreElements()) {
Note note = (Note) notes.nextElement();
// deal with offset
offSetTime = (int) (note.getOffset() * m_ppqn * elementTempoRatio);
//handle frequency pitch types
int pitch = -1;
if (note.getPitchType() == Note.MIDI_PITCH) {
pitch = note.getPitch();
} else {
pitch = Note.freqToMidiPitch(note.getFrequency());
}
int dynamic = note.getDynamic();
if (pitch == Note.REST) {
phraseTick += note.getRhythmValue() * m_ppqn * elementTempoRatio;
continue;
}
long onTick = (long) (phraseTick);
// pan
if (note.getPan() != lastPanPosition) {
evt = createCChangeEvent(currChannel, 10, (int) (note.getPan() * 127), onTick);
currTrack.add(evt);
lastPanPosition = note.getPan();
}
evt = createNoteOnEvent(currChannel, pitch, dynamic, onTick + offSetTime);
currTrack.add(evt);
long offTick = (long) (phraseTick + note.getDuration() * m_ppqn * elementTempoRatio);
evt = createNoteOffEvent(currChannel, pitch, dynamic, offTick + offSetTime);
currTrack.add(evt);
phraseTick += note.getRhythmValue() * m_ppqn * elementTempoRatio;
// TODO: Should this be ticks since we have tempo stuff
// to worry about