private void BtnOpen_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Filter = "Midi Files|*.mid";
            openFileDialog.Title  = "Select a Midi File";

            if (openFileDialog.ShowDialog().Value)
            {
                string filename = openFileDialog.FileName;

                //todo: using Dispatcher.Invoke doesn't work
                Dispatcher.Invoke(() => { txt.Text += $"File {filename} loading...\r\n"; });
                composition = MidiFileReader.Read(filename);
                Dispatcher.Invoke(() => { txt.Text += "File loaded.\r\n"; this.UpdateLayout(); });

                txt.Text += "Analysing...\r\n";
                var allNodes = ChomskyGrammarAnalysis.Reduce(composition.GetVoices(), new List <TwelveToneSet>()
                {
                    TwelveToneSet.majorScale
                });
                txt.Text += $"Analysis finished!\r\n";

                txt.Text += "Post analysis...\r\n";
                ChomskyGrammarAnalysis.PostAnalysis(composition.GetVoices());
                txt.Text += "Post analysis finished!\r\n";

                this.Title = $"{filename} - Music Analysis";

                listView.ItemsSource = allNodes;
            }
        }
Beispiel #2
0
        public void TestConvertMidi()
        {
            // File to test against (result file)
            string baselineFilePath = @"Tests\Passacaglia, Handel_Sample_Cubase_Format0.mid";
            var    baselineFileInfo = new FileInfo(baselineFilePath);
            var    sequenceBaseline = new MidiFileReader().GetSequence(baselineFileInfo);

            // Dump Baseline Midi
            string baselineTextPath = baselineFileInfo.Name + "_dump.txt";

            sequenceBaseline.DumpMidi(baselineTextPath);

            // File to test with
            string fileName = @"Tests\Passacaglia, Handel_Sample.mid";
            var    fileInfo = new FileInfo(fileName);
            var    sequence = new MidiFileReader().GetSequence(fileInfo);

            // Convert Midi to Format 0
            var convertedSequence = sequence.Convert((int)MidiHelper.MidiFormat.SingleTrack, SequenceExtensions.FormatConversionOption.NoteOffZero2NoteOnZero, 480, "SongNameForType0");

            // Dump Converted Midi
            string convertedOutputTextPath = fileInfo.Name + "_converted_dump.txt";

            convertedSequence.DumpMidi(convertedOutputTextPath);

            if (FileCompare(baselineTextPath, convertedOutputTextPath))
            {
                Assert.Pass("The midi files are identical.");
            }
            else
            {
                Assert.Fail("The midi files are different!");
            }
        }
        public void PlayBackTest(string filename)
        {
            Composition composition = MidiFileReader.Read(filename);

            int[] tones = new int[128];

            // Play the composition keeping track of what nodes are on/off
            composition.PlayBack(
                note =>
            {
                tones[note]++;
            },
                note =>
            {
                tones[note]--;
                Assert.IsTrue(tones[note] >= 0);
            },
                IncludeDurations: false
                );

            // At the end all tones are released
            foreach (int i in tones)
            {
                Assert.AreEqual(0, tones[0]);
            }
        }
Beispiel #4
0
        static void Main(string[] args)
        {
            string midiFileName = null;
            string bfFileName   = null;

            if (args.Length > 1)
            {
                midiFileName = args[0];
                bfFileName   = args[1];
            }
            if (args.Length <= 1)
            {
                Console.WriteLine("Usage: BadadoomToBF 'MidiFile.mid' 'BFFile.bf'");
                return;
            }

            var fileData = new MidiFileReader(midiFileName);

            var notes = fileData.Notes
                        .Where(x => x.Channel == PercussionChannel)
                        .OrderBy(x => x.AbsoluteTime)
                        .ToList();

            Translate(notes, bfFileName);
        }
Beispiel #5
0
        uint ReadInt32()
        {
            uint length = 0;

            for (int i = 0; i != 4; i++)
            {
                length = (uint)((length << 8) | (byte)MidiFileReader.ReadByte());
            }
            return(length);
        }
