/// <summary> /// The rootPitch and all the pitches in the MidiChordDef must be contained in the gamut. /// The vertical velocity sequence remains unchanged except when notes are removed because they are duplicates. /// Calculates the number of steps to transpose, and then calls TransposeStepsInGamut. /// When this function returns, rootPitch is the lowest pitch in both BasicMidiChordDefs[0] and NotatedMidiPitches. /// </summary> public void TransposeToRootInGamut(Gamut gamut, int rootPitch) { #region conditions Debug.Assert(gamut != null); Debug.Assert(gamut.Contains(rootPitch)); Debug.Assert(gamut.Contains(BasicMidiChordDefs[0].Pitches[0])); #endregion conditions int stepsToTranspose = gamut.IndexOf(rootPitch) - gamut.IndexOf(BasicMidiChordDefs[0].Pitches[0]); // checks that all the pitches are in the gamut. TransposeStepsInGamut(gamut, stepsToTranspose); }
/// <summary> /// All the pitches in the MidiChordDef must be contained in the gamut. /// Transposes the pitches in NotatedMidiPitches, and all BasicMidiChordDef.Pitches by /// the number of steps in the gamut. Negative values transpose down. /// The vertical velocity sequence remains unchanged except when notes are removed. /// It is not an error if Midi values would exceed the range of the gamut. /// In this case, they are silently coerced to the bottom or top notes of the gamut respectively. /// Duplicate top and bottom gamut pitches are removed. /// </summary> public void TransposeStepsInGamut(Gamut gamut, int steps) { #region conditions Debug.Assert(gamut != null); foreach(BasicMidiChordDef bmcd in BasicMidiChordDefs) { foreach(int pitch in bmcd.Pitches) { Debug.Assert(gamut.Contains(pitch)); } } #endregion conditions int bottomMostPitch = gamut[0]; int topMostPitch = gamut[gamut.Count - 1]; foreach(BasicMidiChordDef bmcd in BasicMidiChordDefs) { List<byte> pitches = bmcd.Pitches; List<byte> velocities = bmcd.Velocities; for(int i = 0; i < pitches.Count; ++i) { pitches[i] = DoTranspose(pitches[i], gamut, steps); } RemoveDuplicateNotes(pitches, velocities); } SetNotatedValuesFromFirstBMCD(); }