private double pitchFromNote(int noteNum) { if (_notePitches.ContainsKey(noteNum)) { return(_notePitches[noteNum]); } int toneIdx = noteNum % 12; int octave = (int)((noteNum - toneIdx) / 12.0) - 1; double pitch = ToneAnalyzer.PitchFromTone(toneIdx, octave); _notePitches.Add(noteNum, pitch); return(pitch); }
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) { _curTime = 0; _points.Clear(); load(filePath); foreach (Note n in _notes) { if (n.ToneIdx >= 0) { double pLen = n.Length; if (n.LenRatio >= 0 && n.LenRatio < 8) { pLen *= n.LenRatio / 8.0; } MusicNote onNote = new MusicNote(); onNote.Pitch = ToneAnalyzer.PitchFromTone(n.ToneIdx, n.Octave); onNote.Start = true; onNote.TimeInSec = _curTime; _points.Add(onNote); MusicNote offNote = new MusicNote(); offNote.Pitch = onNote.Pitch; offNote.Start = false; offNote.TimeInSec = _curTime + pLen; _points.Add(offNote); if (_maxP < onNote.Pitch) { _maxP = onNote.Pitch; } if (_minP > onNote.Pitch) { _minP = onNote.Pitch; } } _curTime += n.Length; } Length = _curTime; ToneResult minTone = ToneAnalyzer.Analyze(_minP, 1.0); ToneResult maxTone = ToneAnalyzer.Analyze(_maxP, 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); } }); }