Beispiel #6
0
        ushort ReadInt16()
        {
            ushort length = 0;

            for (int i = 0; i != 2; i++)
            {
                length = (ushort)((length << 8) | (byte)MidiFileReader.ReadByte());
            }
            return(length);
        }
Beispiel #7
0
 void AssertText(string text)
 {
     foreach (char c in text)
     {
         if (MidiFileReader.ReadByte() != c)
         {
             throw new Exception("Corrupt chunk headers");
         }
     }
 }
Beispiel #8
0
        static void Main(string[] args)
        {
            string midiFileName = null;

            if (args.Length > 0)
            {
                midiFileName = args[0];
            }
            if (args.Length <= 0)
            {
                Console.WriteLine("Usage: Badadoom 'MidiFile.mid'");
                return;
            }

            var reader = new MidiFileReader(midiFileName);

            Interpreter(reader
                        .Notes
                        .Where(x => x.Channel == PercussionChannel)
                        .OrderBy(x => x.AbsoluteTime)
                        .ToList());
        }
Beispiel #9
0
        private void Test(string filename, int take = int.MaxValue, Fraction?prec = null)
        {
            var lists = MidiFileReader.Read(filename, prec).GetVoices().Take(take).ToList();

            // Save copy
            var copy = FlatCopy(lists);
            //AssertEqual(lists, copy);

            // Perform Chomsky reduction
            var allNodes = ChomskyGrammarAnalysis.Reduce(lists, new List <TwelveToneSet>()
            {
                TwelveToneSet.majorScale
            });

            AssertEqual(lists, copy);

            // At least one diatonic?
            //Assert.IsTrue(allNodes.Exists(mpl => mpl.IsDiatonic));

            // Post analysis
            ChomskyGrammarAnalysis.PostAnalysis(lists);
            ChomskyGrammarAnalysis.Print(allNodes);
            CheckPostAnalysis(allNodes, lists.Count);

            int totalNotesBefore = copy.Sum(list => list.Count);
            int totalNotesAfter  = allNodes.Sum(list => list.children.Count(imp => imp is NoteWithDuration));
            int totalLeafs       = allNodes.Sum(list => list.IsLeaf ? 1 : 0);
            int totalLeafNotes   = allNodes.Sum(list => list.IsLeaf ? list.Count : 0);

            Debug.WriteLine(filename);
            Debug.WriteLine($"Total notes before: {totalNotesBefore}");
            Debug.WriteLine($"Total notes after: {totalNotesAfter}");
            Debug.WriteLine($"After/before: {100 * totalNotesAfter / totalNotesBefore}%");
            Debug.WriteLine($"Total leaf notes: {totalLeafNotes}");
            Debug.WriteLine($"Leaf notes/before: {100 * totalLeafNotes / totalNotesBefore}%");
            Debug.WriteLine($"Total leafs: {totalLeafs}");
        }
Beispiel #10
0
        public void TestReadWriteMidi()
        {
            string inputFileName = @"Tests\Passacaglia, Handel_Sample.mid";

            var fileIn   = new FileInfo(inputFileName);
            var sequence = new MidiFileReader().GetSequence(fileIn);

            string outputTextPath = fileIn.Name + ".txt";

            sequence.DumpMidi(outputTextPath);

            string outputFileName = fileIn.Name + "_parsed.mid";

            sequence.Save(outputFileName);

            if (FileCompare(inputFileName, outputFileName))
            {
                Assert.Pass("The midi files are identical.");
            }
            else
            {
                Assert.Fail("The midi files are different!");
            }
        }
