Esempio n. 1
0
        public void Write_DeleteDefaultTimeSignature()
        {
            var nonDefaultTimeSignatureEvent = new TimeSignatureEvent(2, 16);

            var midiFile = new MidiFile(
                new TrackChunk(
                    new NoteOnEvent((SevenBitNumber)100, (SevenBitNumber)50),
                    new NoteOffEvent((SevenBitNumber)100, (SevenBitNumber)50),
                    new UnknownMetaEvent(254),
                    new TimeSignatureEvent(),
                    nonDefaultTimeSignatureEvent));

            Write(
                midiFile,
                settings => settings.DeleteDefaultTimeSignature = true,
                (fileInfo1, fileInfo2) =>
            {
                var originalMidiFile = MidiFile.Read(fileInfo1.FullName);
                Assert.AreEqual(
                    2,
                    originalMidiFile.GetTrackChunks().SelectMany(c => c.Events).OfType <TimeSignatureEvent>().Count(),
                    "Invalid count of Time Signature events in original file.");

                var newMidiFile         = MidiFile.Read(fileInfo2.FullName);
                var timeSignatureEvents = newMidiFile.GetTrackChunks().SelectMany(c => c.Events).OfType <TimeSignatureEvent>().ToArray();
                Assert.AreEqual(
                    1,
                    timeSignatureEvents.Length,
                    "Invalid count of Time Signature events in new file.");

                MidiAsserts.AreEventsEqual(timeSignatureEvents[0], nonDefaultTimeSignatureEvent, false, "Invalid Time Signature event.");
            });
        }
Esempio n. 2
0
 public MidiMBT(MidiFile mf)
 {
     timeSignature = mf.Events[0].OfType <TimeSignatureEvent>().FirstOrDefault();
     BeatsPerBar   = timeSignature == null ? 4 : timeSignature.Numerator;
     TicksPerBar   = timeSignature == null ? mf.DeltaTicksPerQuarterNote * 4 : (timeSignature.Numerator * mf.DeltaTicksPerQuarterNote * 4) / (1 << timeSignature.Denominator);
     TicksPerBeat  = TicksPerBar / BeatsPerBar;
 }
Esempio n. 3
0
 // Token: 0x06002A63 RID: 10851 RVA: 0x001380BC File Offset: 0x001362BC
 private static void smethod_5(EventsCollection eventsCollection_0, Song gclass27_0)
 {
     if (!GClass30.bool_0)
     {
         foreach (MidiEvent midiEvent in eventsCollection_0)
         {
             TimeSignatureEvent timeSignatureEvent = midiEvent as TimeSignatureEvent;
             if (timeSignatureEvent != null)
             {
                 long absoluteTime = midiEvent.AbsoluteTime;
                 gclass27_0.method_39(new GClass25((uint)absoluteTime, (uint)timeSignatureEvent.Numerator, (uint)timeSignatureEvent.Denominator), false);
             }
             else
             {
                 SetTempoEvent setTempoEvent = midiEvent as SetTempoEvent;
                 if (setTempoEvent != null)
                 {
                     long absoluteTime2 = midiEvent.AbsoluteTime;
                     gclass27_0.method_39(new GClass24((uint)absoluteTime2, (uint)(60000000.0 / (double)setTempoEvent.MicrosecondsPerQuarterNote * 1000.0)), false);
                 }
                 else
                 {
                     TextEvent textEvent = midiEvent as TextEvent;
                     if (textEvent != null)
                     {
                         gclass27_0.string_0 = textEvent.Text;
                     }
                 }
             }
         }
         gclass27_0.method_15();
     }
 }
Esempio n. 4
0
        /// <summary>
        /// Get Minecraft Tick When a Midi Event Starts
        /// </summary>
        /// <param name="eventTime">Current Tick</param>
        /// <param name="ticksPerQuarterNote">TP QuarterNote</param>
        /// <param name="timeSignature">timeSignate</param>
        /// <param name="bpm">Current BPM</param>
        /// <param name="bpm_key_t">Current Tick of BPM Event</param>
        /// <param name="bpm_key_mt">Current Minecraft Tick of BPM Event</param>
        /// <returns>Tick Start</returns>
        #region Functional
        private long MinecraftTickStart(long eventTime, int ticksPerQuarterNote, TimeSignatureEvent timeSignature, double bpm, long bpm_key_t, long bpm_key_mt)
        {
            int beatsPerBar  = timeSignature == null ? 4 : timeSignature.Numerator;
            int ticksPerBar  = timeSignature == null ? ticksPerQuarterNote * 4 : (timeSignature.Numerator * ticksPerQuarterNote * 4) / (1 << timeSignature.Denominator);
            int ticksPerBeat = ticksPerBar / beatsPerBar;

            return((long)(((double)(eventTime - bpm_key_t)) * 1200 / ((double)(ticksPerBeat * bpm)) + bpm_key_mt)); //Tick per Minute
        }
Esempio n. 5
0
        /// <summary>
        /// Get Duration of a Midi Event as Minecraft Tick
        /// </summary>
        /// <param name="eventTime">Current Tick</param>
        /// <param name="ticksPerQuarterNote">TP QuarterNote</param>
        /// <param name="timeSignature">timeSignate</param>
        /// <param name="bpm">Current BPM</param>
        /// <returns>Tick Duration</returns>
        private long MinecraftTickDuration(long eventTime, int ticksPerQuarterNote, TimeSignatureEvent timeSignature, int bpm)
        {
            int beatsPerBar  = timeSignature == null ? 4 : timeSignature.Numerator;
            int ticksPerBar  = timeSignature == null ? ticksPerQuarterNote * 4 : (timeSignature.Numerator * ticksPerQuarterNote * 4) / (1 << timeSignature.Denominator);
            int ticksPerBeat = ticksPerBar / beatsPerBar;

            return((long)(((double)eventTime) * 1200 / ((double)(ticksPerBeat * bpm))));
        }
Esempio n. 6
0
    private long GetBeat(long eventTime, int ticksPerQuarterNote, TimeSignatureEvent timeSignature)
    {
        int  beatsPerBar  = timeSignature == null ? 4 : timeSignature.Numerator;
        int  ticksPerBar  = timeSignature == null ? ticksPerQuarterNote * 4 : (timeSignature.Numerator * ticksPerQuarterNote * 4) / (1 << timeSignature.Denominator);
        int  ticksPerBeat = ticksPerBar / beatsPerBar;
        long beat         = 1 + ((eventTime % ticksPerBar) / ticksPerBeat);

        return(beat);
    }
Esempio n. 7
0
        private static string ToMBT(long eventTime, int ticksPerQuarterNote, TimeSignatureEvent timeSignature)
        {
            int  beatsPerBar  = timeSignature == null ? 4 : timeSignature.Numerator;
            int  ticksPerBar  = timeSignature == null ? ticksPerQuarterNote * 4 : (timeSignature.Numerator * ticksPerQuarterNote * 4) / (1 << timeSignature.Denominator);
            int  ticksPerBeat = ticksPerBar / beatsPerBar;
            long bar          = 1 + (eventTime / ticksPerBar);
            long beat         = 1 + ((eventTime % ticksPerBar) / ticksPerBeat);
            long tick         = eventTime % ticksPerBeat;

            return(String.Format("{0}:{1}:{2}", bar, beat, tick));
        }
Esempio n. 8
0
        private long[] GetMBT(long eventTime, int ticksPerQuarterNote, TimeSignatureEvent timeSignature)
        {
            int  beatsPerBar  = timeSignature == null ? 4 : timeSignature.Numerator;
            int  ticksPerBar  = timeSignature == null ? ticksPerQuarterNote * 4 : (timeSignature.Numerator * ticksPerQuarterNote * 4) / (1 << timeSignature.Denominator);
            int  ticksPerBeat = ticksPerBar / beatsPerBar;
            long bar          = 1 + (eventTime / ticksPerBar);
            long beat         = 1 + ((eventTime % ticksPerBar) / ticksPerBeat);
            long tick         = eventTime % ticksPerBeat;

            //bar, beat, tick
            long[] mbt = new[] { bar, beat, tick };
            return(mbt);
        }
Esempio n. 9
0
    private void ReadMidiFile(MidiFile midiFile, List <MidiNote> midiNotes)
    {
        if (midiFile.Tracks > 1)
        {
            Debug.LogWarning("Warning! Midi file has more than one track. Taking first track");
        }
        int totalMidiEvents = midiFile.Events[0].Count;

        for (int i = 0; i < totalMidiEvents; i++)
        {
            MidiEvent midiEvent = midiFile.Events[0][i];
            if (timeSignature is null)
            {
                try
                {
                    timeSignature = (TimeSignatureEvent)midiEvent;
                }
                catch (InvalidCastException e) when(e.Data != null)
                {
                }
            }
            if (!MidiEvent.IsNoteOff(midiEvent))
            {
                // Get the final tick of the song
                if (i == totalMidiEvents - 1)
                {
                    int eventTime = (int)midiEvent.AbsoluteTime;
                    if (eventTime > finalTick)
                    {
                        finalTick = eventTime;
                    }
                }
                // Ensure that the midievent is a note, and not metadata
                if (midiEvent.CommandCode.ToString() == "NoteOn")
                {
                    // Note length is retrieved from the next midiEvent's deltaTime
                    float noteLength = 0;

                    // Not at the end yet
                    if (i < totalMidiEvents)
                    {
                        MidiEvent nextMidievent = midiFile.Events[0][i + 1];
                        noteLength = ((float)nextMidievent.DeltaTime / ticksperQuarterNote);
                    }
                    Debug.Log(noteLength);
                    MidiNote note = GenerateMidiNote(midiEvent.AbsoluteTime, noteLength);
                    midiNotes.Add(note);
                }
            }
        }
    }
