Ejemplo n.º 1
0
        public void Export(string path)
        {
            MidiEventCollection mid = new MidiEventCollection(1, DELTA_TICKS_PER_QUARTER);

            mid.AddTrack(CreateTempoTrack());
            mid.AddTrack(CreateTrack());

            MidiFile.Export(path, mid);
        }
Ejemplo n.º 2
0
        private void ExportAtMarker(MidiFile midiFile, string markerName, string midiFilename, long startAbsoluteTime, long endAbsoluteTime)
        {
            string exportFileName = CreateFileName(markerName, midiFilename);
            LogInformation("Exporting Marker {0} to {1}", markerName, exportFileName);

            // 1. Construct a list of meta-events for track zero
            List<MidiEvent> trackZeroEvents = new List<MidiEvent>();
            trackZeroEvents.Add(new TextEvent(markerName, MetaEventType.SequenceTrackName, startAbsoluteTime));
            CreateTrackZeroEvents(trackZeroEvents, midiFile, startAbsoluteTime, endAbsoluteTime, settings.MidiFileType == 0);
            MidiEventCollection exportEvents = new MidiEventCollection(settings.MidiFileType, midiFile.DeltaTicksPerQuarterNote);
            exportEvents.AddTrack(trackZeroEvents);
            
            if (settings.MidiFileType == 1)
            {
                if (midiFile.Tracks == 1)
                {
                    // this is a special case - we got a type 0 or a strange type 1 with just 1 track
                    // turn it into a type 1 with notes on the second track
                    List<MidiEvent> trackOneEvents = new List<MidiEvent>();
                    trackOneEvents.Add(new TextEvent(markerName, MetaEventType.SequenceTrackName, startAbsoluteTime));
                    CreateTrackEvents(trackOneEvents, midiFile.Events[0], startAbsoluteTime, endAbsoluteTime, false);
                    exportEvents.AddTrack(trackOneEvents);
                }

                for (int track = 1; track < midiFile.Tracks; track++)
                {
                    List<MidiEvent> trackEvents = new List<MidiEvent>();
                    trackEvents.Add(new TextEvent(markerName, MetaEventType.SequenceTrackName, startAbsoluteTime));
                    CreateTrackEvents(trackEvents, midiFile.Events[track], startAbsoluteTime, endAbsoluteTime, true);
                    exportEvents.AddTrack(trackEvents);
                }
            }
                        
            bool gotNotes = false;
            foreach(IList<MidiEvent> trackEvents in exportEvents)
            {            
                foreach(MidiEvent trackEvent in trackEvents)
                {
                    if (trackEvent.CommandCode == MidiCommandCode.NoteOn)
                    {
                        gotNotes = true;
                        break;
                    }
                }
            }

            if (!gotNotes)
            {
                LogInformation("No note events found for this marker {0}", markerName);
                return;
            }

            exportEvents.StartAbsoluteTime = startAbsoluteTime; 
            MidiFile.Export(exportFileName, exportEvents);
        }