Beispiel #11
0
        public Project ShowDialog(FamiStudioForm parent)
        {
            var project = (Project)null;

            if (dialog != null)
            {
                // This is only ran in desktop and this isnt really async, so its ok.
                dialog.ShowDialogAsync(parent, (r) =>
                {
                    if (r == DialogResult.OK)
                    {
                        var expansionMask      = GetExpansionMask(dialog.Properties.GetPropertyValue <bool[]>(4));
                        var polyphony          = dialog.Properties.GetSelectedIndex(0);
                        var measuresPerPattern = dialog.Properties.GetPropertyValue <int>(1);
                        var velocityAsVolume   = dialog.Properties.GetPropertyValue <bool>(2);
                        var pal = expansionMask != ExpansionType.NoneMask ? false : dialog.Properties.GetPropertyValue <bool>(3);

                        project = new MidiFileReader().Load(filename, expansionMask, pal, channelSources, velocityAsVolume, polyphony, measuresPerPattern);
                    }
                });
            }

            return(project);
        }
Beispiel #12
0
        public void TestGenerateMidi()
        {
            //string fileName = @"Tests\Passacaglia, Handel_Sample.mid";
            //string fileName = @"Tests\agnes-release_me.mid";
            string fileName = @"Tests\Passacaglia, Handel_Sample_Cubase_Format0.mid";

            var fileIn   = new FileInfo(fileName);
            var sequence = new MidiFileReader().GetSequence(fileIn);

            string outputTextPath = fileIn.Name + "_dump.txt";

            sequence.DumpMidi(outputTextPath);

            // Generate C# Code
            string outputCodePath = fileIn.Name + "_code.cs";

            sequence.SaveGenerateMidiCode(outputCodePath);

            if (!CompileAndRunSource(outputCodePath))
            {
                Assert.Fail("Could not compile and run generated code!");
            }

            // read the generated midi dump file and compare against original
            if (!FileCompare(outputTextPath, "generated_dump.txt"))
            {
                Assert.Fail("The midi dump files are different!");
            }

            // read the generated midi file and compare against original
            //if (!FileCompare(fileName, "generated.mid")) {
            //	Assert.Fail("The midi files are different!");
            //}

            Assert.Pass("The midi files are identical.");
        }
Beispiel #13
0
 public override void Parse()
 {
     try
     {
         Open();
         FirstPassParse();
         foreach (var p in parsers)
         {
             p.globaTempos = globalTempos;
             p.PrepareForSecondPass();
         }
         SecondPassParse();
         MidiLength = parsers.Select(p => p.trackSeconds).Max();
         foreach (var p in parsers)
         {
             p.Dispose();
         }
         parsers         = null;
         globalTempos    = null;
         trackBeginnings = null;
         trackLengths    = null;
         MidiFileReader.Dispose();
         MidiFileReader = null;
         GC.Collect();
         cancel.ThrowIfCancellationRequested();
         LastColorEvent = new int[trackcount * 16];
         SetColors();
         ParseFinishedInvoke();
     }
     catch (OperationCanceledException)
     {
         MidiFileReader.Close();
         MidiFileReader.Dispose();
         ParseCancelledInvoke();
     }
 }
Beispiel #14
0
 static RBMid GetMid(string name)
 {
     using (var s = GetFile(name)) return(RBMidConverter.ToRBMid(MidiFileReader.FromStream(GetFile(name))));
 }