Esempio n. 10
0
        private void AnalyzeTimeSignature(MetaEvent meta)
        {
            TimeSignatureEvent timesig = (TimeSignatureEvent)meta;

            // Numerator: counts the number of beats in a measure.
            // For example a numerator of 4 means that each bar contains four beats.
            MPTK_TimeSigNumerator = timesig.Numerator;
            // Denominator: number of quarter notes in a beat.0=ronde, 1=blanche, 2=quarter, 3=eighth, etc.
            MPTK_TimeSigDenominator       = timesig.Denominator;
            MPTK_NumberBeatsMeasure       = timesig.Numerator;
            MPTK_NumberQuarterBeat        = System.Convert.ToInt32(System.Math.Pow(2, timesig.Denominator));
            MPTK_TicksInMetronomeClick    = timesig.TicksInMetronomeClick;
            MPTK_No32ndNotesInQuarterNote = timesig.No32ndNotesInQuarterNote;
        }
Esempio n. 11
0
    /// <summary>
    /// Find the number of beats per measure
    /// (for now assume just one TimeSignature per MIDI track)
    /// </summary>
    private int FindBeatsPerMeasure(IEnumerable <MidiEvent> midiEvents)
    {
        int beatsPerMeasure = 4;

        foreach (MidiEvent midiEvent in midiEvents)
        {
            TimeSignatureEvent tse = midiEvent as TimeSignatureEvent;
            if (tse != null)
            {
                beatsPerMeasure = tse.Numerator;
            }
        }
        return(beatsPerMeasure);
    }
Esempio n. 12
0
            public void TimeSignatureEvent()
            {
                var  ticks = 19864u;
                byte nn    = 0;
                byte dd    = 0;
                byte cc    = 0;
                byte bb    = 0;

                var x = new TimeSignatureEvent(ticks, nn, dd, cc, bb);
                var y = ReDeserialize(x);

                Assert.That(x.Ticks == y.Ticks);
                Assert.That(x.numerator == y.numerator);
                Assert.That(x.denominator == y.denominator);
                Assert.That(x.midiClocksPerClick == y.midiClocksPerClick);
                Assert.That(x.numberOfNotated32nds == y.numberOfNotated32nds);
            }
Esempio n. 13
0
        private void AnalyzeTimeSignature(MetaEvent meta, TrackMidiEvent trackEvent = null)
        {
            TimeSignatureEvent timesig = (TimeSignatureEvent)meta;

            // Numerator: counts the number of beats in a measure.
            // For example a numerator of 4 means that each bar contains four beats.
            MPTK_TimeSigNumerator = timesig.Numerator;
            // Denominator: number of quarter notes in a beat.0=ronde, 1=blanche, 2=quarter, 3=eighth, etc.
            MPTK_TimeSigDenominator       = timesig.Denominator;
            MPTK_NumberBeatsMeasure       = timesig.Numerator;
            MPTK_NumberQuarterBeat        = System.Convert.ToInt32(Mathf.Pow(2f, timesig.Denominator));
            MPTK_TicksInMetronomeClick    = timesig.TicksInMetronomeClick;
            MPTK_No32ndNotesInQuarterNote = timesig.No32ndNotesInQuarterNote;
            if (LogEvents && trackEvent != null)
            {
                Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Meta     {0,-15} Numerator:{1} Denominator:{2}", meta.MetaEventType, timesig.Numerator, timesig.Denominator));
            }
        }
Esempio n. 14
0
        /// <summary> Constructs an IMidiFile instance based on a MIDI file stream.</summary>
        /// <param name="stream"> stream of the midi file content. </param>
        /// <param name="disposeStream"> Set true if stream is to be closed by the constructor once it's done reading the file. </param>
        internal DryWetMidiAdapter(Stream stream, bool disposeStream = false)
        {
            // initialization
            Stream          = stream;
            stream.Position = 0;
            _midiContent    = MidiFile.Read(stream);
            _tempoMap       = _midiContent.GetTempoMap();
            IList <TrackChunk> trackChunks = _midiContent.GetTrackChunks().ToList();

            _metadataTrack = trackChunks.First();
            _metaEvents    = _metadataTrack.Events.ToList();

            // set midi title property
            Title = (((from e in _metaEvents
                       where e.EventType == MidiEventType.SequenceTrackName
                       select e).First()) as BaseTextEvent)?.Text ?? "Undefined";

            // set key signature property
            TimeSignatureEvent timeSignatureEvent = (from e in _metaEvents
                                                     where e.EventType == MidiEventType.TimeSignature
                                                     select e)?.First() as TimeSignatureEvent;

            KeySignature = MusicTheoryFactory.CreateDuration(timeSignatureEvent.Numerator, timeSignatureEvent.Denominator, false);

            // set number of bars property
            BarBeatFractionTimeSpan duration = _midiContent.GetDuration <BarBeatFractionTimeSpan>();

            NumberOfBars = (int)duration.Bars + (int)Math.Ceiling(duration.Beats / timeSignatureEvent.Numerator);

            // set BPM property
            BeatsPerMinute = (byte)(_midiContent.GetTempoMap()?.Tempo.AtTime(0).BeatsPerMinute);

            // set MIDI pitch range
            IEnumerable <DWMidiI.Note> notes = _midiContent.GetNotes();

            LowestPitch  = (NotePitch)(byte)(notes.Min(note => note.NoteNumber));
            HighestPitch = (NotePitch)(byte)(notes.Max(note => note.NoteNumber));

            // dispose stream if requested
            if (disposeStream)
            {
                stream.Dispose();
            }
        }
Esempio n. 15
0
        // BAD. Should have one for numerator, one for denominator
        private TimeSignatureEvent getTimeSignature()
        {
            // should there be a default state?
            for (int track = 0; track < m_data.Tracks; track++)
            {
                foreach (MidiEvent e in m_data[track])
                {
                    if (e.CommandCode == MidiCommandCode.MetaEvent)
                    {
                        if (e is TimeSignatureEvent)
                        {
                            TimeSignatureEvent n = (TimeSignatureEvent)e;

                            m_timeSig = n;
                            break; // not allowing time signature changes
                        }
                    }
                }
            }
            return(m_timeSig);
        }
Esempio n. 16
0
        private List <TimeSignatureChange> FindTimeSignatures(List <MidiEvent> midiEvents)
        {
            long currentTime = -1;
            List <TimeSignatureChange> timeSignatureEvents = new List <TimeSignatureChange>();

            foreach (MidiEvent midiEvent in midiEvents)
            {
                TimeSignatureEvent tse = midiEvent as TimeSignatureEvent;
                if (tse != null)
                {
                    if (tse.AbsoluteTime <= currentTime)
                    {
                        throw new ArgumentException("Unsorted Time Signatures found");
                    }
                    // TODO: work out how to get the start measure
                    int startMeasure = 1;
                    timeSignatureEvents.Add(new TimeSignatureChange(tse.AbsoluteTime, tse.Numerator, startMeasure));
                    currentTime = tse.AbsoluteTime;
                }
            }
            return(timeSignatureEvents);
        }
Esempio n. 17
0
        public IMessage getMessage(MetaEvent metaEvent)
        {
            switch (metaEvent.MetaEventType)
            {
            case SetTempo:
                TempoEvent       tempoEvent = (TempoEvent)metaEvent;
                TempoMetaMessage message    = TempoMetaMessage(tempoEvent.Tempo, tempoEvent.AbsoluteTime);
                return(message);

            case TimeSignature:
                TimeSignatureEvent       timeSignatureEvent = (TimeSignatureEvent)metaEvent;
                TimeSignatureMetaMessage message            = TimeSignatureMetaMessage(timeSignatureEvent.Numerator, timeSignatureEvent.Numerator, timeSignatureEvent.AbsoluteTime);
                return(message);

            case KeySignature:
                KeySignatureEvent        keySignatureEvent = (KeySignatureEvent)metaEvent;
                TimeSignatureMetaMessage message           = TimeSignatureMetaMessage((sbyte)keySignatureEvent.SharpsFlats, (byte)keySignatureEvent.MajorMinor, timeSignatureEvent.AbsoluteTime);
                return(message);

            default:
                return(null);    // TODO remaining MetaMessage types
            }
        }
