/// <summary> /// Sets Clytamnestra's _uniqueMidiDurationDefs for the whole piece including rests. /// Barline positions are set later. /// </summary> private void SetUniqueMidiDurationDefs(TrkDef wind3) { Debug.Assert(_momentDefsListPerVerse.Count == 5); List <int> verseMsPositions = new List <int>(); verseMsPositions.Add(wind3[8].MsPosition); verseMsPositions.Add(wind3[20].MsPosition); verseMsPositions.Add(wind3[33].MsPosition); verseMsPositions.Add(wind3[49].MsPosition); verseMsPositions.Add(wind3[70].MsPosition); int currentVerseMsPosition = 0; int currentEndMsPosition = 0; IUniqueDef interludeRestDef = null; for (int verseIndex = 0; verseIndex < 5; ++verseIndex) { currentVerseMsPosition = verseMsPositions[verseIndex]; interludeRestDef = new RestDef(currentEndMsPosition, currentVerseMsPosition - currentEndMsPosition); _uniqueDefs.Add(interludeRestDef); List <MomentDef> momentDefs = _momentDefsListPerVerse[verseIndex]; for (int momentDefIndex = 0; momentDefIndex < momentDefs.Count; ++momentDefIndex) { MomentDef momentDef = momentDefs[momentDefIndex]; momentDef.MsPosition += currentVerseMsPosition; int restWidth = momentDef.MsWidth - momentDef.MaximumMsDuration; IUniqueDef lmrd = null; if (restWidth > 0) { momentDef.MsWidth -= restWidth; lmrd = new RestDef(momentDef.MsPosition + momentDef.MsWidth, restWidth); Debug.Assert(lmrd.MsDuration > 0); } MidiChordDef mcd = momentDef.MidiChordDefs[0]; IUniqueDef lmcd = mcd.DeepClone(); lmcd.MsPosition = momentDef.MsPosition; lmcd.MsDuration = momentDef.MsWidth; Debug.Assert(lmcd.MsDuration > 0); _uniqueDefs.Add(lmcd); if (lmrd != null) { _uniqueDefs.Add(lmrd); } currentEndMsPosition = _uniqueDefs[_uniqueDefs.Count - 1].MsPosition + _uniqueDefs[_uniqueDefs.Count - 1].MsDuration; } } interludeRestDef = new RestDef(currentEndMsPosition, wind3.EndMsPosition - currentEndMsPosition); _uniqueDefs.Add(interludeRestDef); }
/// <summary> /// Sets _momentDefsListPerVerse to contain a list of MomentDefs for each verse. /// Each MomentDef is positioned with respect to the beginning of its verse, and contains /// a single MidiChordDef in its MidiChordDefs list. /// </summary> private void SetMomentDefsListPerVerse() { _momentDefsListPerVerse = new List <List <MomentDef> >(); List <List <int> > momentDefMsWidthPerVerse = MomentDefMsWidthPerVerse; List <List <int> > midiChordDefMsDurPerVerse = MidiChordDefMsDurationsPerVerse; CheckWidths(momentDefMsWidthPerVerse, midiChordDefMsDurPerVerse); List <List <string> > lyricsPerVerse = LyricsPerVerse; List <byte> verseVelocities = new List <byte>() { (byte)64, (byte)75, (byte)90, (byte)105, (byte)120 }; for (int verseIndex = 0; verseIndex < 5; ++verseIndex) { int momentMsPos = 0; List <int> momentMsWidth = momentDefMsWidthPerVerse[verseIndex]; List <int> midiChordMsDur = midiChordDefMsDurPerVerse[verseIndex]; List <string> lyrics = lyricsPerVerse[verseIndex]; List <MomentDef> momentDefs = new List <MomentDef>(); _momentDefsListPerVerse.Add(momentDefs); byte patch = (byte)(123 + verseIndex); // top 5 patches in bank 0 List <byte> velocity = new List <byte>() { verseVelocities[verseIndex] }; for (int syllableIndex = 0; syllableIndex < momentMsWidth.Count; ++syllableIndex) { Debug.Assert(midiChordMsDur[syllableIndex] <= momentMsWidth[syllableIndex]); MomentDef momentDef = new MomentDef(momentMsPos); momentDef.MsWidth = momentMsWidth[syllableIndex]; momentDefs.Add(momentDef); List <byte> pitch = new List <byte>() { (byte)syllableIndex }; // the syllables are organised like this in the soundfont. int msDuration = midiChordMsDur[syllableIndex]; #region MidiChordDef lmcd = new MidiChordDef(); lmcd.HasChordOff = true; // Bank, and Patch are added to *every* chord so that performances can start anywhere. // If the Assistant Performer is clever enough, repeated controls are not actually sent. lmcd.Bank = (byte)(0); lmcd.Patch = patch; lmcd.Lyric = lyrics[syllableIndex]; // the following determine what is actually heard List <byte> expressionMsbs = new List <byte>() { (byte)65 }; lmcd.MidiChordSliderDefs = new MidiChordSliderDefs(null, null, null, expressionMsbs); lmcd.BasicMidiChordDefs.Add(new BasicMidiChordDef(msDuration, 0, patch, true, pitch, velocity)); lmcd.MsDuration = msDuration; // these two attributes determine the symbols in the score. lmcd.NotatedMidiPitches = new List <byte>() { 67 }; // display middle G, even though "pitch" is different. lmcd.MidiVelocity = velocity[0]; // determines the visible dynamic symbol #endregion momentDef.MidiChordDefs.Add(lmcd); momentMsPos += momentDef.MsWidth; } } }