Beispiel #15
0
        public Main()
        {
            _instance = this;

            this.FontGenerator = new Endogine.Text.FontGenerator();
            Endogine.Text.FontGenerator fg = this.FontGenerator;
            fg.UseStyleTemplate("Test1");
            fg.FontSize          = 20;
            fg.DefinedCharacters = Endogine.Text.FontGenerator.GetCharSet(Endogine.Text.FontGenerator.CharSet.Default, false, false);

            this.Score = new Score();
            this.Score.FontGenerator = fg;
            this.Score.Value         = 0;
            this.Score.Loc           = new EPointF(30, 30);

//			Endogine.Forms.Label lbl = new Endogine.Forms.Label();
//			lbl.FontGenerator = fg;
//			lbl.Text = "AbrakadagvAsk49Å";
//			lbl.Loc = new EPointF(100,100);


            this._scripter = ScriptingProvider.CreateScripter("boo");
            Hashtable htScripts = new Hashtable();

            htScripts.Add("Test", Endogine.Files.FileReadWrite.Read(Endogine.AppSettings.Instance.FindFile("test.boo")));
            this._interactorClassNames = new ArrayList();
            this._interactorClassNames.Add("Test");
            this._scripter.CompileMultiple(htScripts);


            //Hashtable htKeys = new Hashtable();
            //Endogine.KeysSteering _keys = new KeysSteering(htKeys);
            EH.Instance.KeyEvent += new KeyEventHandler(Instance_KeyEvent);

            Node   tracks = new Node();
            string sFile  = "Muppet_Show";

            sFile = "Flourish";
            float fSpeed = 1f;

            switch (sFile)
            {
            case "Flourish":
                tracks.GetOrCreate("Drums.Interactor").Text   = "X";
                tracks.GetOrCreate("Drums.LocSetter").Text    = "Default";
                tracks.GetOrCreate("Kalimba.Interactor").Text = "Shake";
                tracks.GetOrCreate("Kalimba.LocSetter").Text  = "Swirl";
                tracks.GetOrCreate("Piano.Interactor").Text   = "Default";
                sFile  = @"C:\WINDOWS\Media\" + sFile;
                fSpeed = 0.8f;
                break;

            case "Muppet_Show":
                tracks.GetOrCreate("HONKY TONK PIAN.Interactor").Text = "X";
                tracks.GetOrCreate("HONKY TONK PIAN.LocSetter").Text  = "Default";
                tracks.GetOrCreate("SAX.Interactor").Text             = "Shake";
                tracks.GetOrCreate("SAX.LocSetter").Text   = "Swirl";
                tracks.GetOrCreate("TUBA.Interactor").Text = "Default";
                break;
            }

            this._factory = new InteractorFactory(tracks);
            this._factory.ReadAheadMsecs = this._readAheadMsecs;

            sFile = Endogine.AppSettings.Instance.FindFile(sFile + ".mid");
            //sFile = @"C:\WINDOWS\Media\Flourish.MID"; //ONESTOP
            MidiFileReader reader = new MidiFileReader(sFile);

            OutputDevice output = new OutputDevice(0);

            output.Open(0);
            this._sequencer          = new SequencerBase(null, output);
            this._sequencer.Sequence = reader.Sequence;

            this._sequencer.PlaybackSpeed = fSpeed;
            this._sequencer.Start();
            //			this._sequencer.Tempo = 40;

            Endogine.Midi.Devices.EmptyMidiSender midiSender = new Endogine.Midi.Devices.EmptyMidiSender();
            //ScreenOutputDevice midiSender = new ScreenOutputDevice(this.progressBar1);
            this._sequencerPre          = new SequencerBase(null, midiSender);
            this._sequencerPre.Sequence = reader.Sequence;

            TrackPlayer tp;

            for (int i = 0; i < tracks.ChildNodes.Count; i++)
            {
                tp = this._sequencerPre.Player.GetTrackPlayer(tracks[i].Name);                 //Drums
                tp.TrackMessage += new Endogine.Midi.TrackPlayer.TrackMessageDelegate(tp_TrackMessage);
            }

            this._sequencerPre.Start();
            this._sequencerPre.Position      = (int)(this._sequencer.PlaybackTempo * this._readAheadMsecs / 1000 * 6);  //PlaybackTempo
            this._sequencerPre.PlaybackSpeed = this._sequencer.PlaybackSpeed;
            this._sequencerPre.Tempo         = this._sequencer.Tempo;
        }
Beispiel #16
0
 static RBMid GetMid(string name) => RBMidConverter.ToRBMid(MidiFileReader.FromStream(GetFile(name)));
Beispiel #17
0
    public void TestShort()
    {
        ushort[] nums = new ushort[] { 200, 3000, 10000, 40000 };
        byte[] data = new byte[nums.Length * 2];
        int index = 0;
        for (int i = 0; i < nums.Length; i++) {
            data[index]   = (byte)( (nums[i] >> 8) & 0xFF );
            data[index+1] = (byte)( nums[i] & 0xFF );
            index += 2;
        }
        WriteTestFile(data);
        MidiFileReader reader = new MidiFileReader(testfile);

        int offset = 0;
        foreach (ushort u in nums) {
            Assert.AreEqual(reader.GetOffset(), offset);
            Assert.AreEqual(reader.ReadShort(), u);
            offset += 2;
        }
        File.Delete(testfile);
    }