Ejemplo n.º 3
0
        public void ExportMIDI(string fn, CSEQ seq)
        {
            string cr = Path.GetFileNameWithoutExtension(fn) + "\r\n\r\n" + Properties.Resources.midi_copyright;

            MidiEventCollection mc = new MidiEventCollection(1, TPQN);

            //this is a lazy fix for guitarpro5 bug, 1st track does not import there
            List <MidiEvent> dummy = new List <MidiEvent>();

            dummy.Add(new TextEvent(Path.GetFileNameWithoutExtension(fn), MetaEventType.SequenceTrackName, 0));
            dummy.Add(new TextEvent(cr, MetaEventType.Copyright, 0));
            dummy.Add(new TempoEvent(MPQN, 0));

            mc.AddTrack(dummy);

            int availablechannel = 1;

            for (int i = 0; i < tracks.Count; i++)
            {
                mc.AddTrack(tracks[i].ToMidiEventList(MPQN, tracks[i].isDrumTrack ? 10 : availablechannel, seq));

                if (!tracks[i].isDrumTrack)
                {
                    availablechannel++;

                    //skip drum track
                    if (availablechannel == 10)
                    {
                        availablechannel++;
                    }

                    //limit channel if overflow
                    if (availablechannel > 16)
                    {
                        availablechannel = 16;
                    }
                }
            }

            mc.PrepareForExport();


            try
            {
                MidiFile.Export(fn, mc);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
        }
        public void TestAddNamedTrack()
        {
            var          manualMidi     = new MidiEventCollection(1, 200);
            var          noteEvent      = new NoteOnEvent(0, 1, 1, 1, 1);
            const string trackName      = "name";
            var          trackNameEvent = new TextEvent(trackName, MetaEventType.SequenceTrackName, 0);
            var          endTrackEvent  = new MetaEvent(MetaEventType.EndTrack, 0, noteEvent.OffEvent.AbsoluteTime);

            var track = manualMidi.AddTrack();

            track.Add(trackNameEvent);
            track.Add(noteEvent);
            track.Add(noteEvent.OffEvent);
            track.Add(endTrackEvent);

            var extensionMidi = new MidiEventCollection(1, 200);
            var events        = new MidiEvent[] { noteEvent, noteEvent.OffEvent };

            extensionMidi.AddNamedTrack(trackName, events);

            MidiAssert.Equal(manualMidi, extensionMidi);

            // Assert events (not name / end) are the same objects
            var manualTrack    = manualMidi[0];
            var extensionTrack = extensionMidi[0];

            for (var e = 1; e < manualTrack.Count - 1; e++)
            {
                Assert.That(extensionTrack[e], Is.SameAs(manualTrack[e]));
            }
        }
        public void TestAddTrackCopyParams()
        {
            var manualMidi = new MidiEventCollection(1, 200);
            var noteEvent  = new NoteOnEvent(0, 1, 1, 1, 1);

            var track = manualMidi.AddTrack();

            track.Add(noteEvent);
            track.Add(noteEvent.OffEvent);

            var extensionMidi = new MidiEventCollection(1, 200);

            extensionMidi.AddTrackCopy(noteEvent, noteEvent.OffEvent);

            MidiAssert.Equal(manualMidi, extensionMidi);

            // Assert they aren't the same objects
            var manualTrack    = manualMidi[0];
            var extensionTrack = extensionMidi[0];

            for (var e = 0; e < manualTrack.Count; e++)
            {
                Assert.That(extensionTrack[e], Is.Not.SameAs(manualTrack[e]));
            }

            // Verify the NoteOnEvent.OffEvent link
            Assert.AreEqual(extensionMidi[0][1], ((NoteOnEvent)extensionMidi[0][0]).OffEvent);
        }
        public void TestAddNamedTrackCopyWithOwnEnd()
        {
            var          manualMidi     = new MidiEventCollection(1, 200);
            var          noteEvent      = new NoteOnEvent(0, 1, 1, 1, 1);
            const string trackName      = "name";
            var          trackNameEvent = new TextEvent(trackName, MetaEventType.SequenceTrackName, 0);
            var          endTrackEvent  = new MetaEvent(MetaEventType.EndTrack, 0, 90);

            var track = manualMidi.AddTrack();

            track.Add(trackNameEvent);
            track.Add(noteEvent);
            track.Add(noteEvent.OffEvent);
            track.Add(endTrackEvent);

            var extensionMidi = new MidiEventCollection(1, 200);
            var events        = new MidiEvent[] { noteEvent, noteEvent.OffEvent, endTrackEvent };

            extensionMidi.AddNamedTrackCopy(trackName, events);

            MidiAssert.Equal(manualMidi, extensionMidi);

            // Assert they aren't the same objects
            var manualTrack    = manualMidi[0];
            var extensionTrack = extensionMidi[0];

            for (var e = 0; e < manualTrack.Count; e++)
            {
                Assert.That(extensionTrack[e], Is.Not.SameAs(manualTrack[e]));
            }

            // Verify the NoteOnEvent.OffEvent link
            Assert.AreEqual(extensionMidi[0][2], ((NoteOnEvent)extensionMidi[0][1]).OffEvent);
        }
Ejemplo n.º 7
0
        private static void MakeSilent(string midifile)
        {
            var mf = new MidiFile(midifile, false);

            MidiEventCollection collection = new MidiEventCollection(mf.FileFormat, mf.DeltaTicksPerQuarterNote);

            for (int n = 0; n < mf.Tracks; n++)
            {
                collection.AddTrack();
                foreach (var midiEvent in mf.Events[n])
                {
                    if (midiEvent.CommandCode == MidiCommandCode.NoteOn)
                    {
                        var ne = (NoteEvent)midiEvent;
                        ne.Velocity = 1;
                        collection.AddEvent((MidiEvent)ne, n);
                    }
                    else
                    {
                        collection.AddEvent(midiEvent, n);
                    }
                }
            }

            MidiFile.Export(output_dir + "\\" + midifile, collection);

            Console.WriteLine("Created " + output_dir + "\\" + midifile);
        }
Ejemplo n.º 8
0
        public static MidiEventCollection ReorderTracks(MidiEventCollection midi)
        {
            var newMidi       = new MidiEventCollection(midi.MidiFileType, midi.DeltaTicksPerQuarterNote);
            var tempoMapIndex = midi.FindTrackNumberByName(TrackName.TempoMap.ToString());

            newMidi.AddTrack(midi[tempoMapIndex]);

            for (var t = 0; t < midi.Tracks; t++)
            {
                if (t != tempoMapIndex)
                {
                    newMidi.AddTrack(midi[t]);
                }
            }

            return(newMidi);
        }
Ejemplo n.º 9
0
        public bool ConvertFile(string sourceFile, string destFile, int fileType)
        {
            MidiFile midiFile = new MidiFile(sourceFile, false);

            if (fileType == -1)
            {
                fileType = midiFile.FileFormat;
            }
            EventRuleArgs eventRuleArgs = new EventRuleArgs(Path.GetFileNameWithoutExtension(sourceFile));

            MidiEventCollection outputFileEvents = new MidiEventCollection(fileType, midiFile.DeltaTicksPerQuarterNote);
            bool hasNotes = false;

            for (int track = 0; track < midiFile.Tracks; track++)
            {
                IList <MidiEvent> trackEvents = midiFile.Events[track];
                IList <MidiEvent> outputEvents;
                if (fileType == 1 || track == 0)
                {
                    outputEvents = new List <MidiEvent>();
                }
                else
                {
                    outputEvents = outputFileEvents[0];
                }
                foreach (MidiEvent midiEvent in InsertEvents)
                {
                    outputEvents.Add(midiEvent);
                }
                foreach (MidiEvent midiEvent in trackEvents)
                {
                    if (Process(midiEvent, eventRuleArgs))
                    {
                        outputEvents.Add(midiEvent);
                        NoteOnEvent noteOnEvent = midiEvent as NoteOnEvent;
                        if (noteOnEvent != null)
                        {
                            System.Diagnostics.Debug.Assert(noteOnEvent.OffEvent != null);
                            hasNotes = true;
                            outputEvents.Add(noteOnEvent.OffEvent);
                        }
                    }
                }
                if (fileType == 1 || track == 0)
                {
                    outputFileEvents.AddTrack(outputEvents);
                }
            }
            if (hasNotes)
            {
                MidiFile.Export(destFile, outputFileEvents);
            }

            return(hasNotes);
        }
        public void TestClone()
        {
            var          manualMidi      = new MidiEventCollection(1, 200);
            var          noteEvent1      = new NoteOnEvent(0, 1, 1, 1, 1);
            const string trackName1      = "name";
            var          trackNameEvent1 = new TextEvent(trackName1, MetaEventType.SequenceTrackName, 0);
            var          endTrackEvent1  = new MetaEvent(MetaEventType.EndTrack, 0, noteEvent1.OffEvent.AbsoluteTime);

            var track1 = manualMidi.AddTrack();

            track1.Add(trackNameEvent1);
            track1.Add(noteEvent1);
            track1.Add(noteEvent1.OffEvent);
            track1.Add(endTrackEvent1);

            var          noteEvent2      = new NoteOnEvent(0, 1, 1, 1, 1);
            const string trackName2      = "name";
            var          trackNameEvent2 = new TextEvent(trackName2, MetaEventType.SequenceTrackName, 0);
            var          endTrackEvent2  = new MetaEvent(MetaEventType.EndTrack, 0, noteEvent2.OffEvent.AbsoluteTime);

            var track2 = manualMidi.AddTrack();

            track2.Add(trackNameEvent2);
            track2.Add(noteEvent2);
            track2.Add(noteEvent2.OffEvent);
            track2.Add(endTrackEvent2);

            var clone = manualMidi.Clone();

            MidiAssert.Equal(manualMidi, clone);

            for (var t = 0; t < manualMidi.Tracks; t++)
            {
                var manualTrack    = manualMidi[t];
                var extensionTrack = clone[t];
                for (var e = 1; e < manualTrack.Count - 1; e++)
                {
                    Assert.That(extensionTrack[e], Is.Not.SameAs(manualTrack[e]));
                }
            }
        }
Ejemplo n.º 11
0
        protected void CreateDefaultMid(string midPath)
        {
            var mid = new MidiEventCollection(1, 480);

            // Create basic tempo track
            var tempoTrack = new List <MidiEvent>();

            tempoTrack.Add(new TextEvent("animTempo", MetaEventType.SequenceTrackName, 0));
            tempoTrack.Add(new MetaEvent(MetaEventType.EndTrack, 0, 0));
            mid.AddTrack(tempoTrack);

            // Add other tracks
            foreach (var trackName in DefaultMIDITracks)
            {
                var track = new List <MidiEvent>();
                track.Add(new TextEvent(trackName, MetaEventType.SequenceTrackName, 0));
                track.Add(new MetaEvent(MetaEventType.EndTrack, 0, 0));
                mid.AddTrack(track);
            }

            MidiFile.Export(midPath, mid);
            Console.WriteLine("Wrote \"venue.mid\"");
        }
        public static IList <MidiEvent> AddNamedTrack(this MidiEventCollection midiEventCollection, string name, IEnumerable <MidiEvent> initialEvents)
        {
            var nameEvent = new TextEvent(name, MetaEventType.SequenceTrackName, 0);
            var track     = midiEventCollection.AddTrack(nameEvent);

            foreach (var midiEvent in initialEvents)
            {
                track.Add(midiEvent);
            }

            var endEvent = track.OfType <MetaEvent>().Where(MidiEvent.IsEndTrack).SingleOrDefault();

            if (endEvent == null)
            {
                var lastEvent = track.OrderBy(e => e.AbsoluteTime).Last();
                track.Add(new MetaEvent(MetaEventType.EndTrack, 0, lastEvent.AbsoluteTime));
            }

            return(track);
        }
        public static IList <MidiEvent> AddTrackCopy(this MidiEventCollection midiEventCollection, IEnumerable <MidiEvent> initialEvents)
        {
            var initialEventsList = initialEvents.ToList();

            if (initialEventsList.GroupBy(e => e).Any(g => g.Count() > 1))
            {
                throw new ArgumentException("Must not contain duplicate events", nameof(initialEventsList));
            }

            var clonedEvents = new MidiEvent[initialEventsList.Count];

            for (var e = 0; e < initialEventsList.Count; e++)
            {
                var midiEvent = initialEventsList[e];
                var clone     = midiEvent.Clone();

                var noteEvent = midiEvent as NoteEvent;
                if (noteEvent != null)
                {
                    var noteOnEvent = noteEvent as NoteOnEvent;
                    // NoteOff events are set at the same time as their NoteOnEvent
                    if (noteOnEvent == null)
                    {
                        continue;
                    }

                    var clonedOff     = ((NoteOnEvent)clone).OffEvent;
                    var offEventIndex = initialEventsList.FindIndex(m => m == noteOnEvent.OffEvent);
                    if (offEventIndex != -1)
                    {
                        clonedEvents[offEventIndex] = clonedOff;
                    }
                }

                clonedEvents[e] = clone;
            }

            var newTrack = midiEventCollection.AddTrack(clonedEvents);

            return(newTrack);
        }
Ejemplo n.º 14
0
 private void toolStripButton2_Click(object sender, EventArgs e)
 {
     if (MessageBox.Show("Do you want to export all channels?", "Export", MessageBoxButtons.YesNo) == DialogResult.No)
     {
         MidiEventCollection events = new MidiEventCollection(1, 48);
         for (int index = 0; index < this.file.Data.Midi.Tracks; ++index)
         {
             if (this.checkedListBox1.GetItemChecked(index))
             {
                 events.AddTrack(this.file.Data.Midi[index]);
             }
         }
         if (this.saveFileDialog1.ShowDialog() != DialogResult.OK || this.saveFileDialog1.FileName.Length <= 0)
         {
             return;
         }
         MidiFile.Export(this.saveFileDialog1.FileName, events);
     }
     else if (this.saveFileDialog1.ShowDialog() == DialogResult.OK && this.saveFileDialog1.FileName.Length > 0)
     {
         MidiFile.Export(this.saveFileDialog1.FileName, this.file.Data.Midi);
     }
 }
Ejemplo n.º 15
0
        public void Export(string path)
        {
            MidiEventCollection mid = new MidiEventCollection(1, DELTA_TICKS_PER_QUARTER);

            _xmks.Sort((x, y) => GetSortNumber(x.Name) - GetSortNumber(y.Name));

            int GetSortNumber(string name)
            {
                switch (name)
                {
                case "touchdrums":
                    return(1);

                case "touchguitar":
                    return(2);

                case "guitar_3x2":
                    return(3);

                case "vocals":
                    return(4);

                case "control":
                    return(5);

                default:
                    return(100);
                }
            }

            // Get xmk track to use for tempo map + generating BEAT track
            // Note: Avoiding "touchdrums" because it was an under-developed feature so it may not consistently be as accurate compared to 6 fret
            var tempoTrackPreference = new[] { "guitar_3x2", "touchguitar", "vocals", "control" };
            Xmk firstXmk             = _xmks
                                       .Select(x =>
            {
                var idx = Array.FindIndex(tempoTrackPreference, y => y == x.Name);
                if (idx == -1)
                {
                    idx = 100;
                }

                return(Xmk: x, Order: idx);
            })
                                       .OrderBy(x => x.Order)
                                       .Select(x => x.Xmk)
                                       .First();

            mid.AddTrack(CreateTempoTrack(firstXmk.TempoEntries, firstXmk.TimeSignatureEntries));

            if (!_exportOptions.Remap)
            {
                for (int i = 0; i < _xmks.Count; i++)
                {
                    mid.AddTrack(CreateTrack(_xmks[i], i));
                }
            }
            else
            {
                var eventsIdx = -1;
                for (int i = 0; i < _xmks.Count; i++)
                {
                    Xmk    xmk       = _xmks[i];
                    string trackName = !string.IsNullOrEmpty(xmk.Name) ? xmk.Name : $"NOTES {i}";

                    // Sets remapping and track name
                    switch (trackName.ToLower())
                    {
                    case "control":
                        // EVENTS
                        mid.AddTrack(ParseEvents(xmk));
                        eventsIdx = i + 1;
                        continue;

                    case "guitar_3x2":
                        // PART GUITAR GHL
                        mid.AddTrack(ParseGuitar3(xmk));
                        continue;

                    case "touchdrums":
                        // PART DRUMS
                        mid.AddTrack(ParseDrums(xmk));
                        continue;

                    case "touchguitar":
                        // PART GUITAR
                        mid.AddTrack(ParseGuitar5(xmk));
                        continue;

                    case "vocals":
                        // PART VOCALS
                        mid.AddTrack(ParseVocals(xmk));
                        continue;
                    }

                    // TODO: Refactor to be more elegant
                    if (_voxRegex.IsMatch(trackName))
                    {
                        mid.AddTrack(ParseVocals(xmk));
                        continue;
                    }

                    mid.AddTrack(CreateTrack(xmk, i));
                }

                // Updates EVENTS track
                var firstPlay = mid.SelectMany(x => x)
                                .Where(y => y is TextEvent && ((TextEvent)y).Text == "[play]")
                                .OrderBy(z => z.AbsoluteTime)
                                .FirstOrDefault();

                var lastIdle = mid.SelectMany(x => x)
                               .Where(y => y is TextEvent && ((TextEvent)y).Text == "[idle]")
                               .OrderByDescending(z => z.AbsoluteTime)
                               .FirstOrDefault();

                if (eventsIdx != -1 && firstPlay != null)
                {
                    var events    = mid[eventsIdx];
                    var nextEvent = events
                                    .OrderBy(y => y.AbsoluteTime)
                                    .FirstOrDefault(z => z.AbsoluteTime > firstPlay.AbsoluteTime);

                    // If nextEvent is null, assume no text events exist
                    var nextEventIdx = (nextEvent is null)
                        ? 1
                        : events.IndexOf(nextEvent);

                    events.Insert(nextEventIdx, new TextEvent("[music_start]", MetaEventType.TextEvent, firstPlay.AbsoluteTime));
                }

                if (eventsIdx != -1 && lastIdle != null)
                {
                    var events   = mid[eventsIdx];
                    var trackEnd = events.Last();
                    trackEnd.AbsoluteTime = lastIdle.AbsoluteTime; // Updates end track position
                    events.Remove(trackEnd);

                    events.Add(new TextEvent("[music_end]", MetaEventType.TextEvent, lastIdle.AbsoluteTime));
                    events.Add(new TextEvent("[end]", MetaEventType.TextEvent, lastIdle.AbsoluteTime));
                    events.Add(trackEnd); // Adds end track back
                }

                // Generates up/down events for BEAT track (Needed for beat markers in CH and OD in RB)
                mid.AddTrack(GenerateBeatTrack(firstXmk.TimeSignatureEntries, mid));
            }

            MidiFile.Export(path, mid);
        }
        public MidiEventCollection process(int timeSigNum, int timeSigDen, int octaveEst, int avgVel, int bars)
        {
            MidiEventCollection m = melody;


            int noteCount = getNumberOfNotes();
            int noteIndex = 0;

            int initialTrackCount = m.Tracks;

            m.AddTrack();
            int newTrack = m.Tracks - 1;

            bool bFirst = true;

            Vector3D noHint = new Vector3D(0, 0, 0);

            m[newTrack].Add(new PatchChangeEvent(0, 2, 1));

            // Loop through each track in the MidiEventCollection
            for (int track = 0; track < initialTrackCount; track++)
            {
                // For every MidiEvent in that track...
                foreach (MidiEvent e in m[track])
                {
                    // This is where we can do some work.

                    // Check the CommandCode.
                    // Here, we are interested in NoteOn messages
                    if (e.CommandCode == MidiCommandCode.NoteOn)
                    {
                        if (e is NoteOnEvent)
                        {
                            NoteOnEvent non = (NoteOnEvent)e;
                            NoteEvent   n   = (NoteEvent)e;

                            if (non.OffEvent != null)
                            {
                                ++noteIndex;
                                // We want to harmonize this note!
                                Vector3D harmonization = new Vector3D(0, 0, 0);

                                if (!bFirst && noteIndex < noteCount - 1)
                                {
                                    harmonization = harmonizeNote(n.NoteNumber, mostRecentChord, noHint);
                                }
                                else
                                {
                                    if (noteIndex == noteCount - 1)
                                    {
                                        harmonization = harmonizeNote(n.NoteNumber, mostRecentChord,
                                                                      chordVectors[getCadenceForNote(n.NoteNumber % 12)]);
                                    }
                                    else if (noteIndex == noteCount)
                                    {
                                        harmonization = harmonizeNote(n.NoteNumber, mostRecentChord,
                                                                      chordVectors[0]);
                                    }
                                    else
                                    {
                                        bFirst        = false;
                                        harmonization = mostRecentChord;
                                    }
                                }

                                //        NoteEvent n1 = new NoteEvent(n.AbsoluteTime, 2, MidiCommandCode.NoteOn,
                                //                       (int) harmonization.X + 60, n.Velocity);
                                NoteOnEvent n1 = new NoteOnEvent(n.AbsoluteTime, 2,
                                                                 (int)harmonization.X + 60, n.Velocity, non.NoteLength);
                                //    NoteEvent n1off = new NoteEvent(non.NoteLength, 2, MidiCommandCode.NoteOff,
                                //                                   (int) harmonization.X + 60, n.Velocity);

                                //   NoteEvent n2 = new NoteEvent(n.AbsoluteTime, 2, MidiCommandCode.NoteOn,
                                //                             (int) harmonization.Y + 60, n.Velocity);

                                NoteOnEvent n2 = new NoteOnEvent(n.AbsoluteTime, 2,
                                                                 (int)harmonization.Y + 60, n.Velocity, non.NoteLength);

                                //   NoteEvent n2off = new NoteEvent(non.NoteLength, 2, MidiCommandCode.NoteOff,
                                //                                 (int) harmonization.Y + 60, n.Velocity);

                                //     NoteEvent n3 = new NoteEvent(n.AbsoluteTime, 2, MidiCommandCode.NoteOn,
                                //                                   (int) harmonization.Z + 60, n.Velocity);

                                NoteOnEvent n3 = new NoteOnEvent(n.AbsoluteTime, 2,
                                                                 (int)harmonization.Z + 60, n.Velocity, non.NoteLength);

                                //   NoteEvent n3off = new NoteEvent(non.NoteLength, 2, MidiCommandCode.NoteOff,
                                //                               (int) harmonization.Z + 60, n.Velocity);



                                m[newTrack].Add(n1); m[newTrack].Add(n1.OffEvent);
                                //       m[newTrack].Add(n1off);
                                m[newTrack].Add(n2); m[newTrack].Add(n2.OffEvent);
                                //       m[newTrack].Add(n2off);
                                m[newTrack].Add(n3); m[newTrack].Add(n3.OffEvent);
                                //     m[newTrack].Add(n3off);

                                mostRecentChord = harmonization;
                            }
                        }
                    }
                }
            }
            AppendEndMarker(m[0]);
            AppendEndMarker(m[1]);
            return(m);
        }
Ejemplo n.º 17
0
        public void WriteToMidi(string path)
        {
            MidiEventCollection events = new MidiEventCollection(1, 480);
            foreach(Track t in Tracks)
            {
                List<MidiEvent> trackEvents = new List<MidiEvent>();
                var info = t.GeneratePlaybackInfo();

                var keys = new int[info.Messages.Keys.Count];
                int i = 0;
                foreach (var k in info.Messages.Keys)
                {
                    keys[i++] = k;
                }

                for (i = 0; i < keys.Length - 1; i++)
                {
                    foreach (PlaybackMessage message in info.Messages[keys[i]])
                    {
                        try
                        {
                            var e = MidiEvent.FromRawMessage(message.GenerateMidiMessage().RawData);
                            int note_dur = (int)Note.ToNoteDuration(keys[i]);
                            int midi_dur = Note.ToMidiLength(note_dur, 240, 60);
                            e.AbsoluteTime = keys[i];
                            trackEvents.Add(e);
                        }
                        catch
                        {
                            // TODO figure out crash
                        }
                    }
                    int sleep_dur = keys[i + 1] - keys[i];
                    //Thread.Sleep(sleep_dur);
                }

                // Append the end marker to the track
                if(trackEvents[trackEvents.Count - 1].CommandCode == MidiCommandCode.NoteOn)
                {
                    var noteOn = trackEvents[trackEvents.Count - 1] as NoteOnEvent;
                    int note = noteOn.NoteNumber;
                    int duration = noteOn.NoteLength;
                    int channel = noteOn.Channel;
                    var offM = MidiMessage.StopNote(note, noteOn.Velocity, channel);
                    var offE = MidiEvent.FromRawMessage(offM.RawData);
                    offE.AbsoluteTime = noteOn.AbsoluteTime;
                    trackEvents.Add(offE);
                }

                long absoluteTime = 0;
                if (trackEvents.Count > 0)
                    absoluteTime = trackEvents[trackEvents.Count - 1].AbsoluteTime+100;
                trackEvents.Add(new MetaEvent(MetaEventType.EndTrack, 0, absoluteTime));

                events.AddTrack(trackEvents);
            }

            MidiFile.Export(path, events);
        }
Ejemplo n.º 18
0
        public void Export(string path, bool remap = false)
        {
            MidiEventCollection mid = new MidiEventCollection(1, DELTA_TICKS_PER_QUARTER);

            _xmks.Sort((x, y) => GetSortNumber(x.Name) - GetSortNumber(y.Name));

            int GetSortNumber(string name)
            {
                switch (name)
                {
                case "touchdrums":
                    return(1);

                case "touchguitar":
                    return(2);

                case "guitar_3x2":
                    return(3);

                case "vocals":
                    return(4);

                case "control":
                    return(5);

                default:
                    return(100);
                }
            }

            Xmk firstXmk = _xmks.FirstOrDefault();

            mid.AddTrack(CreateTempoTrack(firstXmk.TempoEntries, firstXmk.TimeSignatureEntries));

            if (!remap)
            {
                for (int i = 0; i < _xmks.Count; i++)
                {
                    mid.AddTrack(CreateTrack(_xmks[i], i));
                }
            }
            else
            {
                var eventsIdx = -1;
                for (int i = 0; i < _xmks.Count; i++)
                {
                    Xmk    xmk       = _xmks[i];
                    string trackName = !string.IsNullOrEmpty(xmk.Name) ? xmk.Name : $"NOTES {i}";

                    // Sets remapping and track name
                    switch (trackName.ToLower())
                    {
                    case "control":
                        // EVENTS
                        mid.AddTrack(ParseEvents(xmk));
                        eventsIdx = i + 1;
                        continue;

                    case "guitar_3x2":
                        // PART GUITAR GHL
                        mid.AddTrack(ParseGuitar3(xmk));
                        continue;

                    case "touchdrums":
                        // PART DRUMS
                        mid.AddTrack(ParseDrums(xmk));
                        continue;

                    case "touchguitar":
                        // PART GUITAR
                        mid.AddTrack(ParseGuitar6(xmk));
                        continue;

                    case "vocals":
                        // PART VOCALS
                        mid.AddTrack(ParseVocals(xmk));
                        continue;
                    }

                    mid.AddTrack(CreateTrack(xmk, i));
                }

                // Updates EVENTS track
                var firstPlay = mid.SelectMany(x => x)
                                .Where(y => y is TextEvent && ((TextEvent)y).Text == "[play]")
                                .OrderBy(z => z.AbsoluteTime)
                                .FirstOrDefault();

                var lastIdle = mid.SelectMany(x => x)
                               .Where(y => y is TextEvent && ((TextEvent)y).Text == "[idle]")
                               .OrderByDescending(z => z.AbsoluteTime)
                               .FirstOrDefault();

                if (eventsIdx != -1 && firstPlay != null)
                {
                    var events       = mid[eventsIdx];
                    var nextEvent    = events.OrderBy(x => x.AbsoluteTime).First(y => y.AbsoluteTime > firstPlay.AbsoluteTime);
                    var nextEventIdx = events.IndexOf(nextEvent);

                    events.Insert(nextEventIdx, new TextEvent("[music_start]", MetaEventType.TextEvent, firstPlay.AbsoluteTime));
                }

                if (eventsIdx != -1 && lastIdle != null)
                {
                    var events   = mid[eventsIdx];
                    var trackEnd = events.Last();
                    trackEnd.AbsoluteTime = lastIdle.AbsoluteTime; // Updates end track position
                    events.Remove(trackEnd);

                    events.Add(new TextEvent("[music_end]", MetaEventType.TextEvent, lastIdle.AbsoluteTime));
                    events.Add(new TextEvent("[end]", MetaEventType.TextEvent, lastIdle.AbsoluteTime));
                    events.Add(trackEnd); // Adds end track back
                }

                // Generates up/down events for BEAT track (Needed for beat markers in CH and OD in RB)
                mid.AddTrack(GenerateBeatTrack(firstXmk.TimeSignatureEntries, mid));
            }

            MidiFile.Export(path, mid);
        }
Ejemplo n.º 19
0
        public bool ConvertFile(string sourceFile, int fileType, int TrackNum, ICollection<MidiNotes> NoteCollection)
        {
            try
            {
                //MidiFile midiFile = new MidiFile(sourceFile);
                MidiFile midiFile = new MidiFile(sourceFile);
                if (fileType == -1)
                {
                    fileType = midiFile.FileFormat;
                }
                EventRuleArgs eventRuleArgs = new EventRuleArgs(Path.GetFileNameWithoutExtension(sourceFile));

                MidiEventCollection outputFileEvents = new MidiEventCollection(fileType, midiFile.DeltaTicksPerQuarterNote);
                bool hasNotes = false;

                int track = TrackNum;

                ; IList<MidiEvent> trackEvents = midiFile.Events[track];  // Notes the use of the Track reference, if invalid track is referenced then causes big issues

                IList<MidiEvent> outputEvents;
                if (fileType == 1 || track == 0)
                {
                    outputEvents = new List<MidiEvent>();
                }
                else
                {
                    outputEvents = outputFileEvents[0];
                }
                foreach (MidiEvent midiEvent in InsertEvents)
                {
                    outputEvents.Add(midiEvent);
                }
                foreach (MidiEvent midiEvent in trackEvents)
                {

                    outputEvents.Add(midiEvent);
                    NoteOnEvent noteOnEvent = midiEvent as NoteOnEvent;
                    if (noteOnEvent != null)
                    {
                        // Add to the midi collection
                        if (!MidiEvent.IsNoteOff(noteOnEvent))
                        {
                            MidiNotes tempnote = new MidiNotes(noteOnEvent);
                            NoteCollection.Add(tempnote);
                        };

                        //System.Diagnostics.Debug.Assert(noteOnEvent.OffEvent != null);
                        hasNotes = true;
                        outputEvents.Add(noteOnEvent.OffEvent);
                    }
                    //}
                }

                // Get the tempo events
                foreach (MidiEvent midiEvent in trackEvents)
                {
                    //get the tempo and drop out of that track
                    if (midiEvent is TempoEvent)
                    {
                        //tempo in milliseconds
                        tempo = (midiEvent as TempoEvent).MicrosecondsPerQuarterNote / 1000;
                        break;
                    }

                    //get the tempo and drop out of that track
                    if (midiEvent is TimeSignatureEvent)
                    {
                        //Time sig
                        timesig1 = (midiEvent as TimeSignatureEvent).Numerator;
                        timesig2 = (midiEvent as TimeSignatureEvent).Denominator;
                        break;
                    }

                }

                if (fileType == 1 || track == 0)
                {
                    outputFileEvents.AddTrack(outputEvents);
                }
                //}
                if (hasNotes)
                {
                    //MidiFile.Export(destFile, outputFileEvents);
                }

                return hasNotes;
            }
            catch
            {
                MessageBox.Show("Invalid File or track number");
                return false;
            }
        }
 public static IList <MidiEvent> AddTrack(this MidiEventCollection midiEventCollection, params MidiEvent[] events)
 {
     return(midiEventCollection.AddTrack(events));
 }
Ejemplo n.º 21
0
        public void ExportMidi(string exportMidPath)
        {
            // Create directory if it doesn't exist
            var dirPath = Path.GetDirectoryName(exportMidPath);

            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }

            // Create dictionary of tracks to filter events in
            var midFilteredTracks = TBRBCharacters
                                    .Select(x => x.ToUpper())
                                    .Concat(new[] { "VENUE" })
                                    .ToDictionary(x => x, y => new List <MidiEvent>());

            var nameFilterRegex = new Regex($"(?i)([_]?)({string.Join("|", TBRBCharacters)})$");

            foreach (var group in Anim.DirectorGroups)
            {
                // Default event name + track
                var eventName = group.PropName;
                var track     = midFilteredTracks["VENUE"];

                var match = nameFilterRegex.Match(group.PropName);
                if (match.Success)
                {
                    // Get last group match (ex: "_ringo" -> "ringo" and "spot_paul" -> "paul")
                    var key = match
                              .Groups
                              .Values
                              .Last()
                              .Value
                              .ToUpper();

                    // Look for character track
                    if (midFilteredTracks.ContainsKey(key))
                    {
                        // Remove appended name + assign character track
                        eventName = nameFilterRegex.Replace(eventName, "");
                        track     = midFilteredTracks[key];
                    }
                }

                foreach (var ev in group.Events.OrderBy(x => x.Position))
                {
                    var tickPos = MidiHelper.FramePosToTicks((decimal)ev.Position);

                    var evValue = ev switch
                    {
                        DirectedEventFloat evFloat => $"{evFloat.Value}",
                        DirectedEventTextFloat {
                            Value : 0.0f
                        } evTextFloat => $"{evTextFloat.Text}",                                      // postproc events
                        DirectedEventTextFloat evTextFloat => $"{evTextFloat.Text} {evTextFloat.Value}",
                        DirectedEventBoolean evBool => $"{(evBool.Enabled ? "TRUE" : "FALSE")}",
                        DirectedEventVector4 evVector4 => $"{evVector4.Value.X} {evVector4.Value.Y} {evVector4.Value.Z} {evVector4.Value.W}",
                        DirectedEventVector3 evVector3 => $"{evVector3.Value.X} {evVector3.Value.Y} {evVector3.Value.Z}",
                        DirectedEventText evTextFloat => $"{evTextFloat.Text}",
                        _ => throw new NotSupportedException()
                    };

                    var evText = eventName switch
                    {
                        "body" => $"[{evValue}]",
                        "shot" => $"[{evValue}]",
                        "configuration" => $"[config ({evValue})]", // Use alias
                        "postproc" when evValue.EndsWith(".pp") && !evValue.Contains(' ') => $"[{evValue}]",
                        "lyric_transition" when evValue.EndsWith(".anim") && !evValue.StartsWith('(') => $"[{evValue}]",
                        _ => $"[{eventName} ({evValue})]",
                    };
                    track.Add(new TextEvent(evText, MetaEventType.TextEvent, tickPos));
                }
            }

            foreach (var key in midFilteredTracks.Keys)
            {
                if (midFilteredTracks[key].Count <= 0)
                {
                    // Remove empty track
                    midFilteredTracks.Remove(key);
                }
            }

            // Get tracks from mid
            var midiTracks = MidiHelper.CreateMidiTracksFromBase();

            foreach (var kv in midFilteredTracks)
            {
                var trackName = kv.Key;
                var track     = kv.Value;

                var existingTrack = midiTracks
                                    .FirstOrDefault(x =>
                                                    x.Any(y => (y is TextEvent te) &&
                                                          te.MetaEventType == MetaEventType.SequenceTrackName &&
                                                          te.Text == trackName));

                if ((existingTrack is null))
                {
                    // Sort events
                    track.Sort((x, y) => x.AbsoluteTime.CompareTo(y.AbsoluteTime));

                    // Create new track
                    // Insert track name and add end event
                    track.Insert(0, new TextEvent(trackName, MetaEventType.SequenceTrackName, 0));
                    track.Add(new MetaEvent(MetaEventType.EndTrack, 0, track.Max(x => x.AbsoluteTime)));

                    midiTracks.Add(track);
                    continue;
                }

                // Use existing track

                // Remove track name event
                var trackNameEvent = existingTrack
                                     .First(x => x is TextEvent me &&
                                            me.MetaEventType == MetaEventType.SequenceTrackName);

                existingTrack.Remove(trackNameEvent);

                // Remove end event if it exists (it probably should)
                var endEvent = existingTrack
                               .FirstOrDefault(x => x is MetaEvent me &&
                                               me.MetaEventType == MetaEventType.EndTrack);

                if (!(endEvent is null))
                {
                    existingTrack.Remove(endEvent);
                }

                existingTrack.AddRange(track);

                // Sort events
                existingTrack.Sort((x, y) => x.AbsoluteTime.CompareTo(y.AbsoluteTime));

                // Insert track name
                existingTrack.Insert(0, new TextEvent(trackName, MetaEventType.SequenceTrackName, 0));

                // Add end event
                existingTrack.Add(new MetaEvent(MetaEventType.EndTrack, 0, existingTrack.Max(x => x.AbsoluteTime)));
            }

            // Copy tracks to mid
            var mid = new MidiEventCollection(1, MidiHelper.GetTicksPerQuarter());

            midiTracks.ForEach(x => mid.AddTrack(x));

            MidiFile.Export(exportMidPath, mid);
        }
    }
