FindConsecutiveChords(List <MusicSymbol> symbols, TimeSignature time, int startIndex, int[] chordIndexes, ref int horizDistance) { int i = startIndex; int numChords = chordIndexes.Length; while (true) { horizDistance = 0; /* Find the starting chord */ while (i < symbols.Count - numChords) { if (symbols[i] is ChordSymbol) { ChordSymbol c = (ChordSymbol)symbols[i]; if (c.Stem != null) { break; } } i++; } if (i >= symbols.Count - numChords) { chordIndexes[0] = -1; return(false); } chordIndexes[0] = i; bool foundChords = true; for (int chordIndex = 1; chordIndex < numChords; chordIndex++) { i++; int remaining = numChords - 1 - chordIndex; while ((i < symbols.Count - remaining) && (symbols[i] is BlankSymbol)) { horizDistance += symbols[i].Width; i++; } if (i >= symbols.Count - remaining) { return(false); } if (!(symbols[i] is ChordSymbol)) { foundChords = false; break; } chordIndexes[chordIndex] = i; horizDistance += symbols[i].Width; } if (foundChords) { return(true); } /* Else, start searching again from index i */ } }
List <MusicSymbol> AddRests(List <MusicSymbol> symbols, TimeSignature time) { int prevtime = 0; List <MusicSymbol> result = new List <MusicSymbol>(symbols.Count); foreach (MusicSymbol symbol in symbols) { int starttime = symbol.StartTime; RestSymbol[] rests = GetRests(time, prevtime, starttime); if (rests != null) { foreach (RestSymbol r in rests) { result.Add(r); } } result.Add(symbol); /* Set prevtime to the end time of the last note/symbol. */ if (symbol is ChordSymbol) { ChordSymbol chord = (ChordSymbol)symbol; prevtime = Math.Max(chord.EndTime, prevtime); } else { prevtime = Math.Max(starttime, prevtime); } } return(result); }
/** Find the initial clef to use for this staff. Use the clef of * the first ChordSymbol. */ private Clef FindClef(List <MusicSymbol> list) { foreach (MusicSymbol m in list) { if (m is ChordSymbol) { ChordSymbol c = (ChordSymbol)m; return(c.Clef); } } return(Clef.Treble); }
CreateBeamedChords(List <MusicSymbol>[] allsymbols, TimeSignature time, int numChords, bool startBeat) { int[] chordIndexes = new int[numChords]; ChordSymbol[] chords = new ChordSymbol[numChords]; foreach (List <MusicSymbol> symbols in allsymbols) { int startIndex = 0; while (true) { int horizDistance = 0; bool found = FindConsecutiveChords(symbols, time, startIndex, chordIndexes, ref horizDistance); if (!found) { break; } for (int i = 0; i < numChords; i++) { chords[i] = (ChordSymbol)symbols[chordIndexes[i]]; } if (ChordSymbol.CanCreateBeam(chords, time, startBeat)) { ChordSymbol.CreateBeam(chords, horizDistance); startIndex = chordIndexes[numChords - 1] + 1; } else { startIndex = chordIndexes[0] + 1; } /* What is the value of startIndex here? * If we created a beam, we start after the last chord. * If we failed to create a beam, we start after the first chord. */ } } }
List <ChordSymbol> CreateChords(List <MidiNote> midinotes, KeySignature key, TimeSignature time, ClefMeasures clefs) { int i = 0; List <ChordSymbol> chords = new List <ChordSymbol>(); List <MidiNote> notegroup = new List <MidiNote>(12); int len = midinotes.Count; while (i < len) { int starttime = midinotes[i].StartTime; Clef clef = clefs.GetClef(starttime); /* Group all the midi notes with the same start time * into the notes list. */ notegroup.Clear(); notegroup.Add(midinotes[i]); i++; while (i < len && midinotes[i].StartTime == starttime) { notegroup.Add(midinotes[i]); i++; } /* Create a single chord from the group of midi notes with * the same start time. */ ChordSymbol chord = new ChordSymbol(notegroup, key, time, clef, this); chords.Add(chord); } return(chords); }
/** Calculate the start and end time of this staff. */ private void CalculateStartEndTime() { starttime = endtime = 0; if (symbols.Count == 0) { return; } starttime = symbols[0].StartTime; foreach (MusicSymbol m in symbols) { if (endtime < m.StartTime) { endtime = m.StartTime; } if (m is ChordSymbol) { ChordSymbol c = (ChordSymbol)m; if (endtime < c.EndTime) { endtime = c.EndTime; } } } }
/** Shade all the chords played in the given time. * Un-shade any chords shaded in the previous pulse time. * Store the x coordinate location where the shade was drawn. */ public void ShadeNotes(Graphics g, SolidBrush shadeBrush, Pen pen, int currentPulseTime, int prevPulseTime, ref int x_shade) { /* If there's nothing to unshade, or shade, return */ if ((starttime > prevPulseTime || endtime < prevPulseTime) && (starttime > currentPulseTime || endtime < currentPulseTime)) { return; } /* Skip the left side Clef symbol and key signature */ int xpos = keysigWidth; MusicSymbol curr = null; ChordSymbol prevChord = null; int prev_xpos = 0; /* Loop through the symbols. * Unshade symbols where start <= prevPulseTime < end * Shade symbols where start <= currentPulseTime < end */ for (int i = 0; i < symbols.Count; i++) { curr = symbols[i]; if (curr is BarSymbol) { xpos += curr.Width; continue; } int start = curr.StartTime; int end = 0; if (i + 2 < symbols.Count && symbols[i + 1] is BarSymbol) { end = symbols[i + 2].StartTime; } else if (i + 1 < symbols.Count) { end = symbols[i + 1].StartTime; } else { end = endtime; } /* If we've past the previous and current times, we're done. */ if ((start > prevPulseTime) && (start > currentPulseTime)) { if (x_shade == 0) { x_shade = xpos; } return; } /* If shaded notes are the same, we're done */ if ((start <= currentPulseTime) && (currentPulseTime < end) && (start <= prevPulseTime) && (prevPulseTime < end)) { x_shade = xpos; return; } bool redrawLines = false; /* If symbol is in the previous time, draw a white background */ if ((start <= prevPulseTime) && (prevPulseTime < end)) { g.TranslateTransform(xpos - 2, -2); g.FillRectangle(Brushes.White, 0, 0, curr.Width + 4, this.Height + 4); g.TranslateTransform(-(xpos - 2), 2); g.TranslateTransform(xpos, 0); curr.Draw(g, pen, ytop); g.TranslateTransform(-xpos, 0); redrawLines = true; } /* If symbol is in the current time, draw a shaded background */ if ((start <= currentPulseTime) && (currentPulseTime < end)) { x_shade = xpos; g.TranslateTransform(xpos, 0); g.FillRectangle(shadeBrush, 0, 0, curr.Width, this.Height); curr.Draw(g, pen, ytop); g.TranslateTransform(-xpos, 0); redrawLines = true; } /* If either a gray or white background was drawn, we need to redraw * the horizontal staff lines, and redraw the stem of the previous chord. */ if (redrawLines) { int line = 1; int y = ytop - SheetMusic.LineWidth; pen.Width = 1; g.TranslateTransform(xpos - 2, 0); for (line = 1; line <= 5; line++) { g.DrawLine(pen, 0, y, curr.Width + 4, y); y += SheetMusic.LineWidth + SheetMusic.LineSpace; } g.TranslateTransform(-(xpos - 2), 0); if (prevChord != null) { g.TranslateTransform(prev_xpos, 0); prevChord.Draw(g, pen, ytop); g.TranslateTransform(-prev_xpos, 0); } if (showMeasures) { DrawMeasureNumbers(g, pen); } if (lyrics != null) { DrawLyrics(g, pen); } } if (curr is ChordSymbol) { ChordSymbol chord = (ChordSymbol)curr; if (chord.Stem != null && !chord.Stem.Receiver) { prevChord = (ChordSymbol)curr; prev_xpos = xpos; } } xpos += curr.Width; } }