/** Set the MidiFile to use. * Save the list of midi notes. Each midi note includes the note Number * and StartTime (in pulses), so we know which notes to shade given the * current pulse time. */ public void SetMidiFile(MidiFile midifile, MidiOptions options) { if (midifile == null) { notes = null; useTwoColors = false; return; } List<MidiTrack> tracks = midifile.ChangeMidiNotes(options); MidiTrack track = MidiFile.CombineToSingleTrack(tracks); notes = track.Notes; maxShadeDuration = midifile.Time.Quarter * 2; /* We want to know which track the note came from. * Use the 'channel' field to store the track. */ for (int tracknum = 0; tracknum < tracks.Count; tracknum++) { foreach (MidiNote note in tracks[tracknum].Notes) { note.Channel = tracknum; } } /* When we have exactly two tracks, we assume this is a piano song, * and we use different colors for highlighting the left hand and * right hand notes. */ useTwoColors = false; if (tracks.Count == 2) { useTwoColors = true; } showNoteLetters = options.showNoteLetters; this.Invalidate(); }
/** Create a new SheetMusic control. * MidiFile is the parsed midi file to display. * SheetMusic Options are the menu options that were selected. * * - Apply all the Menu Options to the MidiFile tracks. * - Calculate the key signature * - For each track, create a list of MusicSymbols (notes, rests, bars, etc) * - Vertically align the music symbols in all the tracks * - Partition the music notes into horizontal staffs */ public void init(MidiFile file, MidiOptions options) { if (options == null) { options = new MidiOptions(file); } zoom = 1.0f; filename = file.FileName; SetColors(options.colors, options.shadeColor, options.shade2Color); pen = new Pen(Color.Black, 1); List<MidiTrack> tracks = file.ChangeMidiNotes(options); SetNoteSize(options.largeNoteSize); scrollVert = options.scrollVert; showNoteLetters= options.showNoteLetters; TimeSignature time = file.Time; if (options.time != null) { time = options.time; } if (options.key == -1) { mainkey = GetKeySignature(tracks); } else { mainkey = new KeySignature(options.key); } numtracks = tracks.Count; int lastStart = file.EndTime() + options.shifttime; /* Create all the music symbols (notes, rests, vertical bars, and * clef changes). The symbols variable contains a list of music * symbols for each track. The list does not include the left-side * Clef and key signature symbols. Those can only be calculated * when we create the staffs. */ List<MusicSymbol>[] symbols = new List<MusicSymbol> [ numtracks ]; for (int tracknum = 0; tracknum < numtracks; tracknum++) { MidiTrack track = tracks[tracknum]; ClefMeasures clefs = new ClefMeasures(track.Notes, time.Measure); List<ChordSymbol> chords = CreateChords(track.Notes, mainkey, time, clefs); symbols[tracknum] = CreateSymbols(chords, clefs, time, lastStart); } List<LyricSymbol>[] lyrics = null; if (options.showLyrics) { lyrics = GetLyrics(tracks); } /* Vertically align the music symbols */ SymbolWidths widths = new SymbolWidths(symbols, lyrics); // SymbolWidths widths = new SymbolWidths(symbols); AlignSymbols(symbols, widths); staffs = CreateStaffs(symbols, mainkey, options, time.Measure); CreateAllBeamedChords(symbols, time); if (lyrics != null) { AddLyricsToStaffs(staffs, lyrics); } /* After making chord pairs, the stem directions can change, * which affects the staff height. Re-calculate the staff height. */ foreach (Staff staff in staffs) { staff.CalculateHeight(); } BackColor = Color.White; SetZoom(1.0f); }