Ejemplo n.º 22
0
        private void ConvertMidi(MidiFile midiFile, string target, string[] context)
        {
            string fileNameWithoutExtension = context[context.Length - 1];
            string name = null;
            long endTrackTime = -1;
            if (settings.UseFileName)
            {
                name = fileNameWithoutExtension;
            }
            if (settings.ApplyNamingRules)
            {
                if (ezdFileName.Match(fileNameWithoutExtension).Success)
                {
                    name = CreateEzdName(context);
                }
            }

            int outputFileType = midiFile.FileFormat;
            int outputTrackCount;
            if (settings.OutputMidiType == OutputMidiType.Type0)
            {
                outputFileType = 0;
            }
            else if (settings.OutputMidiType == OutputMidiType.Type1)
            {
                outputFileType = 1;
            }

            if (outputFileType == 0)
            {
                outputTrackCount = 1;
            }
            else
            {
                if (midiFile.FileFormat == 0)
                    outputTrackCount = 2;
                else
                    outputTrackCount = midiFile.Tracks;
            }


            MidiEventCollection events = new MidiEventCollection(outputFileType, midiFile.DeltaTicksPerQuarterNote);
            for (int track = 0; track < outputTrackCount; track++)
            {
                events.AddTrack();
            }
            if (name != null)
            {
                for (int track = 0; track < outputTrackCount; track++)
                {
                    events[track].Add(new TextEvent(name, MetaEventType.SequenceTrackName, 0));
                }
                if (settings.AddNameMarker)
                {
                    events[0].Add(new TextEvent(name, MetaEventType.Marker, 0));
                }
            }

            foreach (MidiEvent midiEvent in midiFile.Events[0])
            {
                if (settings.OutputChannelNumber != -1)
                    midiEvent.Channel = settings.OutputChannelNumber;
                MetaEvent metaEvent = midiEvent as MetaEvent;
                if (metaEvent != null)
                {
                    bool exclude = false;
                    switch (metaEvent.MetaEventType)
                    {
                        case MetaEventType.SequenceTrackName:
                            if (name != null)
                            {
                                exclude = true;
                            }
                            break;
                        case MetaEventType.SequencerSpecific:
                            exclude = settings.RemoveSequencerSpecific;
                            break;
                        case MetaEventType.EndTrack:
                            exclude = settings.RecreateEndTrackMarkers;
                            endTrackTime = metaEvent.AbsoluteTime;
                            break;
                        case MetaEventType.SetTempo:
                            if (metaEvent.AbsoluteTime != 0 && settings.RemoveExtraTempoEvents)
                            {
                                LogWarning("Removing a tempo event ({0}bpm) at {1} from {2}", ((TempoEvent)metaEvent).Tempo, metaEvent.AbsoluteTime, target);
                                exclude = true;
                            }
                            break;
                        case MetaEventType.TextEvent:
                            if (settings.TrimTextEvents)
                            {
                                TextEvent textEvent = (TextEvent)midiEvent;
                                textEvent.Text = textEvent.Text.Trim();
                                if (textEvent.Text.Length == 0)
                                {
                                    exclude = true;
                                }
                            }
                            break;
                        case MetaEventType.Marker:
                            if (settings.AddNameMarker && midiEvent.AbsoluteTime == 0)
                            {
                                exclude = true;
                            }
                            if (settings.RemoveExtraMarkers && midiEvent.AbsoluteTime > 0)
                            {
                                LogWarning("Removing a marker ({0}) at {1} from {2}", ((TextEvent)metaEvent).Text, metaEvent.AbsoluteTime, target);                                
                                exclude = true;
                            }
                            break;
                    }
                    if (!exclude)
                    {
                        events[0].Add(midiEvent);
                    }
                }
                else
                {
                    if (outputFileType == 1)
                        events[1].Add(midiEvent);
                    else
                        events[0].Add(midiEvent);
                }
            }

            // now do track 1 (Groove Monkee)                
            for (int inputTrack = 1; inputTrack < midiFile.Tracks; inputTrack++)
            {
                int outputTrack;
                if(outputFileType == 1)
                    outputTrack = inputTrack;
                else
                    outputTrack = 0;

                foreach (MidiEvent midiEvent in midiFile.Events[inputTrack])
                {                    
                    if (settings.OutputChannelNumber != -1)
                        midiEvent.Channel = settings.OutputChannelNumber;
                    bool exclude = false;                    
                    MetaEvent metaEvent = midiEvent as MetaEvent;
                    if (metaEvent != null)
                    {
                        switch (metaEvent.MetaEventType)
                        {
                            case MetaEventType.SequenceTrackName:
                                if (name != null)
                                {
                                    exclude = true;
                                }
                                break;
                            case MetaEventType.SequencerSpecific:
                                exclude = settings.RemoveSequencerSpecific;
                                break;
                            case MetaEventType.EndTrack:
                                exclude = settings.RecreateEndTrackMarkers;
                                break;
                        }
                    }
                    if (!exclude)
                    {
                        events[outputTrack].Add(midiEvent);
                    }
                }
                if(outputFileType == 1 && settings.RecreateEndTrackMarkers)
                {
                    AppendEndMarker(events[outputTrack]);
                }
            }

            if (settings.RecreateEndTrackMarkers)
            {
                if (outputFileType == 1)
                {
                    // if we are converting type 0 to type 1 and recreating end markers,
                    if (midiFile.FileFormat == 0)
                    {
                        AppendEndMarker(events[1]);
                    }
                }
                // make sure that track zero has an end track marker
                AppendEndMarker(events[0]);
            }
            else
            {
                // if we are converting type 0 to type 1 without recreating end markers,
                // then we still need to add an end marker to track 1
                if (midiFile.FileFormat == 0)
                {
                    // use the time we got from track 0 as the end track time for track 1
                    if (endTrackTime == -1)
                    {
                        LogError("Error adding track 1 end marker");
                        // make it a valid MIDI file anyway
                        AppendEndMarker(events[1]);
                    }
                    else
                    {
                        events[1].Add(new MetaEvent(MetaEventType.EndTrack, 0, endTrackTime));
                    }
                }
            }

            if (settings.VerboseOutput)
            {
                LogTrace("Processing {0}: {1}", name, target);
            }

            if (settings.RemoveEmptyTracks)
            {
                MidiEventCollection newList = new MidiEventCollection(events.MidiFileType, events.DeltaTicksPerQuarterNote);
                
                int removed = 0;
                for (int track = 0; track < events.Tracks; track++)
                {
                    IList<MidiEvent> trackEvents = events[track];
                    if (track < 2)
                    {
                        newList.AddTrack(events[track]);
                    }
                    else
                    {
                        if(HasNotes(trackEvents))
                        {
                            newList.AddTrack(trackEvents);
                        }
                        else
                        {
                            removed++;
                        }
                    }

                }
                if (removed > 0)
                {
                    events = newList;
                    LogWarning("Removed {0} empty tracks from {1} ({2} remain)", removed, target, events.Tracks);
                }
            }
            MidiFile.Export(target, events);
        }
