示例#1
0
        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);
        }
示例#2
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);
                }
            });
        }
示例#3
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);
                }
            });
        }