package com.xenoage.zong.io.midi.out;
import com.xenoage.zong.core.music.Pitch;
import static com.xenoage.utils.math.MathUtils.clamp;
import static com.xenoage.zong.core.music.Pitch.pi;
/**
* Some useful methods for working
* with MIDI data.
*
* @author Andreas Wenger
*/
public class MidiTools {
/**
* Converts the given MIDI note number (between 0 and 127)
* to a {@link Pitch} and returns it.
* Only positive values are used for alter.
*/
public static Pitch getPitchFromNoteNumber(int noteNumber) {
//12 = C0, 24 = C1, 36 = C2, ...
int octave = noteNumber / 12 - 1;
noteNumber -= (octave + 1) * 12;
int step = 0, alter = 0;
switch (noteNumber) {
case 0: step = 0; alter = 0; break;
case 1: step = 0; alter = 1; break;
case 2: step = 1; alter = 0; break;
case 3: step = 1; alter = 1; break;
case 4: step = 2; alter = 0; break;
case 5: step = 3; alter = 0; break;
case 6: step = 3; alter = 1; break;
case 7: step = 4; alter = 0; break;
case 8: step = 4; alter = 1; break;
case 9: step = 5; alter = 0; break;
case 10: step = 5; alter = 1; break;
case 11: step = 6; alter = 0; break;
}
return pi(step, alter, octave);
}
/**
* Converts the given {@link Pitch} to a MIDI note number
* (between 0 and 127) and returns it.
* If the note number would be outside the range of 0 to 127,
* 0 or 127 is returned.
*/
public static int getNoteNumber(Pitch pitch) {
return getNoteNumber(pitch, 0);
}
/**
* Converts the given {@link Pitch} with the given transposition in half steps
* to a MIDI note number (between 0 and 127) and returns it.
* If the note number would be outside the range of 0 to 127,
* 0 or 127 is returned.
*/
public static int getNoteNumber(Pitch pitch, int transpose) {
int ret = (pitch.getOctave() + 1) * 12 + transpose;
switch (pitch.getStep()) {
case 0: break;
case 1: ret += 2; break;
case 2: ret += 4; break;
case 3: ret += 5; break;
case 4: ret += 7; break;
case 5: ret += 9; break;
case 6: ret += 11; break;
}
ret += pitch.getAlter();
ret = clamp(ret, 0, 127);
return ret;
}
}