CreateSymbols(List <ChordSymbol> chords, ClefMeasures clefs, TimeSignature time, int lastStart) { List <MusicSymbol> symbols = new List <MusicSymbol>(); symbols = AddBars(chords, time, lastStart); symbols = AddRests(symbols, time); symbols = AddClefChanges(symbols, clefs, time); return(symbols); }
List <MusicSymbol> AddClefChanges(List <MusicSymbol> symbols, ClefMeasures clefs, TimeSignature time) { List <MusicSymbol> result = new List <MusicSymbol>(symbols.Count); Clef prevclef = clefs.GetClef(0); foreach (MusicSymbol symbol in symbols) { /* A BarSymbol indicates a new measure */ if (symbol is BarSymbol) { Clef clef = clefs.GetClef(symbol.StartTime); if (clef != prevclef) { result.Add(new ClefSymbol(clef, symbol.StartTime - 1, true)); } prevclef = clef; } result.Add(symbol); } return(result); }
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); }
/** Create the chord symbols for a single track. * @param midinotes The Midinotes in the track. * @param key The Key Signature, for determining sharps/flats. * @param time The Time Signature, for determining the measures. * @param clefs The clefs to use for each measure. * @ret An array of ChordSymbols */ private 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; }
/** The current clef is always shown at the beginning of the staff, on * the left side. However, the clef can also change from measure to * measure. When it does, a Clef symbol must be shown to indicate the * change in clef. This function adds these Clef change symbols. * This function does not add the main Clef Symbol that begins each * staff. That is done in the Staff() contructor. */ private List<MusicSymbol> AddClefChanges(List<MusicSymbol> symbols, ClefMeasures clefs, TimeSignature time) { List<MusicSymbol> result = new List<MusicSymbol>( symbols.Count ); Clef prevclef = clefs.GetClef(0); foreach (MusicSymbol symbol in symbols) { /* A BarSymbol indicates a new measure */ if (symbol is BarSymbol) { Clef clef = clefs.GetClef(symbol.StartTime); if (clef != prevclef) { result.Add(new ClefSymbol(clef, symbol.StartTime-1, true)); } prevclef = clef; } result.Add(symbol); } return result; }
/** Create a new SheetMusic control, using the given midi filename. * The options can be null. */ //public SheetMusic(string filename, MidiOptions options) { // MidiFile file = new MidiFile(filename); // init(file, options); //} /** Create a new SheetMusic control, using the given raw midi byte[] data. * The options can be null. */ //public SheetMusic(byte[] data, string title, MidiOptions options) { // MidiFile file = new MidiFile(data, title); // init(file, options); // } /** 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 Load(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(); } braces = CreateBraceSymbols(staffs); BackColor = Color.White; SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); // ��ֹ��������. SetStyle(ControlStyles.DoubleBuffer, true); }
/** Given the chord symbols for a track, create a new symbol list * that contains the chord symbols, vertical bars, rests, and clef changes. * Return a list of symbols (ChordSymbol, BarSymbol, RestSymbol, ClefSymbol) */ private List<MusicSymbol> CreateSymbols(List<ChordSymbol> chords, ClefMeasures clefs, TimeSignature time, int lastStart) { List<MusicSymbol> symbols = new List<MusicSymbol>(); symbols = AddBars(chords, time, lastStart); symbols = AddRests(symbols, time); symbols = AddClefChanges(symbols, clefs, time); return symbols; }
/** 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); }
public void TestMainClefTreble() { List<MidiNote> notes = new List<MidiNote>(); for (int i = 0; i < 100; i++) { int num = F4 + (i % 20); MidiNote note = new MidiNote(i*10, 0, num, 5); notes.Add(note); } for (int i = 100; i < 200; i++) { int num = G3 - (i % 2); MidiNote note = new MidiNote(i*10, 0, num, 5); notes.Add(note); } for (int i = 200; i < 300; i++) { int num = middleC - (i % 2); MidiNote note = new MidiNote(i*10, 0, num, 5); notes.Add(note); } ClefMeasures clefs = new ClefMeasures(notes, 50); for (int i = 0; i < 100; i++) { Clef clef = clefs.GetClef(i*10); Assert.AreEqual(clef, Clef.Treble); } for (int i = 100; i < 200; i++) { Clef clef = clefs.GetClef(i*10); Assert.AreEqual(clef, Clef.Bass); } for (int i = 200; i < 300; i++) { Clef clef = clefs.GetClef(i*10); /* Even though the average note is below middle C, * the main clef is treble. */ Assert.AreEqual(clef, Clef.Treble); } }
public void TestAllTreble() { List<MidiNote> notes = new List<MidiNote>(); for (int i = 0; i < 100; i++) { int num = middleC + (i % 5); MidiNote note = new MidiNote(i*10, 0, num, 5); notes.Add(note); } ClefMeasures clefs = new ClefMeasures(notes, 40); for (int i = 0; i < 100; i++) { Clef clef = clefs.GetClef(10 * i); Assert.AreEqual(clef, Clef.Treble); } }