Beispiel #18
0
    public void TestByte()
    {
        byte[] data = new byte[] { 10, 20, 30, 40, 50 };
        WriteTestFile(data);
        MidiFileReader reader = new MidiFileReader(testfile);

        int offset = 0;
        foreach (byte b in data) {
            Assert.AreEqual(reader.GetOffset(), offset);
            Assert.AreEqual(reader.Peek(), b);
            Assert.AreEqual(reader.ReadByte(), b);
            offset++;
        }
        File.Delete(testfile);
    }
Beispiel #19
0
        /** Parse the given Midi file, and return an instance of this MidiFile
         * class.  After reading the midi file, this object will contain:
         * - The raw list of midi events
         * - The Time Signature of the song
         * - All the tracks in the song which contain notes.
         * - The number, starttime, and duration of each note.
         */
        public void parse(MidiFileReader file, string filename)
        {
            string id;
            int len;

            this.filename = filename;
            tracks = new List<MidiTrack>();
            trackPerChannel = false;

            id = file.ReadAscii(4);
            if (id != "MThd") {
            throw new MidiFileException("Doesn't start with MThd", 0);
            }
            len = file.ReadInt();
            if (len !=  6) {
            throw new MidiFileException("Bad MThd header", 4);
            }
            trackmode = file.ReadShort();
            int num_tracks = file.ReadShort();
            quarternote = file.ReadShort();

            events = new List<MidiEvent>[num_tracks];
            for (int tracknum = 0; tracknum < num_tracks; tracknum++) {
            events[tracknum] = ReadTrack(file);
            MidiTrack track = new MidiTrack(events[tracknum], tracknum);
            if (track.Notes.Count > 0) {
                tracks.Add(track);
            }
            }

            /* Get the length of the song in pulses */
            foreach (MidiTrack track in tracks) {
            MidiNote last = track.Notes[track.Notes.Count-1];
            if (this.totalpulses < last.StartTime + last.Duration) {
                this.totalpulses = last.StartTime + last.Duration;
            }
            }

            /* If we only have one track with multiple channels, then treat
             * each channel as a separate track.
             */
            if (tracks.Count == 1 && HasMultipleChannels(tracks[0])) {
            tracks = SplitChannels(tracks[0], events[tracks[0].Number]);
            trackPerChannel = true;
            }

            CheckStartTimes(tracks);

            /* Determine the time signature */
            int tempo = 0;
            int numer = 0;
            int denom = 0;
            foreach (List<MidiEvent> list in events) {
            foreach (MidiEvent mevent in list) {
                if (mevent.Metaevent == MetaEventTempo && tempo == 0) {
                    tempo = mevent.Tempo;
                }
                if (mevent.Metaevent == MetaEventTimeSignature && numer == 0) {
                    numer = mevent.Numerator;
                    denom = mevent.Denominator;
                }
            }
            }
            if (tempo == 0) {
            tempo = 500000; /* 500,000 microseconds = 0.05 sec */
            }
            if (numer == 0) {
            numer = 4; denom = 4;
            }
            timesig = new TimeSignature(numer, denom, quarternote, tempo);
        }
Beispiel #20
0
 /** Create a new MidiFile from the byte[]. */
 public MidiFile(byte[] data, string title)
 {
     MidiFileReader file = new MidiFileReader(data);
     if (title == null)
     title = "";
     parse(file, title);
 }
Beispiel #21
0
        private List<MidiTrack> tracks; /** The tracks of the midifile that have notes */

        #endregion Fields

        #region Constructors

        /** Create a new MidiFile from the file. */
        public MidiFile(string filename)
        {
            MidiFileReader file = new MidiFileReader(filename);
            parse(file, filename);
        }