Ejemplo n.º 23
0
        private void ConvertMidi(MidiFile midiFile, string target, string[] context)
        {
            string fileNameWithoutExtension = context[context.Length - 1];
            string name         = null;
            long   endTrackTime = -1;

            if (settings.UseFileName)
            {
                name = fileNameWithoutExtension;
            }
            if (settings.ApplyNamingRules)
            {
                if (ezdFileName.Match(fileNameWithoutExtension).Success)
                {
                    name = CreateEzdName(context);
                }
            }

            int outputFileType = midiFile.FileFormat;
            int outputTrackCount;

            if (settings.OutputMidiType == OutputMidiType.Type0)
            {
                outputFileType = 0;
            }
            else if (settings.OutputMidiType == OutputMidiType.Type1)
            {
                outputFileType = 1;
            }

            if (outputFileType == 0)
            {
                outputTrackCount = 1;
            }
            else
            {
                if (midiFile.FileFormat == 0)
                {
                    outputTrackCount = 2;
                }
                else
                {
                    outputTrackCount = Math.Max(midiFile.Tracks, 2); // at least two tracks because we'll move notes onto track 1 always
                }
            }


            MidiEventCollection events = new MidiEventCollection(outputFileType, midiFile.DeltaTicksPerQuarterNote);

            for (int track = 0; track < outputTrackCount; track++)
            {
                events.AddTrack();
            }
            if (name != null)
            {
                for (int track = 0; track < outputTrackCount; track++)
                {
                    events[track].Add(new TextEvent(name, MetaEventType.SequenceTrackName, 0));
                }
                if (settings.AddNameMarker)
                {
                    events[0].Add(new TextEvent(name, MetaEventType.Marker, 0));
                }
            }

            foreach (MidiEvent midiEvent in midiFile.Events[0])
            {
                if (settings.OutputChannelNumber != -1)
                {
                    midiEvent.Channel = settings.OutputChannelNumber;
                }
                MetaEvent metaEvent = midiEvent as MetaEvent;
                if (metaEvent != null)
                {
                    bool exclude = false;
                    switch (metaEvent.MetaEventType)
                    {
                    case MetaEventType.SequenceTrackName:
                        if (name != null)
                        {
                            exclude = true;
                        }
                        break;

                    case MetaEventType.SequencerSpecific:
                        exclude = settings.RemoveSequencerSpecific;
                        break;

                    case MetaEventType.EndTrack:
                        exclude      = settings.RecreateEndTrackMarkers;
                        endTrackTime = metaEvent.AbsoluteTime;
                        break;

                    case MetaEventType.SetTempo:
                        if (metaEvent.AbsoluteTime != 0 && settings.RemoveExtraTempoEvents)
                        {
                            LogWarning("Removing a tempo event ({0}bpm) at {1} from {2}", ((TempoEvent)metaEvent).Tempo, metaEvent.AbsoluteTime, target);
                            exclude = true;
                        }
                        break;

                    case MetaEventType.TextEvent:
                        if (settings.TrimTextEvents)
                        {
                            TextEvent textEvent = (TextEvent)midiEvent;
                            textEvent.Text = textEvent.Text.Trim();
                            if (textEvent.Text.Length == 0)
                            {
                                exclude = true;
                            }
                        }
                        break;

                    case MetaEventType.Marker:
                        if (settings.AddNameMarker && midiEvent.AbsoluteTime == 0)
                        {
                            exclude = true;
                        }
                        if (settings.RemoveExtraMarkers && midiEvent.AbsoluteTime > 0)
                        {
                            LogWarning("Removing a marker ({0}) at {1} from {2}", ((TextEvent)metaEvent).Text, metaEvent.AbsoluteTime, target);
                            exclude = true;
                        }
                        break;
                    }
                    if (!exclude)
                    {
                        events[0].Add(midiEvent);
                    }
                }
                else
                {
                    if (outputFileType == 1)
                    {
                        events[1].Add(midiEvent);
                    }
                    else
                    {
                        events[0].Add(midiEvent);
                    }
                }
            }

            // now do track 1 (Groove Monkee)
            for (int inputTrack = 1; inputTrack < midiFile.Tracks; inputTrack++)
            {
                int outputTrack;
                if (outputFileType == 1)
                {
                    outputTrack = inputTrack;
                }
                else
                {
                    outputTrack = 0;
                }

                foreach (MidiEvent midiEvent in midiFile.Events[inputTrack])
                {
                    if (settings.OutputChannelNumber != -1)
                    {
                        midiEvent.Channel = settings.OutputChannelNumber;
                    }
                    bool      exclude   = false;
                    MetaEvent metaEvent = midiEvent as MetaEvent;
                    if (metaEvent != null)
                    {
                        switch (metaEvent.MetaEventType)
                        {
                        case MetaEventType.SequenceTrackName:
                            if (name != null)
                            {
                                exclude = true;
                            }
                            break;

                        case MetaEventType.SequencerSpecific:
                            exclude = settings.RemoveSequencerSpecific;
                            break;

                        case MetaEventType.EndTrack:
                            exclude = settings.RecreateEndTrackMarkers;
                            break;
                        }
                    }
                    if (!exclude)
                    {
                        events[outputTrack].Add(midiEvent);
                    }
                }
                if (outputFileType == 1 && settings.RecreateEndTrackMarkers)
                {
                    AppendEndMarker(events[outputTrack]);
                }
            }

            if (settings.RecreateEndTrackMarkers)
            {
                if (outputFileType == 1)
                {
                    // make sure track 1 has an end track marker
                    AppendEndMarker(events[1]);
                }
                // make sure that track zero has an end track marker
                AppendEndMarker(events[0]);
            }
            else
            {
                // if we are converting type 0 to type 1 without recreating end markers,
                // then we still need to add an end marker to track 1
                if (midiFile.FileFormat == 0)
                {
                    // use the time we got from track 0 as the end track time for track 1
                    if (endTrackTime == -1)
                    {
                        LogError("Error adding track 1 end marker");
                        // make it a valid MIDI file anyway
                        AppendEndMarker(events[1]);
                    }
                    else
                    {
                        events[1].Add(new MetaEvent(MetaEventType.EndTrack, 0, endTrackTime));
                    }
                }
            }

            if (settings.VerboseOutput)
            {
                LogTrace("Processing {0}: {1}", name, target);
            }

            if (settings.RemoveEmptyTracks)
            {
                MidiEventCollection newList = new MidiEventCollection(events.MidiFileType, events.DeltaTicksPerQuarterNote);

                int removed = 0;
                for (int track = 0; track < events.Tracks; track++)
                {
                    IList <MidiEvent> trackEvents = events[track];
                    if (track < 2)
                    {
                        newList.AddTrack(events[track]);
                    }
                    else
                    {
                        if (HasNotes(trackEvents))
                        {
                            newList.AddTrack(trackEvents);
                        }
                        else
                        {
                            removed++;
                        }
                    }
                }
                if (removed > 0)
                {
                    events = newList;
                    LogWarning("Removed {0} empty tracks from {1} ({2} remain)", removed, target, events.Tracks);
                }
            }
            MidiFile.Export(target, events);
        }