Esempio n. 18
0
        public void ProcessTimeSignatures(MidiEventCollection midi)
        {
            // This is way easier if these have already been consolidated
            ConsolidateTimeTracks(midi);

            var timeSigTrackNo = midi.FindTrackNumberByName(TrackName.InputTimeSig.ToString());

            if (timeSigTrackNo == -1)
            {
                AddInfo($"No '{TrackName.InputTimeSig}' track");
                return;
            }

            var timeEvents = midi[midi.FindTrackNumberByName(TrackName.TempoMap.ToString())];

            var inputTimeSignatureEvents = midi[timeSigTrackNo].OfType <NoteOnEvent>();
            var groups = inputTimeSignatureEvents.GroupBy(e => e.AbsoluteTime);

            var error = false;

            foreach (var pair in groups)
            {
                var time = pair.Key;
                // The higher velocity value is the numerator (top)
                // And the lower velocity value is the denominator (bottom)
                var sorted = pair.OrderByDescending(e => e.Velocity).ToArray();
                if (sorted.Length != 2)
                {
                    error = true;
                    var detail = string.Join(", ", sorted.Select(e => $"<{e.NoteName} ({e.NoteNumber}), Velocity: {e.Velocity}>"));
                    AddError($"Incorrect number of time signature notes at {GetBarInfo(midi, time)}: {detail}");
                    continue;
                }

                if (sorted[0].Velocity == sorted[1].Velocity)
                {
                    error = true;
                    var detail = string.Join(", ", sorted.Select(e => $"<{e.NoteName} ({e.NoteNumber}), Velocity: {e.Velocity}>"));
                    AddError($"Multiple notes with the same velocity at {GetBarInfo(midi, time)}: {detail}");
                    continue;
                }

                var numerator = sorted[0].NoteNumber;

                int denominator;
                if (!TryConvertToDenominator(sorted[1].NoteNumber, out denominator))
                {
                    error = true;
                    AddError($"Invalid denominator note '{sorted[1].NoteNumber}' at {time}");
                    continue;
                }

                var timeSigEvent         = new TimeSignatureEvent(time, numerator, denominator, TicksInClick, NumberOfThirtySecondNotesInQuarterNote);
                var existingTimeSigEvent = timeEvents.OfType <TimeSignatureEvent>().SingleOrDefault(e => e.AbsoluteTime == time);
                if (existingTimeSigEvent != null)
                {
                    timeEvents.Remove(existingTimeSigEvent);
                }

                timeEvents.Add(timeSigEvent);
            }

            if (error)
            {
                throw new InvalidOperationException("Invalid time signature input");
            }

            // Clean up input track
            midi.RemoveTrack(timeSigTrackNo);

            UpdateTrackEnd(timeEvents, timeEvents.OrderBy(e => e.AbsoluteTime).Last().AbsoluteTime);

            // TODO: If there is no TimeSignatureEvent or TempoEvent at 0, wig out
        }
Esempio n. 19
0
        public Mid ToMid()
        {
            Mid mid = new Mid();

            mid.Type     = Mid.MidiType.Uniform;
            mid.Division = Division;

            Mid.Track beat = new Mid.Track();
            beat.Events.Add(new Mid.MetaEvent()
            {
                DeltaTime = 0,
                Type      = 0x03,
                Data      = (Name == null || Name.Length == 0) ? Util.Encoding.GetBytes("rawksd") : Util.Encoding.GetBytes(Name)
            });

            List <Event> events = new List <Event>();

            events.AddRange(BPM.ToArray());
            events.AddRange(Signature.ToArray());
            events.Sort(new EventComparer());
            ulong delta = 0;

            foreach (Event e in events)
            {
                if (e is TimeSignatureEvent)
                {
                    TimeSignatureEvent sig = e as TimeSignatureEvent;
                    beat.Events.Add(new Mid.MetaEvent()
                    {
                        DeltaTime = (uint)(sig.Time - delta), Type = 0x58, Data = new byte[] { sig.Numerator, sig.Denominator, sig.Metronome, sig.NumberOf32ndNotes }
                    });
                }
                else if (e is TempoEvent)
                {
                    TempoEvent bpm  = e as TempoEvent;
                    byte[]     mpqn = new byte[3];
                    Array.Copy(BigEndianConverter.GetBytes(bpm.MicrosecondsPerBeat), 1, mpqn, 0, 3);
                    beat.Events.Add(new Mid.MetaEvent()
                    {
                        DeltaTime = (uint)(bpm.Time - delta), Type = 0x51, Data = mpqn
                    });
                }
                delta = e.Time;
            }
            beat.Events.Add(new Mid.MetaEvent()
            {
                DeltaTime = 0, Type = 0x2F, Data = new byte[0]
            });
            mid.Tracks.Add(beat);
            foreach (Track t in Tracks)
            {
                events.Clear();
                t.Comments.ForEach(e => { if (e.Type == TextEvent.TextEventType.Unknown)
                                          {
                                              e.Type = TextEvent.TextEventType.Comment;
                                          }
                                   });
                t.Lyrics.ForEach(e => { if (e.Type == TextEvent.TextEventType.Unknown)
                                        {
                                            e.Type = TextEvent.TextEventType.Lyric;
                                        }
                                 });
                t.Markers.ForEach(e => { if (e.Type == TextEvent.TextEventType.Unknown)
                                         {
                                             e.Type = TextEvent.TextEventType.Marker;
                                         }
                                  });
                events.AddRange(t.Notes.ToArray());
                events.AddRange(t.Comments.ToArray());
                events.AddRange(t.Markers.ToArray());
                events.AddRange(t.Lyrics.ToArray());
                events.Sort(new EventComparer());
                delta = 0;
                Mid.Track track = new Mid.Track();
                track.Events.Add(new Mid.MetaEvent()
                {
                    DeltaTime = 0, Type = 0x03, Data = Util.Encoding.GetBytes(t.Name)
                });

                List <NoteEvent> OpenNotes = new List <NoteEvent>();
                foreach (Event e in events)
                {
__fuck_labels_opennotesagain:
                    foreach (NoteEvent n in OpenNotes)
                    {
                        if (n.Time + n.Duration <= e.Time)
                        {
                            track.Events.Add(new Mid.ChannelEvent()
                            {
                                DeltaTime = (uint)(n.Time + n.Duration - delta), Channel = n.Channel, Type = 0x8, Parameter1 = n.Note, Parameter2 = n.ReleaseVelocity
                            });
                            delta = n.Time + n.Duration;
                            OpenNotes.Remove(n);
                            goto __fuck_labels_opennotesagain;                             // Yeah, too lazy to make a ToRemove list
                        }
                    }
                    if (e is NoteEvent)
                    {
                        NoteEvent n = e as NoteEvent;

                        NoteEvent overlap = OpenNotes.Find(n2 => n2.Note == n.Note);
                        if (overlap != null)                           // Stretch the open note over the colliding note
                        {
                            overlap.Duration = Math.Max(overlap.Duration, n.Time + n.Duration - overlap.Time);
                            OpenNotes.Sort(new NoteEventComparer());
                            continue;
                        }
                        else
                        {
                            OpenNotes.Insert(0, n);
                            OpenNotes.Sort(new NoteEventComparer());
                            track.Events.Add(new Mid.ChannelEvent()
                            {
                                DeltaTime = (uint)(n.Time - delta), Channel = n.Channel, Type = 0x9, Parameter1 = n.Note, Parameter2 = n.Velocity
                            });
                        }
                    }
                    else if (e is TextEvent)
                    {
                        TextEvent l = e as TextEvent;
                        track.Events.Add(new Mid.MetaEvent()
                        {
                            DeltaTime = (uint)(l.Time - delta), Type = (byte)l.Type, Data = Util.Encoding.GetBytes(l.Text)
                        });
                    }
                    else if (e is TextEvent)
                    {
                        TextEvent c = e as TextEvent;
                        track.Events.Add(new Mid.MetaEvent()
                        {
                            DeltaTime = (uint)(c.Time - delta), Type = 0x1, Data = Util.Encoding.GetBytes(c.Text)
                        });
                    }
                    delta = e.Time;
                }
                foreach (NoteEvent n in OpenNotes)
                {
                    track.Events.Add(new Mid.ChannelEvent()
                    {
                        DeltaTime = (uint)(n.Time + n.Duration - delta), Channel = n.Channel, Type = 0x8, Parameter1 = n.Note, Parameter2 = n.ReleaseVelocity
                    });
                    delta = n.Time + n.Duration;
                }

                track.Events.Add(new Mid.MetaEvent()
                {
                    DeltaTime = 0, Type = 0x2F, Data = new byte[0]
                });

                mid.Tracks.Add(track);
            }

            return(mid);
        }
