use of com.xenoage.zong.io.midi.out.dynamics.DynamicsInterpretation in project Zong by Xenoage.
the class MidiConverter method convertToSequence.
private MidiSequence<T> convertToSequence() {
// compute mapping of staff indices to channel numbers
channelMap = createChannelMap(score);
// compute repetitions (repeat barlines, segnos, ...)
repetitions = RepetitionsFinder.findRepetitions(score);
// compute the mappings from application time to MIDI time
timeMap = new TimeMapper(score, repetitions, options.midiSettings.resolutionFactor).createTimeMap();
// find all dynamics
dynamics = DynamicsFinder.findDynamics(score, new DynamicsInterpretation(), repetitions);
// one track for each staff and one system track for program changes, tempos and so on,
// and another track for the metronome
int stavesCount = score.getStavesCount();
int tracksCount = stavesCount + 1;
Integer metronomeTrack = null;
if (options.metronome) {
metronomeTrack = tracksCount;
tracksCount++;
}
// resolution in ticks per quarter
resolution = score.getDivisions() * options.midiSettings.getResolutionFactor();
// init writer
writer.init(tracksCount, resolution);
// set MIDI programs and init volume and pan
for (val part : score.getStavesList().getParts()) {
val instrument = part.getFirstInstrument();
int partFirstStaff = score.getStavesList().getPartStaffIndices(part).getStart();
int channel = channelMap.getChannel(partFirstStaff);
if (channel != unused) {
if (instrument instanceof PitchedInstrument) {
val pitchedInstrument = (PitchedInstrument) instrument;
writer.writeProgramChange(systemTrackIndex, channel, 0, (pitchedInstrument).getMidiProgram());
}
writer.writeVolumeChange(systemTrackIndex, channel, 0, instrument.getVolume());
writer.writePanChange(systemTrackIndex, channel, 0, instrument.getPan());
}
}
// fill tracks
for (int iStaff : range(stavesCount)) {
int channel = channelMap.getChannel(iStaff);
if (channel == unused)
// no MIDI channel left for this staff
continue;
Staff staff = score.getStaff(iStaff);
int voicesCount = staff.getVoicesCount();
// first track is reserved; see declaration of tracksCount
int track = iStaff + 1;
for (int iRepetition : range(repetitions)) {
val rep = repetitions.get(iRepetition);
// TODO
int transpose = 0;
for (int iMeasure : range(rep.start.getMeasure(), rep.end.getMeasure())) {
if (iMeasure == score.getMeasuresCount())
continue;
Measure measure = staff.getMeasure(iMeasure);
for (int iVoice : range(measure.getVoices())) {
writeVoice(atVoice(iStaff, iMeasure, iVoice), iRepetition);
}
}
}
}
// write events for time mapping between the MIDI sequence and the score
if (options.addTimeEvents)
writePlaybackControlEvents();
// write metronome track
if (options.metronome)
writeMetronomeTrack(metronomeTrack);
return writer.finish(metronomeTrack, timeMap);
}
Aggregations