Ejemplo n.º 24
0
        void LoadMidi(byte[] bytes)
        {
            var br = new BinaryReader(new MemoryStream(bytes));

               using (br)
               {
              string chunkHeader = Encoding.UTF8.GetString(br.ReadBytes(4));
              if (chunkHeader != "MThd")
              {
                 throw new FormatException("Not a MIDI file - header chunk missing");
              }
              uint chunkSize = SwapUInt32(br.ReadUInt32());

              if (chunkSize != 6)
              {
                 throw new FormatException("Unexpected header chunk length");
              }
              // 0 = single track, 1 = multi-track synchronous, 2 = multi-track asynchronous
              fileFormat = SwapUInt16(br.ReadUInt16());
              int tracks = SwapUInt16(br.ReadUInt16());
              deltaTicksPerQuarterNote = SwapUInt16(br.ReadUInt16());

              events = new MidiEventCollection((fileFormat == 0) ? 0 : 1, deltaTicksPerQuarterNote);
              for (int n = 0; n < tracks; n++)
              {
                 events.AddTrack();
              }

              long absoluteTime = 0;

              for (int track = 0; track < tracks; track++)
              {
                 if (fileFormat == 1)
                 {
                    absoluteTime = 0;
                 }
                 chunkHeader = Encoding.UTF8.GetString(br.ReadBytes(4));
                 if (chunkHeader != "MTrk")
                 {
                    throw new FormatException("Invalid chunk header");
                 }
                 chunkSize = SwapUInt32(br.ReadUInt32());

                 long startPos = br.BaseStream.Position;
                 MidiEvent me = null;
                 var outstandingNoteOns = new List<NoteOnEvent>();
                 while (br.BaseStream.Position < startPos + chunkSize)
                 {
                    me = MidiEvent.ReadNextEvent(br, me);
                    absoluteTime += me.DeltaTime;
                    me.AbsoluteTime = absoluteTime;
                    events[track].Add(me);
                    if (me.CommandCode == MidiCommandCode.NoteOn)
                    {
                       NoteEvent ne = (NoteEvent)me;
                       if (ne.Velocity > 0)
                       {
                          outstandingNoteOns.Add((NoteOnEvent)ne);
                       }
                       else
                       {
                          // don't remove the note offs, even though
                          // they are annoying
                          // events[track].Remove(me);
                          FindNoteOn(ne, outstandingNoteOns);
                       }
                    }
                    else if (me.CommandCode == MidiCommandCode.NoteOff)
                    {
                       FindNoteOn((NoteEvent)me, outstandingNoteOns);
                    }
                    else if (me.CommandCode == MidiCommandCode.MetaEvent)
                    {
                       MetaEvent metaEvent = (MetaEvent)me;
                       if (metaEvent.MetaEventType == MetaEventType.EndTrack)
                       {
                          //break;
                          // some dodgy MIDI files have an event after end track
                          if (strictChecking)
                          {
                             if (br.BaseStream.Position < startPos + chunkSize)
                             {
                                throw new FormatException(String.Format("End Track event was not the last MIDI event on track {0}", track));
                             }
                          }
                       }
                    }
                 }
                 if (outstandingNoteOns.Count > 0)
                 {
                    if (strictChecking)
                    {
                       throw new FormatException(String.Format("Note ons without note offs {0} (file format {1})", outstandingNoteOns.Count, fileFormat));
                    }
                 }
                 if (br.BaseStream.Position != startPos + chunkSize)
                 {
                    throw new FormatException(String.Format("Read too far {0}+{1}!={2}", chunkSize, startPos, br.BaseStream.Position));
                 }
              }
               }
        }