Esempio n. 20
0
    void UpdateBars()
    {
        for (int i = 0; i < tracks.Count; i++)
        {
            while (tracks [i] [eventPos [i]].AbsoluteTime <= ticks)
            {
                if (endOfTrack [i])
                {
                    break;
                }

                midiEvent = tracks [i] [eventPos [i]];

                switch (midiEvent.CommandCode)
                {
                case MidiCommandCode.MetaEvent:
                    metaEvent = (midiEvent as MetaEvent);
                    switch (metaEvent.MetaEventType)
                    {
                    case MetaEventType.KeySignature:
                        keyMajorMinor = (metaEvent as KeySignatureEvent).MajorMinor;
                        Debug.Log("MAJOR or MINOR: " + keyMajorMinor);
                        keySharpsFlats = (metaEvent as KeySignatureEvent).SharpsFlats;
                        Debug.Log("SIGNATURE : " + keySharpsFlats);
                        break;

                    case MetaEventType.SequenceTrackName:
                        Debug.Log("TrackName : " + (metaEvent as TextEvent).Text);
                        break;

                    case MetaEventType.SetTempo:
                        TempoEvent tempoEvent = (midiEvent as TempoEvent);
                        tempoOriginal = (float)tempoEvent.Tempo;
                        if (!tempoCustom)
                        {
                            tempo = tempoOriginal;
                        }
                        break;

                    case MetaEventType.SmpteOffset:

                        break;

                    case MetaEventType.TextEvent:

                        break;

                    case MetaEventType.TimeSignature:
                        TimeSignatureEvent signatureEvent = (midiEvent as TimeSignatureEvent);
                        timeSignatureNumerator    = signatureEvent.Numerator;
                        _timeSignatureDenominator = signatureEvent.Denominator;
                        timeSignatureDenominator  = (int)Mathf.Pow(2, _timeSignatureDenominator);
                        break;

                    case MetaEventType.EndTrack:

                        break;
                    }
                    break;
                }

                if (eventPos [i] >= tracks [i].Count - 1)
                {
                    endOfTrack [i] = true;
                    bool endOfFile = true;
                    for (int k = 0; k < tracks.Count; k++)
                    {
                        if (!endOfTrack [k])
                        {
                            endOfFile = false;
                            break;
                        }
                    }
                    if (endOfFile)
                    {
                        state     = State.Finished;
                        ticks     = ticks - lastDeltaTicks;
                        totalTime = time - lastDeltaTime;
                        Bar lastBar = bars.Last();
                        lastBar.timeDuration  = time - lastBar.time;
                        lastBar.ticksDuration = ticks - lastBar.ticks;
                        return;
                    }
                    break;
                }

                eventPos [i] = eventPos [i] == tracks [i].Count - 1 ? eventPos [i] : eventPos [i] + 1;
            }
        }

        if (beatCount != (int)(ticks / PPQN / (4f / timeSignatureDenominator)) + 1)
        {
            beat      = beatCount % (int)timeSignatureNumerator + 1;
            beatCount = (int)(ticks / PPQN / (4f / timeSignatureDenominator)) + 1;
            if (beat == 1)
            {
                Bar bar = new Bar()
                {
                    time  = this.time,
                    ticks = this.ticks,
                    tempo = this.tempo,
                    timeSignatureNumerator   = this.timeSignatureNumerator,
                    timeSignatureDenominator = this.timeSignatureDenominator,
                    majorMinor  = this.keyMajorMinor,
                    sharpsFlats = this.keySharpsFlats
                };

                if (bars.Count > 0)
                {
                    Bar lastBar = bars.Last();
                    lastBar.timeDuration  = time - lastDeltaTime - lastBar.time;
                    lastBar.ticksDuration = ticks - lastDeltaTicks - lastBar.ticks;
                }

                bar.eventPos   = new int[eventPos.Length];
                bar.endOfTrack = new bool[endOfTrack.Length];

                for (int i = 0; i < bar.eventPos.Length; i++)
                {
                    bar.eventPos [i]   = GetTrackEventPosFromAbsoluteTicks(i, ticks - 100);
                    bar.endOfTrack [i] = endOfTrack [i];
                }
                bars.Add(bar);
            }
        }

        deltaTime = deltaTimeResolution;

        periodResolution = PPQN * 1000f * deltaTime * MicrosecondsPerMillisecond;
        //ticksPerClock = PPQN / PPQNMinValue;
        deltaTicks       = (fractionalTicks + periodResolution) / tempoTicks;
        fractionalTicks += periodResolution - deltaTicks * tempoTicks;
        ticks           += deltaTicks;
        time            += deltaTime;

        lastTime       = time;
        lastDeltaTime  = deltaTime;
        lastDeltaTicks = deltaTicks;
    }
