public override void Load(string filePath) { List <List <TrackEvent> > trackEvents = new List <List <TrackEvent> >(); BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open), Encoding.UTF8); _header = readHeader(reader); if (!_header.DeltaTimeInPPQN) { throw new SMFException("対応していないMIDIファイル:TimeInSec Division"); } if (_header.FormatType == 2) { throw new SMFException("対応していないMIDIファイル:Format"); } for (int i = 0; i < _header.TrackNum; i++) { List <TrackEvent> evs = new List <TrackEvent>(); readTrack(reader, ref evs); trackEvents.Add(evs); } double maxPitch = double.MinValue; double minPitch = double.MaxValue; long prevTick = 0; double time = 0; int tempo = 500000; double ppqnInv = 1 / (double)_header.DeltaTime; Dictionary <int, Dictionary <int, SMFNote> > channels = new Dictionary <int, Dictionary <int, SMFNote> >(); _points = new List <MusicNote>(); while (true) { if (trackEvents.Count == 0) { break; } if (trackEvents.TrueForAll((lst) => { return(lst.Count == 0); })) { break; } int idx = -1; long minTick = long.MaxValue; for (int i = 0; i < trackEvents.Count; i++) { if (trackEvents[i].Count == 0) { continue; } long tick = trackEvents[i][0].AbsoluteTick; if (tick < minTick) { idx = i; minTick = tick; } } if (idx < 0) { break; } TrackEvent fstev = trackEvents[idx][0]; trackEvents[idx].RemoveAt(0); time += (fstev.AbsoluteTick - prevTick) * tempo * ppqnInv / 1000000.0; switch (fstev.EventType) { case EventType.Tempo: tempo = (int)fstev.Params[0]; break; case EventType.NoteOn: { int channel = (int)fstev.Params[0]; int noteNum = (int)fstev.Params[1]; Dictionary <int, SMFNote> noteNums; if (channels.ContainsKey(channel)) { noteNums = channels[channel]; } else { noteNums = new Dictionary <int, SMFNote>(); channels.Add(channel, noteNums); } SMFNote note; if (noteNums.ContainsKey(noteNum)) { note = noteNums[noteNum]; MusicNote n = new MusicNote(); n.TimeInSec = time; n.Pitch = note.Pitch; n.Start = false; _points.Add(n); } note = new SMFNote(true, pitchFromNote(noteNum)); if (noteNums.ContainsKey(noteNum)) { noteNums[noteNum] = note; } else { noteNums.Add(noteNum, note); } MusicNote nn = new MusicNote(); nn.TimeInSec = time; nn.Pitch = note.Pitch; nn.Start = true; _points.Add(nn); if (note.Pitch < minPitch) { minPitch = note.Pitch; } if (note.Pitch > maxPitch) { maxPitch = note.Pitch; } } break; case EventType.NoteOff: { int channel = (int)fstev.Params[0]; int noteNum = (int)fstev.Params[1]; Dictionary <int, SMFNote> noteNums; if (channels.ContainsKey(channel)) { noteNums = channels[channel]; } else { noteNums = new Dictionary <int, SMFNote>(); channels.Add(channel, noteNums); } SMFNote note; if (noteNums.ContainsKey(noteNum)) { note = noteNums[noteNum]; MusicNote n = new MusicNote(); n.TimeInSec = time; n.Pitch = note.Pitch; n.Start = false; _points.Add(n); if (note.Pitch < minPitch) { minPitch = note.Pitch; } if (note.Pitch > maxPitch) { maxPitch = note.Pitch; } noteNums.Remove(noteNum); } } break; } prevTick = fstev.AbsoluteTick; } _length = time; ToneResult minTone = ToneAnalyzer.Analyze(minPitch, 1.0); ToneResult maxTone = ToneAnalyzer.Analyze(maxPitch, 1.0); maxTone.ToneIdx++; if (maxTone.ToneIdx >= 12) { maxTone.ToneIdx -= 12; maxTone.Octave++; } minTone.ToneIdx--; if (minTone.ToneIdx <= 0) { minTone.ToneIdx += 12; minTone.Octave--; } MinPitch = ToneAnalyzer.PitchFromTone(minTone.ToneIdx, minTone.Octave); MaxPitch = ToneAnalyzer.PitchFromTone(maxTone.ToneIdx, maxTone.Octave); _points.Sort((MusicNote n1, MusicNote n2) => { if (n1.TimeInSec != n2.TimeInSec) { return(n1.TimeInSec.CompareTo(n2.TimeInSec)); } if (n1.Start) { if (n2.Start) { return(0); } return(1); } else { if (n2.Start) { return(-1); } return(0); } }); }
public override void Load(string filePath) { List<List<TrackEvent>> trackEvents = new List<List<TrackEvent>>(); BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open), Encoding.UTF8); _header = readHeader(reader); if (!_header.DeltaTimeInPPQN) throw new SMFException("対応していないMIDIファイル:TimeInSec Division"); if (_header.FormatType == 2) throw new SMFException("対応していないMIDIファイル:Format"); for (int i = 0; i < _header.TrackNum; i++) { List<TrackEvent> evs = new List<TrackEvent>(); readTrack(reader, ref evs); trackEvents.Add(evs); } double maxPitch = double.MinValue; double minPitch = double.MaxValue; long prevTick = 0; double time = 0; int tempo = 500000; double ppqnInv = 1 / (double)_header.DeltaTime; Dictionary<int, Dictionary<int, SMFNote>> channels = new Dictionary<int, Dictionary<int, SMFNote>>(); _points = new List<MusicNote>(); while (true) { if (trackEvents.Count == 0) break; if (trackEvents.TrueForAll((lst) => { return lst.Count == 0; })) break; int idx = -1; long minTick = long.MaxValue; for (int i = 0; i < trackEvents.Count; i++) { if (trackEvents[i].Count == 0) continue; long tick = trackEvents[i][0].AbsoluteTick; if (tick < minTick) { idx = i; minTick = tick; } } if (idx < 0) break; TrackEvent fstev = trackEvents[idx][0]; trackEvents[idx].RemoveAt(0); time += (fstev.AbsoluteTick - prevTick) * tempo * ppqnInv / 1000000.0; switch (fstev.EventType) { case EventType.Tempo: tempo = (int)fstev.Params[0]; break; case EventType.NoteOn: { int channel = (int)fstev.Params[0]; int noteNum = (int)fstev.Params[1]; Dictionary<int, SMFNote> noteNums; if (channels.ContainsKey(channel)) { noteNums = channels[channel]; } else { noteNums = new Dictionary<int, SMFNote>(); channels.Add(channel, noteNums); } SMFNote note; if (noteNums.ContainsKey(noteNum)) { note = noteNums[noteNum]; MusicNote n = new MusicNote(); n.TimeInSec = time; n.Pitch = note.Pitch; n.Start = false; _points.Add(n); } note = new SMFNote(true, pitchFromNote(noteNum)); if (noteNums.ContainsKey(noteNum)) noteNums[noteNum] = note; else noteNums.Add(noteNum, note); MusicNote nn = new MusicNote(); nn.TimeInSec = time; nn.Pitch = note.Pitch; nn.Start = true; _points.Add(nn); if (note.Pitch < minPitch) minPitch = note.Pitch; if (note.Pitch > maxPitch) maxPitch = note.Pitch; } break; case EventType.NoteOff: { int channel = (int)fstev.Params[0]; int noteNum = (int)fstev.Params[1]; Dictionary<int, SMFNote> noteNums; if (channels.ContainsKey(channel)) { noteNums = channels[channel]; } else { noteNums = new Dictionary<int, SMFNote>(); channels.Add(channel, noteNums); } SMFNote note; if (noteNums.ContainsKey(noteNum)) { note = noteNums[noteNum]; MusicNote n = new MusicNote(); n.TimeInSec = time; n.Pitch = note.Pitch; n.Start = false; _points.Add(n); if (note.Pitch < minPitch) minPitch = note.Pitch; if (note.Pitch > maxPitch) maxPitch = note.Pitch; noteNums.Remove(noteNum); } } break; } prevTick = fstev.AbsoluteTick; } _length = time; ToneResult minTone = ToneAnalyzer.Analyze(minPitch, 1.0); ToneResult maxTone = ToneAnalyzer.Analyze(maxPitch, 1.0); maxTone.ToneIdx++; if (maxTone.ToneIdx >= 12) { maxTone.ToneIdx -= 12; maxTone.Octave++; } minTone.ToneIdx--; if (minTone.ToneIdx <= 0) { minTone.ToneIdx += 12; minTone.Octave--; } MinPitch = ToneAnalyzer.PitchFromTone(minTone.ToneIdx, minTone.Octave); MaxPitch = ToneAnalyzer.PitchFromTone(maxTone.ToneIdx, maxTone.Octave); _points.Sort((MusicNote n1, MusicNote n2) => { if (n1.TimeInSec != n2.TimeInSec) return n1.TimeInSec.CompareTo(n2.TimeInSec); if (n1.Start) { if (n2.Start) return 0; return 1; } else { if (n2.Start) return -1; return 0; } }); }