Ejemplo n.º 25
0
        public void Export(string path)
        {
            MidiEventCollection mid = new MidiEventCollection(1, DELTA_TICKS_PER_QUARTER);

            Song song        = _objects.First(x => x is Song) as Song;
            var  instruments = song.InstrumentPaths.Select(x => _objects.First(y => y.FilePath == x) as Instrument).ToList();

            List <ZObject> GetInstrumentTracks(string type, string difficulty)
            {
                var insTracks = instruments.FirstOrDefault(x => x.InstrumentType == type && x.Difficulty == difficulty);

                if (insTracks == null)
                {
                    return(new List <ZObject>());
                }

                return(insTracks.TrackPaths.Select(x => _objects.First(y => y.FilePath == x)).ToList());
            }

            var master  = GetInstrumentTracks("master", "");
            var tempo   = master.First(x => x is Tempo) as Tempo;
            var ts      = master.First(x => x is TimeSignature) as TimeSignature;
            var ev      = master.First(x => x is Event) as Event;
            var section = master.First(x => x is Section) as Section;

            // Tempo track
            mid.AddTrack(CreateTempoTrack(tempo, ts));

            // Bass tracks
            var track = CreateTabTrack(GetInstrumentTracks("bass", "jam"), "PART BASS_E");

            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }
            track = CreateTabTrack(GetInstrumentTracks("bass", "nov"), "PART BASS_M");
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }
            track = CreateTabTrack(GetInstrumentTracks("bass", "beg"), "PART BASS_H");
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }
            track = CreateTabTrack(GetInstrumentTracks("bass", "int"), "PART BASS_X");
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }
            track = CreateTabTrack(GetInstrumentTracks("bass", "adv"), "PART BASS_R");
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }

            // Guitar tracks
            track = CreateTabTrack(GetInstrumentTracks("guitar", "jam"), "PART GUITAR_E");
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }
            track = CreateTabTrack(GetInstrumentTracks("guitar", "nov"), "PART GUITAR_M");
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }
            track = CreateTabTrack(GetInstrumentTracks("guitar", "beg"), "PART GUITAR_H");
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }
            track = CreateTabTrack(GetInstrumentTracks("guitar", "int"), "PART GUITAR_X");
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }
            track = CreateTabTrack(GetInstrumentTracks("guitar", "adv"), "PART GUITAR_R");
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }
            track = CreateTabTrack(GetInstrumentTracks("guitar", "rhy"), "PART GUITAR_R_RHYTHM");
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }

            // Vox track
            track = CreateVoxTrack(GetInstrumentTracks("vocals", ""));
            if (track.Count > 2)
            {
                mid.AddTrack(track);
            }

            // Events track
            mid.AddTrack(CreateEventsTrack(ev, section));

            // Beat track
            var measure = master.First(x => x is Measure) as Measure;

            track = CreateBeatTrack(measure);
            mid.AddTrack(track);

            MidiFile.Export(path, mid);
        }