Beispiel #22
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Playing all songs:");
                foreach (MethodInfo mi in typeof(Compositions).GetMethods())
                {
                    if (mi.GetParameters().Length == 0 && mi.ReturnType == typeof(Melody12Tone))
                    {
                        Console.Write(mi.Name + " ");
                        Main(new[] { mi.Name });
                        Console.WriteLine();
                        Console.WriteLine("Wait for 1 second...");
                        Thread.Sleep(1000);
                    }
                }
                Console.WriteLine();
                return;
            }

            if (args.Length == 2 && args[0] == "midi")
            {
                var composition = MidiFileReader.Read(args[1]);

                composition.PlayBack(
                    note =>
                {
                    midiOut.Send(MidiMessage.StartNote(note, 100, 1).RawData);
                    midiOut.Send(MidiMessage.StartNote(note + 4, 100, 1).RawData);
                },
                    note => midiOut.Send(MidiMessage.StopNote(note, 100, 1).RawData));

                return;
            }

            if (args[0] == "RandomSequencer")
            {
                RandomSequencer();
                return;
            }

            MethodInfo          miStatic      = typeof(Compositions).GetMethod(args[0]);
            Func <Melody12Tone> dgComposition = Delegate.CreateDelegate(typeof(Func <Melody12Tone>), miStatic) as Func <Melody12Tone>;
            Melody12Tone        m12tone       = dgComposition();

            List <int> lastnotes = new List <int>();

            foreach (var nwd in m12tone.Notes())
            {
                foreach (int note in lastnotes)
                {
                    midiOut.Send(MidiMessage.StopNote(note, 100, 1).RawData);
                }

                // Play the note, and if it's pause mute the last note
                if (!nwd.IsPause)
                {
                    Note note = nwd;
                    lastnotes = new List <int>();
                    do
                    {
                        midiOut.Send(MidiMessage.StartNote(note.note, 100, 1).RawData);
                        lastnotes.Add(note.note);
                        //note = note.otherNote;
                    } while (false /*note != null*/);
                }
                else
                {
                    foreach (var note in lastnotes)
                    {
                        midiOut.Send(MidiMessage.StartNote(note, 0, 1).RawData);
                    }
                }

                Fraction fract = nwd.Duration;
                Console.Write(fract + " ");
                Thread.Sleep(60 * 1000 * fract.p / fract.q / m12tone.tempo);
            }

            // Mute the last note(s)
            foreach (var note in lastnotes)
            {
                midiOut.Send(MidiMessage.StartNote(note, 0, 1).RawData);
            }
        }
Beispiel #23
0
    public void TestVarlen()
    {
        byte[] data = new byte[12];

        data[0] = 0x40;

        data[1] = 0x90;
        data[2] = 0x30;

        data[3] = 0x81;
        data[4] = 0xA5;
        data[5] = 0x10;

        data[6] = 0x81;
        data[7] = 0x84;
        data[8] = 0xBF;
        data[9] = 0x05;

        WriteTestFile(data);
        MidiFileReader reader = new MidiFileReader(testfile);

        int len = varlen(0, 0, 0, data[0]);
        Assert.AreEqual(reader.GetOffset(), 0);
        Assert.AreEqual(reader.ReadVarlen(), len);
        Assert.AreEqual(reader.GetOffset(), 1);

        len = varlen(0, 0, data[1], data[2]);
        Assert.AreEqual(reader.ReadVarlen(), len);
        Assert.AreEqual(reader.GetOffset(), 3);

        len = varlen(0, data[3], data[4], data[5]);
        Assert.AreEqual(reader.ReadVarlen(), len);
        Assert.AreEqual(reader.GetOffset(), 6);

        len = varlen(data[6], data[7], data[8], data[9]);
        Assert.AreEqual(reader.ReadVarlen(), len);
        Assert.AreEqual(reader.GetOffset(), 10);

        File.Delete(testfile);
    }
