示例#1
0
        private static SMFHeader readHeader(BinaryReader reader)
        {
            SMFHeader header = new SMFHeader();

            char[] chunkIDChars = reader.ReadChars(4);
            string chunkID      = new string(chunkIDChars);

            if (chunkID != "MThd")
            {
                throw new SMFException("invalid chunkID");
            }
            uint dataSize = readBENumeric(reader, 4);

            header.FormatType      = readBENumeric(reader, 2);
            header.TrackNum        = readBENumeric(reader, 2);
            header.DeltaTime       = readBENumeric(reader, 2);
            header.DeltaTimeInPPQN = false;
            if ((header.DeltaTime & 0x8000) == 0) // MSBが立っていない
            {
                header.DeltaTimeInPPQN = true;
                header.DeltaTime       = header.DeltaTime & 0x7fff;
            }
            else
            {
                header.DeltaTime = (header.DeltaTime & 0x7f00) * (header.DeltaTime & 0x00ff);
            }

            if (dataSize > 6)
            {
                reader.ReadBytes((int)(dataSize - 6));
            }

            return(header);
        }
示例#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)
        {
            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;
                }
            });
        }
示例#4
0
        private static SMFHeader readHeader(BinaryReader reader)
        {
            SMFHeader header = new SMFHeader();

            char[] chunkIDChars = reader.ReadChars(4);
            string chunkID = new string(chunkIDChars);
            if (chunkID != "MThd")
            {
                throw new SMFException("invalid chunkID");
            }
            uint dataSize = readBENumeric(reader, 4);
            header.FormatType = readBENumeric(reader, 2);
            header.TrackNum = readBENumeric(reader, 2);
            header.DeltaTime = readBENumeric(reader, 2);
            header.DeltaTimeInPPQN = false;
            if ((header.DeltaTime & 0x8000) == 0) // MSBが立っていない
            {
                header.DeltaTimeInPPQN = true;
                header.DeltaTime = header.DeltaTime & 0x7fff;
            }
            else
            {
                header.DeltaTime = (header.DeltaTime & 0x7f00) * (header.DeltaTime & 0x00ff);
            }

            if (dataSize > 6) reader.ReadBytes((int)(dataSize - 6));

            return header;
        }