예제 #1
0
        internal static MidiFileData ReadMidiFile(string filePath)
        {
            var data   = new MidiFileData();
            var reader = FileReaderFactory.CreateReader(filePath);

            data.Header = reader.ReadNextChunk() as MThdChunk;

            var tracks = new List <MTrkChunk>();

            for (int i = 0; i < data.Header.NumberOfTracks; i++)
            {
                try
                {
                    var track = reader.ReadNextChunk() as MTrkChunk;

                    if (track != null)
                    {
                        tracks.Add(track);
                    }
                    else
                    {
                        Console.WriteLine(String.Format("Track '{0}' was not read successfully.", i + 1));
                    }
                }
                catch (Exception e)
                {
                    reader.SkipCurrentChunk();

                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Failed to read track: " + (i + 1));
                    Console.WriteLine(e);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
            }

            data.Tracks = tracks;
            return(data);
        }
예제 #2
0
        private static MidiOutPortBase ProcessStreaming(int outPortId, MidiFileData fileData,
                                                        IEnumerable <MidiFileEvent> notes, MidiOutPortCaps caps)
        {
            var outPort = new MidiOutStreamPort();

            outPort.Open(outPortId);
            outPort.BufferManager.Initialize(10, 1024);
            outPort.TimeDivision = fileData.Header.TimeDivision;

            // TODO: extract Tempo from meta messages from the file.
            // 120 bpm (uSec/QuarterNote).
            outPort.Tempo = 500000;

            Console.WriteLine(String.Format("Midi Out Stream Port '{0}' is now open.", caps.Name));

            MidiMessageOutStreamWriter writer = null;
            MidiBufferStream           buffer = null;
            MidiFileEvent lastNote            = null;

            foreach (var note in notes)
            {
                if (writer == null)
                {
                    // brute force buffer aqcuirement.
                    // when callbacks are implemented this will be more elegant.
                    do
                    {
                        buffer = outPort.BufferManager.RetrieveBuffer();

                        if (buffer != null)
                        {
                            break;
                        }

                        Thread.Sleep(50);
                    } while (buffer == null);

                    writer = new MidiMessageOutStreamWriter(buffer);
                }

                if (writer.CanWrite(note.Message))
                {
                    if (lastNote != null)
                    {
                        // fixup delta time artifically...
                        writer.Write(note.Message, (int)(note.AbsoluteTime - lastNote.AbsoluteTime));
                    }
                    else
                    {
                        writer.Write(note.Message, (int)note.DeltaTime);
                    }
                }
                else
                {
                    outPort.LongData(buffer);
                    writer = null;

                    Console.WriteLine("Buffer sent...");

                    if (!outPort.HasStatus(MidiPortStatus.Started))
                    {
                        outPort.Restart();
                    }
                }

                lastNote = note;
            }

            return(outPort);
        }