Beispiel #24
0
 public void TestSkip()
 {
     byte[] data = new byte[] { 65, 66, 67, 68, 69, 70, 71 };
     WriteTestFile(data);
     MidiFileReader reader = new MidiFileReader(testfile);
     Assert.AreEqual(reader.GetOffset(), 0);
     reader.Skip(3);
     Assert.AreEqual(reader.GetOffset(), 3);
     Assert.AreEqual(reader.ReadByte(), 68);
     reader.Skip(2);
     Assert.AreEqual(reader.GetOffset(), 6);
     Assert.AreEqual(reader.ReadByte(), 71);
     Assert.AreEqual(reader.GetOffset(), 7);
     File.Delete(testfile);
 }
Beispiel #25
0
 public void TestAscii()
 {
     byte[] data = new byte[] { 65, 66, 67, 68, 69, 70 };
     WriteTestFile(data);
     MidiFileReader reader = new MidiFileReader(testfile);
     Assert.AreEqual(reader.GetOffset(), 0);
     Assert.AreEqual(reader.ReadAscii(3), "ABC");
     Assert.AreEqual(reader.GetOffset(), 3);
     Assert.AreEqual(reader.ReadAscii(3), "DEF");
     Assert.AreEqual(reader.GetOffset(), 6);
     File.Delete(testfile);
 }