Esempio n. 21
0
        public void Extractor()
        {
            int  pan         = 0;
            int  noteLength  = 0;
            int  restLength  = 0;
            int  tempLength  = 0;
            int  totalLength = 0;  //the sum of noteLength and restLength.
            int  trackVolume = 1;  //volume of the MIDI track, can change throughout the track
            int  velocity    = 0;  // velocity of the MIDI note
            int  note        = -1; //stores the value of the next note; -1 is the starting note and is a "rest" that might print only in the beginning;
            bool flagNote    = false;

            int[] MIDILength = new int[] { 0, 0, 0, 0 };

            //checks if the out.asm file already exists and clears its contents
            if (File.Exists(string.Concat(directoryPath, ASMFileName, ".asm")))
            {
                FileStream fileStream = File.Open(string.Concat(directoryPath, ASMFileName, ".asm"), FileMode.Open);
                fileStream.SetLength(0);
                fileStream.Close();
            }

            var midifile     = MidiFile.Read(directoryPath + midiFileName + "." + midiFileExtension);
            var trackChuncks = midifile.GetTrackChunks(); // contains the information for all tracks

            if (TempoTrack)
            {
                NumberOfTracks = trackChuncks.Count() - 1;
                TrackNumber    = -1;
            }
            else
            {
                NumberOfTracks = trackChuncks.Count();
            }

            //finds the TimeDivision and the number of tracks of the MIDI file
            string[] tempDivision = midifile.TimeDivision.ToString().Split(' ');
            TimeDivision = Int32.Parse(tempDivision[0]);
            for (int k = 0; k < allowedNotetypes.Length; k++)
            {
                unitaryLengthArray[k] = Convert.ToInt32((double)TimeDivision / (48 / allowedNotetypes[k]));
            }
            unitaryLength = unitaryLengthArray[BaseNotetypeLocation];

            AllTrackList = new List <MIDINote> [NumberOfTracks]; //creates the AllTrackList with NumberOfTracks Length
            // Reads each track in sequence
            foreach (var track in trackChuncks)
            {
                TrackNumber++;
                trackVolume = 1; //resets trackvolume for the new track

                //loops through events
                foreach (MidiEvent Level2 in track.Events)
                {
                    //get the Delta Time of the event
                    tempLength  = (int)Level2.DeltaTime;
                    totalLength = noteLength + tempLength + restLength;

                    switch (Level2.EventType.ToString())
                    {
                    case "ControlChange":
                    {
                        ControlChangeEvent TempEvent = (ControlChangeEvent)Level2;
                        //tests and changes stereopanning
                        if (TempEvent.ControlNumber == 10)
                        {
                            pan = TempEvent.ControlValue;
                        }
                        //sets new trackvolume to define the intensity of this track. Can vary multiple times during the same music.
                        if (TempEvent.ControlNumber == 7)
                        {
                            trackVolume = TempEvent.ControlValue;
                        }
                        break;
                    }

                    //only relevant for the first track
                    case "TimeSignature":
                    {
                        TimeSignatureEvent TempEvent = (TimeSignatureEvent)Level2;
                        timeSignature = TempEvent.Numerator * 16 / TempEvent.Denominator;
                        break;
                    }

                    case "SetTempo":
                    {
                        SetTempoEvent TempEvent = (SetTempoEvent)Level2;
                        Tempo = Convert.ToInt32(TempEvent.MicrosecondsPerQuarterNote) / 3138;;
                        break;
                    }

                    case "NoteOn":
                    {
                        //register the currently "saved" note
                        // we are on a rest

                        NoteEvent TempEvent = (NoteEvent)Level2;
                        flagNote    = true;
                        restLength += tempLength;
                        if ((restLength >= unitaryLength & TrackNumber != 4) || (restLength >= unitaryLength * 16))         //the noise channel only prints rests if its bigger than 16 times the UL
                        {
                            if (IgnoreRests)
                            {
                                NoteListTemp.Add(new MIDINote(noteLength + restLength, MIDILength[TrackNumber - 1], note, pan, velocity, trackVolume));
                            }
                            else
                            {
                                NoteListTemp.Add(new MIDINote(noteLength, MIDILength[TrackNumber - 1], note, pan, velocity, trackVolume));
                                NoteListTemp.Add(new MIDINote(restLength, MIDILength[TrackNumber - 1] + noteLength, 0, pan, velocity, trackVolume));
                            }
                        }
                        else
                        {
                            NoteListTemp.Add(new MIDINote(totalLength, MIDILength[TrackNumber - 1], note, pan, velocity, trackVolume));
                        }

                        //i++; //debug
                        //NoteListTemp.ElementAt(i-1).ShowNotes(); //debug

                        MIDILength[TrackNumber - 1] += totalLength;
                        noteLength = restLength = tempLength = totalLength = 0;

                        //setup for the next note
                        note     = TempEvent.NoteNumber;
                        velocity = TempEvent.Velocity;
                        break;
                    }

                    case "NoteOff":
                    {
                        //NoteEvent TempEvent = (NoteEvent)Level2;
                        flagNote    = true;
                        noteLength += tempLength;
                        break;
                    }

                    default:
                    {
                        break;
                    }
                    }
                    if (!flagNote & tempLength > unitaryLength)
                    {
                        restLength += tempLength;
                    }
                    else if (!flagNote)
                    {
                        noteLength += tempLength;
                    }
                    flagNote = false;
                }

                //last note print
                if (TrackNumber > 0)
                {
                    NoteListTemp.Add(new MIDINote(totalLength, MIDILength[TrackNumber - 1], note, pan, velocity, trackVolume));
                }

                //We've reached the end of the track
                noteLength = restLength = totalLength = 0;
                note       = -1;

                if (TrackNumber > 0)
                {
                    AllTrackList[TrackNumber - 1] = new List <MIDINote>(NoteListTemp);
                    //for(int i=0;i<NoteListTemp.Count;i++)
                    //{
                    //    Console.WriteLine(NoteListTemp.ElementAt(i));
                    //}
                    NoteListTemp.Clear();
                }
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Return information about a midifile : patch change, copyright, ...
        /// </summary>
        /// <param name="pathfilename"></param>
        /// <param name="Info"></param>
        static public void GeneralInfo(string pathfilename, BuilderInfo Info)
        {
            try
            {
                int NumberBeatsMeasure;
                int NumberQuarterBeat;
                Debug.Log("Open midifile :" + pathfilename);
                MidiLoad midifile = new MidiLoad();
                midifile.Load(pathfilename);
                if (midifile != null)
                {
                    Info.Add(string.Format("Format: {0}", midifile.midifile.FileFormat));
                    Info.Add(string.Format("Tracks: {0}", midifile.midifile.Tracks));
                    Info.Add(string.Format("Ticks Quarter Note: {0}", midifile.midifile.DeltaTicksPerQuarterNote));

                    //if (false)
                    {
                        foreach (TrackMidiEvent trackEvent in midifile.MidiSorted)
                        {
                            if (trackEvent.Event.CommandCode == MidiCommandCode.NoteOn)
                            {
                                // Not used
                                //if (((NoteOnEvent)trackEvent.Event).OffEvent != null)
                                //{
                                //    //infoTrackMidi[e.Channel].Events.Add((NoteOnEvent)e);
                                //    NoteOnEvent noteon = (NoteOnEvent)trackEvent.Event;
                                //}
                            }
                            else if (trackEvent.Event.CommandCode == MidiCommandCode.NoteOff)
                            {
                                Debug.Log("NoteOff");
                            }
                            else if (trackEvent.Event.CommandCode == MidiCommandCode.ControlChange)
                            {
                                // Not used
                                //ControlChangeEvent controlchange = (ControlChangeEvent)e;
                                //Debug.Log(string.Format("CtrlChange  Track:{0} Channel:{1,2:00} {2}", track, e.Channel, controlchange.ToString()));
                            }
                            else if (trackEvent.Event.CommandCode == MidiCommandCode.PatchChange)
                            {
                                PatchChangeEvent change = (PatchChangeEvent)trackEvent.Event;
                                Info.Add(BuildInfoTrack(trackEvent) + string.Format("PatchChange {0,3:000} {1}", change.Patch, PatchChangeEvent.GetPatchName(change.Patch)), 2);
                            }
                            else if (trackEvent.Event.CommandCode == MidiCommandCode.MetaEvent)
                            {
                                MetaEvent meta = (MetaEvent)trackEvent.Event;
                                switch (meta.MetaEventType)
                                {
                                case MetaEventType.SetTempo:
                                    TempoEvent tempo = (TempoEvent)meta;
                                    Info.Add(BuildInfoTrack(trackEvent) + string.Format("SetTempo Tempo:{0} MicrosecondsPerQuarterNote:{1}", Math.Round(tempo.Tempo, 0), tempo.MicrosecondsPerQuarterNote), 2);
                                    //tempo.Tempo
                                    break;

                                case MetaEventType.TimeSignature:

                                    TimeSignatureEvent timesig = (TimeSignatureEvent)meta;
                                    // Numerator: counts the number of beats in a measure.
                                    // For example a numerator of 4 means that each bar contains four beats.

                                    // Denominator: number of quarter notes in a beat.0=ronde, 1=blanche, 2=quarter, 3=eighth, etc.
                                    // Set default value
                                    NumberBeatsMeasure = timesig.Numerator;
                                    NumberQuarterBeat  = System.Convert.ToInt32(System.Math.Pow(2, timesig.Denominator));
                                    Info.Add(BuildInfoTrack(trackEvent) + string.Format("TimeSignature Beats Measure:{0} Beat Quarter:{1}", NumberBeatsMeasure, NumberQuarterBeat), 2);
                                    break;

                                case MetaEventType.SequenceTrackName:   // Sequence / Track Name
                                case MetaEventType.ProgramName:
                                case MetaEventType.TrackInstrumentName: // Track instrument name
                                case MetaEventType.TextEvent:           // Text event
                                case MetaEventType.Copyright:           // Copyright
                                    Info.Add(BuildInfoTrack(trackEvent) + ((TextEvent)meta).Text, 1);
                                    break;

                                case MetaEventType.Lyric:     // lyric
                                case MetaEventType.Marker:    // marker
                                case MetaEventType.CuePoint:  // cue point
                                case MetaEventType.DeviceName:
                                    //Info.Add(BuildInfoTrack(trackEvent) + string.Format("{0} '{1}'", meta.MetaEventType.ToString(), ((TextEvent)meta).Text));
                                    break;
                                }
                            }
                            else
                            {
                                // Other midi event
                                //Debug.Log(string.Format("Track:{0} Channel:{1,2:00} CommandCode:{2,3:000} AbsoluteTime:{3,6:000000}", track, e.Channel, e.CommandCode.ToString(), e.AbsoluteTime));
                            }
                        }
                    }
                    //else DebugMidiSorted(midifile.MidiSorted);
                }
                else
                {
                    Info.Add("Error reading midi file");
                }
            }
            catch (System.Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
        }
Esempio n. 23
0
        private static Tuple <Option <MidiEvent>, int, byte> NextEvent(List <byte> trackData, int startIndex, byte lastMidiChannel)
        {
            var i = startIndex - 1;

            MidiEvent midiEvent = null;

            {
                int deltaTime;
                {
                    var lengthTemp = new List <byte>();
                    do
                    {
                        i += 1;
                        lengthTemp.Add(trackData.ElementAt(i));
                    } while (trackData.ElementAt(i) > 0x7F);

                    deltaTime = VariableLengthUtil.decode_to_int(lengthTemp);
                }

                i += 1;

                var eventTypeValue = trackData.ElementAt(i);

                // MIDI Channel Events
                if ((eventTypeValue & 0xF0) < 0xF0)
                {
                    var midiChannelEventType = (byte)(eventTypeValue & 0xF0);
                    var midiChannel          = (byte)(eventTypeValue & 0x0F);
                    i += 1;
                    var  parameter1 = trackData.ElementAt(i);
                    byte parameter2;

                    // One or two parameter type
                    switch (midiChannelEventType)
                    {
                    // One parameter types
                    case 0xC0:
                        midiEvent       = new ProgramChangeEvent(deltaTime, midiChannel, parameter1);
                        lastMidiChannel = midiChannel;
                        break;

                    case 0xD0:
                        midiEvent       = new ChannelAftertouchEvent(deltaTime, midiChannel, parameter1);
                        lastMidiChannel = midiChannel;
                        break;

                    // Two parameter types
                    case 0x80:
                        i              += 1;
                        parameter2      = trackData.ElementAt(i);
                        midiEvent       = new NoteOffEvent(deltaTime, midiChannel, parameter1, parameter2);
                        lastMidiChannel = midiChannel;
                        break;

                    case 0x90:
                        i              += 1;
                        parameter2      = trackData.ElementAt(i);
                        midiEvent       = new NoteOnEvent(deltaTime, midiChannel, parameter1, parameter2);
                        lastMidiChannel = midiChannel;
                        break;

                    case 0xA0:
                        i              += 1;
                        parameter2      = trackData.ElementAt(i);
                        midiEvent       = new NoteAftertouchEvent(deltaTime, midiChannel, parameter1, parameter2);
                        lastMidiChannel = midiChannel;
                        break;

                    case 0xB0:
                        i              += 1;
                        parameter2      = trackData.ElementAt(i);
                        midiEvent       = new ControllerEvent(deltaTime, midiChannel, parameter1, parameter2);
                        lastMidiChannel = midiChannel;
                        break;

                    case 0xE0:
                        i              += 1;
                        parameter2      = trackData.ElementAt(i);
                        midiEvent       = new PitchBendEvent(deltaTime, midiChannel, parameter1, parameter2);
                        lastMidiChannel = midiChannel;
                        break;

                    // Might be a Control Change Messages LSB
                    default:
                        midiEvent = new ControllerEvent(deltaTime, lastMidiChannel, eventTypeValue, parameter1);
                        break;
                    }

                    i += 1;
                }
                // Meta Events
                else if (eventTypeValue == 0xFF)
                {
                    i += 1;
                    var metaEventType = trackData.ElementAt(i);
                    i += 1;
                    var metaEventLength = trackData.ElementAt(i);
                    i += 1;
                    var metaEventData = Enumerable.Range(i, metaEventLength).Select(trackData.ElementAt).ToArray();

                    switch (metaEventType)
                    {
                    case 0x00:
                        midiEvent = new SequenceNumberEvent(BitConverter.ToUInt16(metaEventData.Reverse().ToArray(), 0));
                        break;

                    case 0x01:
                        midiEvent = new TextEvent(deltaTime, StringEncoder.GetString(metaEventData));
                        break;

                    case 0x02:
                        midiEvent = new CopyrightNoticeEvent(StringEncoder.GetString(metaEventData));
                        break;

                    case 0x03:
                        midiEvent = new SequenceOrTrackNameEvent(StringEncoder.GetString(metaEventData));
                        break;

                    case 0x04:
                        midiEvent = new InstrumentNameEvent(deltaTime, StringEncoder.GetString(metaEventData));
                        break;

                    case 0x05:
                        midiEvent = new LyricsEvent(deltaTime, StringEncoder.GetString(metaEventData));
                        break;

                    case 0x06:
                        midiEvent = new MarkerEvent(deltaTime, StringEncoder.GetString(metaEventData));
                        break;

                    case 0x07:
                        midiEvent = new CuePointEvent(deltaTime, StringEncoder.GetString(metaEventData));
                        break;

                    case 0x20:
                        midiEvent = new MIDIChannelPrefixEvent(deltaTime, metaEventData[0]);
                        break;

                    case 0x2F:
                        midiEvent = new EndOfTrackEvent(deltaTime);
                        break;

                    case 0x51:
                        var tempo =
                            (metaEventData[2] & 0x0F) +
                            ((metaEventData[2] & 0xF0) * 16) +
                            ((metaEventData[1] & 0x0F) * 256) +
                            ((metaEventData[1] & 0xF0) * 4096) +
                            ((metaEventData[0] & 0x0F) * 65536) +
                            ((metaEventData[0] & 0xF0) * 1048576);
                        midiEvent = new SetTempoEvent(deltaTime, tempo);
                        break;

                    case 0x54:
                        midiEvent = new SMPTEOffsetEvent(deltaTime, metaEventData[0], metaEventData[1], metaEventData[2], metaEventData[3], metaEventData[4]);
                        break;

                    case 0x58:
                        midiEvent = new TimeSignatureEvent(deltaTime, metaEventData[0], metaEventData[1], metaEventData[2], metaEventData[3]);
                        break;

                    case 0x59:
                        midiEvent = new KeySignatureEvent(deltaTime, metaEventData[0], metaEventData[1]);
                        break;

                    case 0x7F:
                        midiEvent = new SequencerSpecificEvent(deltaTime, metaEventData);
                        break;
                    }

                    i += metaEventLength;
                }
                // System Exclusive Events
                else if (eventTypeValue == 0xF0 || eventTypeValue == 0xF7)
                {
                    var lengthTemp = new List <byte>();
                    do
                    {
                        i += 1;
                        lengthTemp.Add(trackData.ElementAt(i));
                    } while (trackData.ElementAt(i) > 0x7F);

                    var eventLength = VariableLengthUtil.decode_to_int(lengthTemp);

                    i += 1;

                    var eventData = Enumerable.Range(i, eventLength).Select(trackData.ElementAt);

                    midiEvent = new SysexEvent(deltaTime, eventTypeValue, eventData);

                    i += eventLength;
                }
            }

            return(midiEvent != null
                ? new Tuple <Option <MidiEvent>, int, byte>(new Some <MidiEvent>(midiEvent), i - startIndex, lastMidiChannel)
                : new Tuple <Option <MidiEvent>, int, byte>(new None <MidiEvent>(), i - startIndex, lastMidiChannel));
        }
Esempio n. 24
0
        /// <summary>
        /// Return information about a midifile : patch change, copyright, ...
        /// </summary>
        /// <param name="pathfilename"></param>
        /// <param name="Info"></param>
        static public List <string> GeneralInfo(string pathfilename, bool withNoteOn, bool withNoteOff, bool withControlChange, bool withPatchChange, bool withAfterTouch, bool withMeta, bool withOthers)
        {
            List <string> Info = new List <string>();

            try
            {
                int      NumberBeatsMeasure;
                int      NumberQuarterBeat;
                MidiLoad midifile = new MidiLoad();
                midifile.KeepNoteOff = withNoteOff;
                midifile.MPTK_Load(pathfilename);
                if (midifile != null)
                {
                    Info.Add(string.Format("Format: {0}", midifile.midifile.FileFormat));
                    Info.Add(string.Format("Tracks: {0}", midifile.midifile.Tracks));
                    Info.Add(string.Format("Events count: {0}", midifile.MidiSorted.Count()));
                    Info.Add(string.Format("Duration: {0} ({1} seconds) {2} Ticks", midifile.MPTK_RealDuration, midifile.MPTK_RealDuration.TotalSeconds, midifile.MPTK_TickLast));
                    Info.Add(string.Format("Initial Tempo: {0,0:F2} BPM", midifile.MPTK_InitialTempo));
                    Info.Add(string.Format("Beats in a measure: {0}", midifile.MPTK_NumberBeatsMeasure));
                    Info.Add(string.Format("Quarters count in a beat:{0}", midifile.MPTK_NumberQuarterBeat));
                    Info.Add(string.Format("Ticks per Quarter Note: {0}", midifile.midifile.DeltaTicksPerQuarterNote));
                    Info.Add("");
                    //if (false)
                    {
                        foreach (TrackMidiEvent trackEvent in midifile.MidiSorted)
                        {
                            switch (trackEvent.Event.CommandCode)
                            {
                            case MidiCommandCode.NoteOn:
                                if (withNoteOn)
                                {
                                    if (((NoteOnEvent)trackEvent.Event).OffEvent != null)
                                    {
                                        NoteOnEvent noteon = (NoteOnEvent)trackEvent.Event;
                                        Info.Add(BuildInfoTrack(trackEvent) + string.Format("NoteOn {0,3} ({1,3}) Len:{2,3} Vel:{3,3}", noteon.NoteName, noteon.NoteNumber, noteon.NoteLength, noteon.Velocity));
                                    }
                                }
                                break;

                            case MidiCommandCode.NoteOff:
                                if (withNoteOff)
                                {
                                    NoteEvent noteoff = (NoteEvent)trackEvent.Event;
                                    Info.Add(BuildInfoTrack(trackEvent) + string.Format("NoteOff {0,3} ({1,3}) Vel:{2,3}", noteoff.NoteName, noteoff.NoteNumber, noteoff.Velocity));
                                }
                                break;

                            case MidiCommandCode.PitchWheelChange:
                                if (withOthers)
                                {
                                    PitchWheelChangeEvent aftertouch = (PitchWheelChangeEvent)trackEvent.Event;
                                    Info.Add(BuildInfoTrack(trackEvent) + string.Format("PitchWheelChange {0,3}", aftertouch.Pitch));
                                }
                                break;

                            case MidiCommandCode.KeyAfterTouch:
                                if (withAfterTouch)
                                {
                                    NoteEvent aftertouch = (NoteEvent)trackEvent.Event;
                                    Info.Add(BuildInfoTrack(trackEvent) + string.Format("KeyAfterTouch {0,3} ({1,3}) Pressure:{2,3}", aftertouch.NoteName, aftertouch.NoteNumber, aftertouch.Velocity));
                                }
                                break;

                            case MidiCommandCode.ChannelAfterTouch:
                                if (withAfterTouch)
                                {
                                    ChannelAfterTouchEvent aftertouch = (ChannelAfterTouchEvent)trackEvent.Event;
                                    Info.Add(BuildInfoTrack(trackEvent) + string.Format("ChannelAfterTouch Pressure:{0,3}", aftertouch.AfterTouchPressure));
                                }
                                break;

                            case MidiCommandCode.ControlChange:
                                if (withControlChange)
                                {
                                    ControlChangeEvent controlchange = (ControlChangeEvent)trackEvent.Event;
                                    Info.Add(BuildInfoTrack(trackEvent) + string.Format("ControlChange {0,3} ({1,3}) Value:{2,3}", controlchange.Controller, controlchange.Controller, controlchange.ControllerValue));
                                }
                                break;

                            case MidiCommandCode.PatchChange:
                                if (withPatchChange)
                                {
                                    PatchChangeEvent change = (PatchChangeEvent)trackEvent.Event;
                                    Info.Add(BuildInfoTrack(trackEvent) + string.Format("PatchChange {0,3:000} {1}", change.Patch, PatchChangeEvent.GetPatchName(change.Patch)));
                                }
                                break;

                            case MidiCommandCode.MetaEvent:
                                if (withMeta)
                                {
                                    MetaEvent meta = (MetaEvent)trackEvent.Event;
                                    switch (meta.MetaEventType)
                                    {
                                    case MetaEventType.SetTempo:
                                        TempoEvent tempo = (TempoEvent)meta;
                                        Info.Add(BuildInfoTrack(trackEvent) + string.Format("SetTempo Tempo:{0} MicrosecondsPerQuarterNote:{1}", Math.Round(tempo.Tempo, 0), tempo.MicrosecondsPerQuarterNote));
                                        //tempo.Tempo
                                        break;

                                    case MetaEventType.TimeSignature:
                                        TimeSignatureEvent timesig = (TimeSignatureEvent)meta;
                                        // Numerator: counts the number of beats in a measure.
                                        // For example a numerator of 4 means that each bar contains four beats.

                                        // Denominator: number of quarter notes in a beat.0=ronde, 1=blanche, 2=quarter, 3=eighth, etc.
                                        // Set default value
                                        NumberBeatsMeasure = timesig.Numerator;
                                        NumberQuarterBeat  = System.Convert.ToInt32(Mathf.Pow(2, timesig.Denominator));
                                        Info.Add(BuildInfoTrack(trackEvent) + string.Format("TimeSignature Beats Measure:{0} Beat Quarter:{1}", NumberBeatsMeasure, NumberQuarterBeat));
                                        break;

                                    default:
                                        string text = meta is TextEvent ? " '" + ((TextEvent)meta).Text + "'" : "";
                                        Info.Add(BuildInfoTrack(trackEvent) + meta.MetaEventType.ToString() + text);
                                        break;
                                    }
                                }
                                break;

                            default:
                                // Other midi event
                                if (withOthers)
                                {
                                    Info.Add(BuildInfoTrack(trackEvent) + string.Format(" {0} ({1})", trackEvent.Event.CommandCode, (int)trackEvent.Event.CommandCode));
                                }
                                break;
                            }
                        }
                    }
                    //else DebugMidiSorted(midifile.MidiSorted);
                }
                else
                {
                    Info.Add("Error reading midi file");
                }
            }
            catch (System.Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
            return(Info);
        }
    bool CallEvents()
    {
        if (wordPos < words.Count)
        {
            if (wordPos > 0)
            {
                if (!words [wordPos].finishFired)
                {
                    if (words [wordPos].absoluteStartTime <= ticks)
                    {
                        if (OnWordFinished != null)
                        {
                            OnWordFinished();
                        }
                        words [wordPos].finishFired = true;
                    }
                }
            }

            if (words [wordPos < 0 ? 0 : wordPos].absoluteStartTime <= ticks)
            {
                if (OnWord != null)
                {
                    OnWord(words [wordPos < 0 ? 0 : wordPos]);
                }
                wordPos++;
            }
        }

        if (wordOffsetPos < words.Count)
        {
            if (wordOffsetPos > 0)
            {
                if (!words [wordOffsetPos].finishFired)
                {
                    if (words [wordOffsetPos].absoluteStartTime + TimeToTicks(wordTimeOffset) + TimeToTicks(wordTimeFinishedOffset) <= ticks)
                    {
                        if (OnWordOffsetFinished != null)
                        {
                            OnWordOffsetFinished();
                        }
                        words [wordOffsetPos].finishOffsetFired = true;
                    }
                }
            }

            if (words [wordOffsetPos < 0 ? 0 : wordOffsetPos].absoluteStartTime + TimeToTicks(wordTimeOffset) <= ticks)
            {
                if (OnWordOffset != null)
                {
                    OnWordOffset(words [wordOffsetPos < 0 ? 0 : wordOffsetPos]);
                }
                wordOffsetPos++;
            }
        }

        if (sentencePos < sentences.Count)
        {
            if (sentences [sentencePos < 0 ? 0 : sentencePos].absoluteStartTime + TimeToTicks(senteceTimeOffset) <= ticks)
            {
                if (OnSentence != null)
                {
                    OnSentence(sentences [sentencePos < 0 ? 0 : sentencePos]);
                }
                sentencePos++;
            }
        }

        if (versePos < verses.Count)
        {
            if (verses [versePos < 0 ? 0 : versePos].absoluteStartTime + TimeToTicks(versetTimeOffset) <= ticks)
            {
                if (OnVerse != null)
                {
                    OnVerse(verses [versePos < 0 ? 0 : versePos]);
                }

                versePos++;
            }
        }

        for (int i = 0; i < tracks.Count; i++)
        {
            while (tracks [i] [eventPos [i]].AbsoluteTime <= ticks)
            {
                if (endOfTrack [i])
                {
                    break;
                }

                midiEvent = tracks [i] [eventPos [i]];

                command = midiEvent.CommandCode;
                if (command == MidiCommandCode.NoteOn && midiEvent.Data2 == 0)
                {
                    command = MidiCommandCode.NoteOff;
                }

                if (midiOut)
                {
                    if (!muteTrack [i])
                    {
                        MidiOut.SendShortMessage((forceTrackAsChannel ? i : (midiEvent.Channel - 1)) + (int)command, midiEvent.Data1, /*command == MidiCommandCode.NoteOn ? (int)Mathf.Clamp(midiEvent.Data2 * volume, 0, 127) :*/ midiEvent.Data2);
                    }
                }

                if (ShortMessageEvent != null)
                {
                    ShortMessageEvent((forceTrackAsChannel ? i : (midiEvent.Channel - 1)) + (int)command, midiEvent.Data1, midiEvent.Data2);
                }

                switch (midiEvent.CommandCode)
                {
                case MidiCommandCode.AutoSensing:

                    break;

                case MidiCommandCode.ChannelAfterTouch:

                    break;

                case MidiCommandCode.ContinueSequence:

                    break;

                case MidiCommandCode.ControlChange:
                    //controlEvent = (midiEvent as ControlChangeEvent);

                    break;

                case MidiCommandCode.Eox:

                    break;

                case MidiCommandCode.KeyAfterTouch:

                    break;

                case MidiCommandCode.MetaEvent:
                    metaEvent = (midiEvent as MetaEvent);
                    switch (metaEvent.MetaEventType)
                    {
                    case MetaEventType.Copyright:
                        Debug.Log("Copyright : " + (metaEvent as TextEvent).Text);
                        break;

                    case MetaEventType.CuePoint:

                        break;

                    case MetaEventType.DeviceName:

                        break;

                    case MetaEventType.EndTrack:

                        break;

                    case MetaEventType.KeySignature:
                        keyMajorMinor = (metaEvent as KeySignatureEvent).MajorMinor;
                        Debug.Log("MAJOR or MINOR: " + keyMajorMinor);
                        keySharpsFlats = (metaEvent as KeySignatureEvent).SharpsFlats;
                        Debug.Log("SIGNATURE : " + keySharpsFlats);
                        break;

                    case MetaEventType.Lyric:

                        break;

                    case MetaEventType.Marker:

                        break;

                    case MetaEventType.MidiChannel:

                        break;

                    case MetaEventType.MidiPort:

                        break;

                    case MetaEventType.ProgramName:
                        Debug.Log("Program Name : " + (metaEvent as TextEvent).Text);
                        break;

                    case MetaEventType.SequencerSpecific:
                        //SequencerSpecificEvent sequencerEvent = midiEvent as SequencerSpecificEvent;

                        break;

                    case MetaEventType.SequenceTrackName:
                        Debug.Log("TrackName : " + (metaEvent as TextEvent).Text);
                        break;

                    case MetaEventType.SetTempo:
                        TempoEvent tempoEvent = (midiEvent as TempoEvent);
                        tempoOriginal = (float)tempoEvent.Tempo;
                        if (!tempoCustom)
                        {
                            tempo = tempoOriginal;
                        }
                        if (OnTempoChange != null)
                        {
                            OnTempoChange(tempo);
                        }
                        break;

                    case MetaEventType.SmpteOffset:

                        break;

                    case MetaEventType.TextEvent:

                        break;

                    case MetaEventType.TimeSignature:
                        TimeSignatureEvent signatureEvent = (midiEvent as TimeSignatureEvent);
                        timeSignatureNumerator    = signatureEvent.Numerator;
                        _timeSignatureDenominator = signatureEvent.Denominator;
                        timeSignatureDenominator  = (int)Mathf.Pow(2, _timeSignatureDenominator);
                        break;

                    case MetaEventType.TrackInstrumentName:
                        Debug.Log("Instrument Name : " + (metaEvent as TextEvent).Text);
                        break;

                    case MetaEventType.TrackSequenceNumber:

                        break;

                    default:

                        break;
                    }
                    break;

                case MidiCommandCode.NoteOn:

                    break;

                case MidiCommandCode.NoteOff:

                    break;

                case MidiCommandCode.PatchChange:

                    break;

                case MidiCommandCode.PitchWheelChange:

                    break;

                case MidiCommandCode.StartSequence:

                    break;

                case MidiCommandCode.StopSequence:

                    break;

                case MidiCommandCode.Sysex:

                    break;

                case MidiCommandCode.TimingClock:

                    break;
                }

                if (eventPos [i] >= tracks [i].Count - 1)
                {
                    endOfTrack [i] = true;
                    bool endOfFile = true;
                    for (int k = 0; k < tracks.Count; k++)
                    {
                        if (!endOfTrack [k])
                        {
                            endOfFile = false;
                            break;
                        }
                    }

                    if (endOfFile)
                    {
                        ticks = ticks - lastDeltaTicks;
                        time  = time - lastDeltaTime;
                        if (repeatBarSelection)
                        {
                            cancelUpdate = true;
                            SetBar(startBar, true);
                            return(false);
                        }
                        else
                        {
                            cancelUpdate = true;
                            midiFinished = true;
                            return(false);
                        }
                    }
                    break;
                }

                eventPos [i] = eventPos [i] == tracks [i].Count - 1 ? eventPos [i] : eventPos [i] + 1;
            }
        }
        return(true);
    }
Esempio n. 26
0
 public TimeSignatureEventLabel(TimeSignatureEvent timeSignatureEvent) : base(timeSignatureEvent)
 {
 }
Esempio n. 27
0
        private void CreateTrackZeroEvents(List<MidiEvent> trackZeroEvents, MidiFile midiFile, long startAbsoluteTime, long endAbsoluteTime, bool includeAllTrackEvents)
        {
            MetaEvent tempoEvent = null;
            MetaEvent keySignatureEvent = null;
            MetaEvent timeSignatureEvent = null;
            bool gotAStartTempo = false;
            bool gotAStartKeySig = false;
            bool gotAStartTimeSig = false;

            for (int track = 0; track < ((includeAllTrackEvents) ? midiFile.Tracks : 1); track++)
            {
                foreach (MidiEvent midiEvent in midiFile.Events[track])
                {
                    if ((midiEvent.AbsoluteTime >= startAbsoluteTime) && (midiEvent.AbsoluteTime < endAbsoluteTime))
                    {
                        bool exclude = false;
                        MetaEvent metaEvent = midiEvent as MetaEvent;
                        if (metaEvent != null)
                        {
                            if (metaEvent.MetaEventType == MetaEventType.EndTrack)
                            {
                                // we'll add our own
                                exclude = true;
                            }
                            if (metaEvent.AbsoluteTime == startAbsoluteTime)
                            {
                                switch (metaEvent.MetaEventType)
                                {
                                    case MetaEventType.SetTempo:
                                        gotAStartTempo = true;
                                        break;
                                    case MetaEventType.KeySignature:
                                        gotAStartKeySig = true;
                                        break;
                                    case MetaEventType.TimeSignature:
                                        gotAStartTimeSig = true;
                                        break;
                                    case MetaEventType.Marker:
                                        // already done this elsewhere
                                        exclude = true;
                                        break;
                                    case MetaEventType.TextEvent:
                                        // exclude if text events as markers is on
                                        exclude = settings.TextEventMarkers;
                                        break;
                                }
                            }
                        }
                        else
                        {
                            exclude = !includeAllTrackEvents;
                        }
                        if (!exclude)
                        {
                            AddMidiEvent(midiEvent, trackZeroEvents, endAbsoluteTime);
                        }

                    }
                    else if (midiEvent.AbsoluteTime < startAbsoluteTime)
                    {
                        // TODO: perhaps look out for a patch change too
                        MetaEvent metaEvent = midiEvent as MetaEvent;
                        if (metaEvent != null)
                        {
                            switch (metaEvent.MetaEventType)
                            {
                                case MetaEventType.TextEvent:
                                case MetaEventType.Copyright:
                                case MetaEventType.SequenceTrackName:
                                    //TextEvent te = (TextEvent)metaEvent;
                                    //trackZeroEvents.Add(new TextEvent(te.Text, metaEvent.MetaEventType, startAbsoluteTime));
                                    break;
                                case MetaEventType.KeySignature:
                                    KeySignatureEvent kse = (KeySignatureEvent)metaEvent;
                                    keySignatureEvent = new KeySignatureEvent(kse.SharpsFlats, kse.MajorMinor, startAbsoluteTime);
                                    break;
                                case MetaEventType.SetTempo:
                                    tempoEvent = new TempoEvent(((TempoEvent)metaEvent).MicrosecondsPerQuarterNote, startAbsoluteTime); ;
                                    break;
                                case MetaEventType.TimeSignature:
                                    TimeSignatureEvent tse = (TimeSignatureEvent)metaEvent;
                                    timeSignatureEvent = new TimeSignatureEvent(tse.Numerator, tse.Denominator, tse.TicksInMetronomeClick, tse.No32ndNotesInQuarterNote, startAbsoluteTime);
                                    break;
                                case MetaEventType.TrackSequenceNumber:
                                    // TODO: needed?
                                    break;
                                case MetaEventType.TrackInstrumentName:
                                case MetaEventType.Lyric:
                                case MetaEventType.CuePoint:
                                case MetaEventType.Marker:
                                case MetaEventType.SequencerSpecific:
                                case MetaEventType.DeviceName:
                                case MetaEventType.ProgramName:
                                case MetaEventType.SmpteOffset:
                                case MetaEventType.EndTrack:
                                    // ignore these
                                    break;
                                default:
                                    //System.Diagnostics.Debug.Assert(false, String.Format("Unexpected meta event type {0}", metaEvent));
                                    break;
                            }
                        }
                    }
                }
            }
            if ((tempoEvent != null) && (!gotAStartTempo))
                trackZeroEvents.Add(tempoEvent);
            if ((keySignatureEvent != null) && (!gotAStartKeySig))
                trackZeroEvents.Add(keySignatureEvent);
            if ((timeSignatureEvent != null) && (!gotAStartTimeSig))
                trackZeroEvents.Add(timeSignatureEvent);

            // add an end track marker
            trackZeroEvents.Sort(new MidiEventComparer());
            trackZeroEvents.Add(new MetaEvent(MetaEventType.EndTrack,0,trackZeroEvents[trackZeroEvents.Count-1].AbsoluteTime));
        }
Esempio n. 28
0
 protected bool Equals(TimeSignatureEvent other)
 {
     return base.Equals(other) && Numerator == other.Numerator && Denominator == other.Denominator;
 }
Esempio n. 29
0
        /// <summary>
        /// Generates the list of bar entities of a midi file
        /// </summary>
        /// <param name="base64encodedMidiFile"></param>
        /// <returns></returns>
        public static List <Bar> GetBarsOfSong(string base64encodedMidiFile, SongSimplification songSimplification)
        {
            List <Bar> retObj    = new List <Bar>();
            int        barNumber = 1;

            var ticksPerBeat        = GetTicksPerBeatOfSong(base64encodedMidiFile);
            var songDurationInTicks = GetSongDurationInTicks(base64encodedMidiFile);
            var timeSignatureEvents = GetEventsOfType(base64encodedMidiFile, MidiEventType.TimeSignature);
            var setTempoEvents      = GetEventsOfType(base64encodedMidiFile, MidiEventType.SetTempo);

            timeSignatureEvents = ConvertDeltaTimeToAccumulatedTime(timeSignatureEvents);
            var TempoEvents = QuantizeTempos(ConvertDeltaTimeToAccumulatedTime(setTempoEvents));

            //status
            TimeSignatureEvent currentTimeSignature = new TimeSignatureEvent
            {
                Numerator   = 4,
                Denominator = 4
            };

            if (timeSignatureEvents.Count > 0)
            {
                currentTimeSignature = (TimeSignatureEvent)timeSignatureEvents[0];
            }

            int currentTempo = 500000;

            int  timeSigIndex = 0;
            int  tempoIndex   = 0;
            long currentTick  = 0;

            while (currentTick < songDurationInTicks)
            {
                if (TempoEvents.Count > 0)
                {
                    currentTempo = (int)TempoEvents[tempoIndex].MicrosecondsPerQuarterNote;
                }
                long timeOfNextTimeSignatureEvent = songDurationInTicks;
                if (timeSignatureEvents.Count - 1 > timeSigIndex)
                {
                    timeOfNextTimeSignatureEvent = timeSignatureEvents[timeSigIndex + 1].DeltaTime;
                }
                long timeOfNextSetTempoEvent = songDurationInTicks;
                if (TempoEvents.Count - 1 > tempoIndex)
                {
                    timeOfNextSetTempoEvent = TempoEvents[tempoIndex + 1].DeltaTime;
                }

                long lastTickOfBarToBeAdded = currentTimeSignature.Numerator * ticksPerBeat + currentTick;

                while ((lastTickOfBarToBeAdded <= timeOfNextTimeSignatureEvent && lastTickOfBarToBeAdded <= timeOfNextSetTempoEvent) ||
                       (lastTickOfBarToBeAdded > songDurationInTicks))
                {
                    var timeSignature = new TimeSignature
                    {
                        Numerator   = currentTimeSignature.Numerator,
                        Denominator = currentTimeSignature.Denominator
                    };
                    var bar = new Bar
                    {
                        BarNumber = barNumber++,
                        TicksFromBeginningOfSong          = currentTick,
                        TimeSignature                     = timeSignature,
                        TempoInMicrosecondsPerQuarterNote = currentTempo
                    };
                    bar.HasTriplets = HasBarTriplets(songSimplification, bar);
                    retObj.Add(bar);
                    currentTick            += currentTimeSignature.Numerator * ticksPerBeat;
                    lastTickOfBarToBeAdded += currentTimeSignature.Numerator * ticksPerBeat;
                    if (currentTick >= songDurationInTicks)
                    {
                        break;
                    }
                }
                if (lastTickOfBarToBeAdded >= timeOfNextTimeSignatureEvent)
                {
                    timeSigIndex++;
                }
                if (lastTickOfBarToBeAdded >= timeOfNextSetTempoEvent)
                {
                    tempoIndex++;
                }
            }
            return(retObj);
        }
 protected bool Equals(TimeSignatureEvent other)
 {
     return(base.Equals(other) && Numerator == other.Numerator && Denominator == other.Denominator);
 }
Esempio n. 31
0
        static int Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("No midi file specified");
                return(-1);
            }

            string midiFilePath = args[0];

            if (!File.Exists(midiFilePath))
            {
                Console.WriteLine("Cannot find midi file {0}", midiFilePath);
                return(-1);
            }

            string outputFile = midiFilePath + ".spi";

            MidiFile midi = new MidiFile(midiFilePath);

            bool showMetaEvents    = true;
            bool showUnknownEvents = false;
            bool showCalculations  = false;

            int    ticksPerQuarterNote        = midi.DeltaTicksPerQuarterNote;
            double microsecondsPerQuarterNote = 500000f;

            using (var writer = new StreamWriter(outputFile, append: false))
            {
                writer.WriteLine("# Sonic Pi source code generated from {0}", Path.GetFileName(midiFilePath));

                if (showCalculations)
                {
                    writer.WriteLine("# Tracks: {0}", midi.Tracks);

                    for (int track = 0; track < midi.Tracks; ++track)
                    {
                        writer.WriteLine("# \tTrack {0} contains {1} events", track, midi.Events[track].Count());
                    }
                }

                writer.WriteLine();

                // always process first track...
                for (int track = 0; track < midi.Tracks; ++track)
                {
                    writer.WriteLine();
                    writer.WriteLine("# Track {0} ", track);

                    foreach (MidiEvent @event in midi.Events[track])
                    {
                        switch (@event.CommandCode)
                        {
                        case MidiCommandCode.NoteOn:
                        {
                            NoteOnEvent noteOn = @event as NoteOnEvent;

                            if (noteOn != null)
                            {
                                // accumulate notes played at the same time?
                                writer.WriteLine("play :{1} # {0}", noteOn.NoteNumber, noteOn.NoteName.Replace("#", "s"));

                                if (noteOn.DeltaTime > 0)
                                {
                                    writer.WriteLine("sleep {0}", DeltaTimeInSeconds(microsecondsPerQuarterNote, ticksPerQuarterNote, noteOn.DeltaTime));
                                }
                            }
                        }
                        break;

                        case MidiCommandCode.MetaEvent:

                            if (showMetaEvents)
                            {
                                MetaEvent meta = @event as MetaEvent;

                                if (meta != null)
                                {
                                    switch (meta.MetaEventType)
                                    {
                                    case MetaEventType.TimeSignature:
                                    {
                                        TimeSignatureEvent tse = meta as TimeSignatureEvent;

                                        writer.WriteLine("# {0}", tse.ToString());
                                    }
                                    break;

                                    case MetaEventType.SequenceTrackName:
                                    {
                                        TextEvent te = meta as TextEvent;

                                        writer.WriteLine("# Track Name: {0}", te.Text);
                                    }
                                    break;

                                    case MetaEventType.SetTempo:
                                    {
                                        TempoEvent te = meta as TempoEvent;

                                        microsecondsPerQuarterNote = te.MicrosecondsPerQuarterNote;
                                        writer.WriteLine("use_bpm {0}", Math.Floor(te.Tempo));
                                    }
                                    break;
                                    }
                                }
                            }
                            break;

                        default:

                            if (showUnknownEvents)
                            {
                                writer.WriteLine("# unknown command {0}", @event.ToString());
                            }
                            break;
                        }
                    }
                }
            }

            return(0);
        }