Beispiel #26
0
        /** Parse a single Midi track into a list of MidiEvents.
         * Entering this function, the file offset should be at the start of
         * the MTrk header.  Upon exiting, the file offset should be at the
         * start of the next MTrk header.
         */
        private List<MidiEvent> ReadTrack(MidiFileReader file)
        {
            List<MidiEvent> result = new List<MidiEvent>(20);
            int starttime = 0;
            string id = file.ReadAscii(4);

            if (id != "MTrk") {
            throw new MidiFileException("Bad MTrk header", file.GetOffset() - 4);
            }
            int tracklen = file.ReadInt();
            int trackend = tracklen + file.GetOffset();

            int eventflag = 0;

            while (file.GetOffset() < trackend) {

            // If the midi file is truncated here, we can still recover.
            // Just return what we've parsed so far.

            int startoffset, deltatime;
            byte peekevent;
            try {
                startoffset = file.GetOffset();
                deltatime = file.ReadVarlen();
                starttime += deltatime;
                peekevent = file.Peek();
            }
            catch (MidiFileException e) {
                return result;
            }

            MidiEvent mevent = new MidiEvent();
            result.Add(mevent);
            mevent.DeltaTime = deltatime;
            mevent.StartTime = starttime;

            if (peekevent >= EventNoteOff) {
                mevent.HasEventflag = true;
                eventflag = file.ReadByte();
            }

            // Console.WriteLine("offset {0}: event {1} {2} start {3} delta {4}",
            //                   startoffset, eventflag, EventName(eventflag),
            //                   starttime, mevent.DeltaTime);

            if (eventflag >= EventNoteOn && eventflag < EventNoteOn + 16) {
                mevent.EventFlag = EventNoteOn;
                mevent.Channel = (byte)(eventflag - EventNoteOn);
                mevent.Notenumber = file.ReadByte();
                mevent.Velocity = file.ReadByte();
            }
            else if (eventflag >= EventNoteOff && eventflag < EventNoteOff + 16) {
                mevent.EventFlag = EventNoteOff;
                mevent.Channel = (byte)(eventflag - EventNoteOff);
                mevent.Notenumber = file.ReadByte();
                mevent.Velocity = file.ReadByte();
            }
            else if (eventflag >= EventKeyPressure &&
                     eventflag < EventKeyPressure + 16) {
                mevent.EventFlag = EventKeyPressure;
                mevent.Channel = (byte)(eventflag - EventKeyPressure);
                mevent.Notenumber = file.ReadByte();
                mevent.KeyPressure = file.ReadByte();
            }
            else if (eventflag >= EventControlChange &&
                     eventflag < EventControlChange + 16) {
                mevent.EventFlag = EventControlChange;
                mevent.Channel = (byte)(eventflag - EventControlChange);
                mevent.ControlNum = file.ReadByte();
                mevent.ControlValue = file.ReadByte();
            }
            else if (eventflag >= EventProgramChange &&
                     eventflag < EventProgramChange + 16) {
                mevent.EventFlag = EventProgramChange;
                mevent.Channel = (byte)(eventflag - EventProgramChange);
                mevent.Instrument = file.ReadByte();
            }
            else if (eventflag >= EventChannelPressure &&
                     eventflag < EventChannelPressure + 16) {
                mevent.EventFlag = EventChannelPressure;
                mevent.Channel = (byte)(eventflag - EventChannelPressure);
                mevent.ChanPressure = file.ReadByte();
            }
            else if (eventflag >= EventPitchBend &&
                     eventflag < EventPitchBend + 16) {
                mevent.EventFlag = EventPitchBend;
                mevent.Channel = (byte)(eventflag - EventPitchBend);
                mevent.PitchBend = file.ReadShort();
            }
            else if (eventflag == SysexEvent1) {
                mevent.EventFlag = SysexEvent1;
                mevent.Metalength = file.ReadVarlen();
                mevent.Value = file.ReadBytes(mevent.Metalength);
            }
            else if (eventflag == SysexEvent2) {
                mevent.EventFlag = SysexEvent2;
                mevent.Metalength = file.ReadVarlen();
                mevent.Value = file.ReadBytes(mevent.Metalength);
            }
            else if (eventflag == MetaEvent) {
                mevent.EventFlag = MetaEvent;
                mevent.Metaevent = file.ReadByte();
                mevent.Metalength = file.ReadVarlen();
                mevent.Value = file.ReadBytes(mevent.Metalength);
                if (mevent.Metaevent == MetaEventTimeSignature) {
                    if (mevent.Metalength < 2) {
                        // throw new MidiFileException(
                        //  "Meta Event Time Signature len == " + mevent.Metalength  +
                        //  " != 4", file.GetOffset());
                        mevent.Numerator = (byte)0;
                        mevent.Denominator = (byte)4;
                    }
                    else if (mevent.Metalength >= 2 && mevent.Metalength < 4) {
                        mevent.Numerator = (byte)mevent.Value[0];
                        mevent.Denominator = (byte)System.Math.Pow(2, mevent.Value[1]);
                    }
                    else {
                        mevent.Numerator = (byte)mevent.Value[0];
                        mevent.Denominator = (byte)System.Math.Pow(2, mevent.Value[1]);
                    }
                }
                else if (mevent.Metaevent == MetaEventTempo) {
                    if (mevent.Metalength != 3) {
                        throw new MidiFileException(
                          "Meta Event Tempo len == " + mevent.Metalength +
                          " != 3", file.GetOffset());
                    }
                    mevent.Tempo = ( (mevent.Value[0] << 16) | (mevent.Value[1] << 8) | mevent.Value[2]);
                }
                else if (mevent.Metaevent == MetaEventEndOfTrack) {
                    /* break;  */
                }
            }
            else {
                throw new MidiFileException("Unknown event " + mevent.EventFlag,
                                             file.GetOffset()-1);
            }
            }

            return result;
        }
Beispiel #27
0
    public void TestInt()
    {
        int[] nums = new int[] { 200, 10000, 80000, 999888777 };
        byte[] data = new byte[nums.Length * 4];
        int index = 0;
        for (int i = 0; i < nums.Length; i++) {
            data[index]   = (byte)( (nums[i] >> 24) & 0xFF );
            data[index+1] = (byte)( (nums[i] >> 16) & 0xFF );
            data[index+2] = (byte)( (nums[i] >> 8) & 0xFF );
            data[index+3] = (byte)(  nums[i] & 0xFF );
            index += 4;
        }
        WriteTestFile(data);
        MidiFileReader reader = new MidiFileReader(testfile);

        int offset = 0;
        foreach (int x in nums) {
            Assert.AreEqual(reader.GetOffset(), offset);
            Assert.AreEqual(reader.ReadInt(), x);
            offset += 4;
        }
        File.Delete(testfile);
    }