Esempio n. 1
0
        private static double CalculateTime(long absoluteTime, List <TempoEvent> tempos, List <double> cumulativeTime, int dtpq)
        {
            TempoEvent prev     = null;
            double     prevTime = 0;

            for (int i = 0; i < tempos.Count; i++)
            {
                if (tempos[i].AbsoluteTime <= absoluteTime)
                {
                    prev     = tempos[i];
                    prevTime = cumulativeTime[i];
                }
                else
                {
                    break;
                }
            }
            if (prev == null)
            {
                return(absoluteTime);
            }

            double deltaTime = prev.MicrosecondsPerQuarterNote / 1000d * (absoluteTime - prev.AbsoluteTime) / dtpq;

            return(prevTime + deltaTime);
        }
Esempio n. 2
0
        private static List <double> CalculateCumulativeTime(List <TempoEvent> tempos, int deltaTicksPerQuarter)
        {
            // Time is in miliseconds
            List <double> times = new List <double>(tempos.Count);

            TempoEvent last = null;

            foreach (TempoEvent te in tempos)
            {
                if (last == null)
                {
                    times.Add(te.AbsoluteTime);
                }
                else
                {
                    long   deltaTicks = te.AbsoluteTime - last.AbsoluteTime;
                    double deltaTime  = last.MicrosecondsPerQuarterNote / 1000d * deltaTicks / deltaTicksPerQuarter;

                    times.Add(times.Last() + deltaTime);
                }

                last = te;
            }
            return(times);
        }
Esempio n. 3
0
        public ulong GetTime(ulong ticks)
        {
            ulong      time     = 0;
            TempoEvent previous = new TempoEvent(0, Mid.MicrosecondsPerMinute / 120);
            TempoEvent next;

            int   index = -1;
            ulong t;

            while (ticks > 0)
            {
                try {
                    next = BPM[++index];
                } catch (ArgumentOutOfRangeException) {
                    next = new TempoEvent(ulong.MaxValue, 0);
                }

                t      = Math.Min(next.Time - previous.Time, ticks);
                ticks -= t;
                time  += t * previous.MicrosecondsPerBeat / Division.TicksPerBeat;

                previous = next;
            }

            return(time);
        }
        /// <summary>
        /// Builds the tempo list
        /// </summary>
        private void BuildTempoList()
        {
            var currentbpm = 120.00;
            var realtime   = 0.0;
            var reldelta   = 0;

            tempoEvents = new List <TempoEvent>();
            foreach (var ev in midiFile.Events[0])
            {
                reldelta += ev.DeltaTime;
                if (ev.CommandCode != MidiCommandCode.MetaEvent)
                {
                    continue;
                }
                var tempo = (MetaEvent)ev;

                if (tempo.MetaEventType != MetaEventType.SetTempo)
                {
                    continue;
                }
                var relativetime = (double)reldelta / ticksPerQuarter * (60000.0 / currentbpm);
                currentbpm = ((NAudio.Midi.TempoEvent)tempo).Tempo;
                realtime  += relativetime;
                reldelta   = 0;
                var tempo_event = new TempoEvent
                {
                    AbsoluteTime = tempo.AbsoluteTime,
                    RealTime     = realtime,
                    BPM          = currentbpm
                };
                tempoEvents.Add(tempo_event);
            }
        }
Esempio n. 5
0
        public ulong GetTicks(ulong time)
        {
            ulong ticks = 0;

            TempoEvent previous = new TempoEvent(0, Mid.MicrosecondsPerMinute / 120);
            TempoEvent next;

            int   index = -1;
            ulong t;

            while (time > 0)
            {
                try {
                    next = BPM[++index];
                } catch (IndexOutOfRangeException) {
                    next = new TempoEvent(ulong.MaxValue, 0);
                }

                t      = Math.Min(GetTime(next.Time - previous.Time), time);
                time  -= t;
                ticks += t * 1000 * Division.TicksPerBeat / previous.MicrosecondsPerBeat;                 // 1000 for microseconds unit

                previous = next;
            }

            return(ticks);
        }
Esempio n. 6
0
            public void TempoEvent()
            {
                var  ticks = 9843758u;
                uint tempo = 0xff_ff_ff;
                var  x     = new TempoEvent(ticks, tempo);
                var  y     = ReDeserialize(x);

                Assert.That(x.Ticks == y.Ticks);
                Assert.That(x.TickTempo == y.TickTempo);
            }
Esempio n. 7
0
        public List <TempoData> ReadTempoEvents(MidiEventCollection events)
        {
            var tempList = new List <TempoData>();

            foreach (var eventList in events)
            {
                foreach (var e in eventList)
                {
                    if (e is TempoEvent)
                    {
                        TempoEvent tempo = (e as TempoEvent);
                        tempList.Add(new TempoData((int)tempo.AbsoluteTime, (ulong)tempo.MicrosecondsPerQuarterNote));
                    }
                }
            }
            return(tempList);
        }
Esempio n. 8
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. 9
0
        public int getTempo()
        {
            // 120 BPM is the assumed default if no tempo events
            // are found in the midi data.
            int retTempo = 120;

            // There are 60000000 microseconds in a minute.

            // BUGBUG: can be decimal?
            // AWNSER: yes it can, but we will ignore it.

            // Loop through all the tracks
            for (int track = 0; track < m_data.Tracks; track++)
            {
                // For each MidiEvent in the track
                foreach (MidiEvent e in m_data[track])
                {
                    // Look for a MetaEvent
                    if (e.CommandCode == MidiCommandCode.MetaEvent)
                    {
                        // Found a MetaEvent
                        // Is the type TempEvent?
                        if (e is TempoEvent)
                        {
                            // Yes. Cast it.
                            TempoEvent n = (TempoEvent)e;

                            // Store the tempo value in BPM
                            retTempo = (int)n.Tempo;
                        }
                    }
                }
            }

            // Return
            return(retTempo);
        }
Esempio n. 10
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. 11
0
        static void Main(string[] args)
        {
            var strictMode = false;
            var mifi       = new MidiFile(@"lamourtoujours.mid", strictMode);

            MidiEventsByTick = mifi.Events.SelectMany(x => x).OrderBy(x => x.AbsoluteTime).
                               GroupBy(x => x.AbsoluteTime, x => x).ToDictionary(x => x.Key, x => x.ToArray());

            var otherevents = mifi.Events.SelectMany(x => x).OrderBy(x => x.AbsoluteTime).Where(x => !(x is NoteOnEvent || x is TempoEvent)).ToList();



            var MaxMidiTicks = MidiEventsByTick.Keys.Max();

            var timeSignature = mifi.Events[0].OfType <TimeSignatureEvent>().FirstOrDefault();

            int beatsPerBar  = timeSignature == null ? 4 : timeSignature.Numerator;
            int ticksPerBar  = timeSignature == null ? mifi.DeltaTicksPerQuarterNote * 4 : (timeSignature.Numerator * mifi.DeltaTicksPerQuarterNote * 4) / (1 << timeSignature.Denominator);
            int ticksPerBeat = ticksPerBar / beatsPerBar;

            //for (int n = 0; n < mf.Tracks; n++)
            //{
            //    foreach (var midiEvent in mf.Events[n])
            //    {
            //        if (!MidiEvent.IsNoteOff(midiEvent))
            //        {
            //            Console.WriteLine("{0} {1}", ToMBT(midiEvent.AbsoluteTime, mf.DeltaTicksPerQuarterNote, timeSignature), midiEvent);
            //        }
            //    }
            //}

            int sleeptime = 1;

            //Console.ReadKey();
            while (MidiTicks <= MaxMidiTicks)
            {
                Thread.Sleep(sleeptime);
                MidiEvent[] me = null;
                MidiEventsByTick.TryGetValue(MidiTicks, out me);
                MidiTicks++;
                if (me == null)
                {
                    continue;
                }

                foreach (MidiEvent item in me)
                {
                    Console.ForegroundColor = ConsoleColor.White;
                    if (item is TempoEvent)
                    {
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        TempoEvent te = (TempoEvent)item;

                        sleeptime = te.MicrosecondsPerQuarterNote / ticksPerBeat / 1000;
                    }
                    if (item is NoteOnEvent)
                    {
                        NoteOnEvent ne = (NoteOnEvent)item;
                        Console.ForegroundColor = ConsoleColor.Blue;
                        if (ne.OffEvent == null)
                        {
                            Console.ForegroundColor = ConsoleColor.Red;
                        }
                    }
                    Console.WriteLine(item);
                }
            }
        }
Esempio n. 12
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. 14
0
        static void Main(string[] args)
        {
            MidiFile file = new MidiFile(args[0]);
            Dictionary <string, char> NoteToKey = new Dictionary <string, char> // There should be a simpler (thats a word) way of doing this, but I don't know enough yet to know about it.
            {
                { "G1", '1' },
                { "A1", '2' },
                { "B1", '3' },
                { "C2", '4' },
                { "D2", '5' },
                { "E2", '6' },
                { "F2", '7' },
                { "G2", '8' },
                { "A2", '9' },
                { "A#2", '(' },
                { "B2", '0' },
                { "C3", 'q' },
                { "C#3", 'Q' },
                { "D3", 'w' },
                { "D#3", 'W' },
                { "F3", 'r' },
                { "G3", 't' },
                { "G#3", 'T' },
                { "A3", 'y' },
                { "A#3", 'Y' },
                { "B3", 'u' },
                { "C4", 'i' },
                { "C#4", 'I' },
                { "D4", 'o' },
                { "D#4", 'O' },
                { "E4", 'p' },
                { "E#4", 'P' },
                { "F4", 'a' },
                { "G4", 's' },
                { "G#4", 'S' },
                { "A4", 'd' },
                { "A#4", 'D' },
                { "B4", 'f' },
                { "C5", 'g' },
                { "C#5", 'G' },
                { "D5", 'h' },
                { "D#5", 'H' },
                { "E5", 'j' },
                { "E#5", 'J' },
                { "F5", 'k' },
                { "G5", 'l' },
                { "G#5", 'L' },
                { "A5", 'z' },
                { "A#5", 'Z' },
                { "B5", 'x' },
                { "C6", 'c' },
                { "C#6", 'C' },
                { "D6", 'v' },
                { "D#6", 'V' },
                { "E6", 'b' },
                { "E#6", 'B' },
                { "F6", 'n' },
                { "F#6", 'N' },
                { "G6", 'm' },
            };

            Console.Write("Enter track number (1-" + file.Events.Tracks.ToString() + ")");
            int Track          = int.Parse(Console.ReadLine());
            int additionalTime = 0;
            //file.Events.MidiFileType = 0;
            //TempoEvent Tempo;
            int oldType = file.Events.MidiFileType;

            file.Events.MidiFileType = 0;

            foreach (MidiEvent note in file.Events[0])                                               // Set the tempo
            {
                try { Tempo = (TempoEvent)note; Console.WriteLine("tempoevent"); break; } catch { }; // this will break variable tempo things, fix later
            }

            file.Events.MidiFileType = oldType;
            foreach (MidiEvent note in file.Events[Track])
            {
                try { Tempo = (TempoEvent)note; Console.WriteLine("tempoevent"); } catch { };
                if (note.CommandCode == MidiCommandCode.NoteOn)
                {
                    NoteOnEvent noteOn = (NoteOnEvent)note;
                    if (noteOn.NoteName.Length <= 3) // Note will never have a length of more than 3 if it is a melodic note.
                    {
                        Console.Write(("noteOn").PadRight(12));
                        Console.WriteLine(noteOn.NoteName);
                        if (NoteToKey.ContainsKey(noteOn.NoteName)) // Do a note scale down thing later since stuff like the mario theme doesnt like to work because the piano doesnt have enough keys
                        {
                            SendKeys.SendWait(ConvertKey(NoteToKey[noteOn.NoteName]));
                        }
                    }
                    Console.Write(note.DeltaTime.ToString().PadRight(12));
                    Console.Write(Tempo.MicrosecondsPerQuarterNote.ToString().PadRight(12));

                    int timeToSleep = (10000 / file.DeltaTicksPerQuarterNote);
                    Thread.Sleep(timeToSleep + additonalTime);   // convert ticks to ms then
                    if (note.DeltaTime != 0)
                    {
                        additonalTime = (10000 / note.DeltaTime);
                    }
                }
                else if (note.CommandCode == MidiCommandCode.NoteOff)
                {
                    // noteoff is handled by NAudio already so we can ignore it, and we dont need to hold keys down because that doesnt happen for the piano
                    //Thread.Sleep(Math.Abs(note.DeltaTime / ( file.DeltaTicksPerQuarterNote / 4 )));
                } //else if ( note.CommandCode == )
            }
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
Esempio n. 15
0
        public List <MidiNote> ReadMidiEvents(double timeFromStartMS)
        {
            List <MidiNote> notes = null;

            try
            {
                EndMidiEvent = false;
                if (midifile != null)
                {
                    if (NextPosEvent < MidiSorted.Count)
                    {
                        // The BPM measures how many quarter notes happen in a minute. To work out the length of each pulse we can use the following formula:
                        // Pulse Length = 60 / (BPM * PPQN)
                        // Calculate current pulse to play
                        CurrentPulse += Convert.ToInt64((timeFromStartMS - LastTimeFromStartMS) / PulseLengthMs);

                        LastTimeFromStartMS = timeFromStartMS;

                        // From the last position played
                        for (int currentPosEvent = NextPosEvent; currentPosEvent < MidiSorted.Count; currentPosEvent++)
                        {
                            TrackMidiEvent trackEvent = MidiSorted[currentPosEvent];
                            if (Quantization != 0)
                            {
                                trackEvent.AbsoluteQuantize = ((trackEvent.Event.AbsoluteTime + Quantization / 2) / Quantization) * Quantization;
                            }
                            else
                            {
                                trackEvent.AbsoluteQuantize = trackEvent.Event.AbsoluteTime;
                            }

                            //Debug.Log("ReadMidiEvents - timeFromStartMS:" + Convert.ToInt32(timeFromStartMS) + " LastTimeFromStartMS:" + Convert.ToInt32(LastTimeFromStartMS) + " CurrentPulse:" + CurrentPulse + " AbsoluteQuantize:" + trackEvent.AbsoluteQuantize);

                            if (trackEvent.AbsoluteQuantize <= CurrentPulse)
                            {
                                NextPosEvent = currentPosEvent + 1;

                                if (trackEvent.Event.CommandCode == MidiCommandCode.NoteOn)
                                {
                                    if (((NoteOnEvent)trackEvent.Event).OffEvent != null)
                                    {
                                        NoteOnEvent noteon = (NoteOnEvent)trackEvent.Event;
                                        // if (noteon.OffEvent != null)
                                        {
                                            if (notes == null)
                                            {
                                                notes = new List <MidiNote>();
                                            }

                                            //Debug.Log(string.Format("Track:{0} NoteNumber:{1,3:000} AbsoluteTime:{2,6:000000} NoteLength:{3,6:000000} OffDeltaTime:{4,6:000000} ", track, noteon.NoteNumber, noteon.AbsoluteTime, noteon.NoteLength, noteon.OffEvent.DeltaTime));
                                            MidiNote note = new MidiNote()
                                            {
                                                AbsoluteQuantize = trackEvent.AbsoluteQuantize,
                                                Midi             = noteon.NoteNumber,
                                                Channel          = trackEvent.Event.Channel,
                                                Velocity         = noteon.Velocity,
                                                Duration         = noteon.NoteLength * PulseLengthMs,
                                                Length           = noteon.NoteLength,
                                                Patch            = PatchChanel[trackEvent.Event.Channel - 1],
                                                Drum             = (trackEvent.Event.Channel == 10),
                                                Delay            = 0,
                                                Pan = EnablePanChange ? PanChanel[trackEvent.Event.Channel - 1] : -1,
                                            };
                                            if (VolumeChanel[note.Channel - 1] != 127)
                                            {
                                                note.Velocity = Mathf.RoundToInt(((float)note.Velocity) * ((float)VolumeChanel[trackEvent.Event.Channel - 1]) / 127f);
                                            }
                                            notes.Add(note);
                                            if (LogEvents)
                                            {
                                                Debug.Log(BuildInfoTrack(trackEvent) + string.Format("{0,-4} {1,3:000} Lenght:{2} {3} Veloc:{4}",
                                                                                                     noteon.NoteName, noteon.NoteNumber, noteon.NoteLength, NoteLength(note), noteon.Velocity));
                                            }
                                        }
                                    }
                                }
                                else if (trackEvent.Event.CommandCode == MidiCommandCode.NoteOff)
                                {
                                    // no need, noteoff are associated with noteon
                                }
                                else if (trackEvent.Event.CommandCode == MidiCommandCode.ControlChange)
                                {
                                    ControlChangeEvent controlchange = (ControlChangeEvent)trackEvent.Event;
                                    if (controlchange.Controller == MidiController.Expression)
                                    {
                                        VolumeChanel[trackEvent.Event.Channel - 1] = controlchange.ControllerValue;
                                    }
                                    else if (controlchange.Controller == MidiController.MainVolume)
                                    {
                                        VolumeChanel[trackEvent.Event.Channel - 1] = controlchange.ControllerValue;
                                    }
                                    else if (controlchange.Controller == MidiController.Pan)
                                    {
                                        PanChanel[trackEvent.Event.Channel - 1] = controlchange.ControllerValue;
                                    }
                                    // Other midi event
                                    if (LogEvents)
                                    {
                                        Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Control {0} {1}", controlchange.Controller, controlchange.ControllerValue));
                                    }
                                }
                                else if (trackEvent.Event.CommandCode == MidiCommandCode.PatchChange)
                                {
                                    PatchChangeEvent change = (PatchChangeEvent)trackEvent.Event;
                                    PatchChanel[trackEvent.Event.Channel - 1] = trackEvent.Event.Channel == 10 ? 0 : change.Patch;
                                    if (LogEvents)
                                    {
                                        Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Patch   {0,3:000} {1}", change.Patch, PatchChangeEvent.GetPatchName(change.Patch)));
                                    }
                                }
                                else if (trackEvent.Event.CommandCode == MidiCommandCode.MetaEvent)
                                {
                                    MetaEvent meta = (MetaEvent)trackEvent.Event;
                                    switch (meta.MetaEventType)
                                    {
                                    case MetaEventType.SetTempo:
                                        if (EnableChangeTempo)
                                        {
                                            TempoEvent tempo = (TempoEvent)meta;
                                            //NewQuarterPerMinuteValue = tempo.Tempo;
                                            ChangeTempo(tempo.Tempo);
                                            //if (LogEvents)Debug.Log(BuildInfoTrack(trackEvent) + string.Format("SetTempo   {0} MicrosecondsPerQuarterNote:{1}", tempo.Tempo, tempo.MicrosecondsPerQuarterNote));
                                        }
                                        break;

                                    case MetaEventType.SequenceTrackName:
                                        if (!string.IsNullOrEmpty(SequenceTrackName))
                                        {
                                            SequenceTrackName += "\n";
                                        }
                                        SequenceTrackName += string.Format("T{0,2:00} {1}", trackEvent.IndexTrack, ((TextEvent)meta).Text);
                                        if (LogEvents)
                                        {
                                            Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Sequence   '{0}'", ((TextEvent)meta).Text));
                                        }
                                        break;

                                    case MetaEventType.ProgramName:
                                        ProgramName += ((TextEvent)meta).Text + " ";
                                        if (LogEvents)
                                        {
                                            Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Program   '{0}'", ((TextEvent)meta).Text));
                                        }
                                        break;

                                    case MetaEventType.TrackInstrumentName:
                                        if (!string.IsNullOrEmpty(TrackInstrumentName))
                                        {
                                            TrackInstrumentName += "\n";
                                        }
                                        TrackInstrumentName += string.Format("T{0,2:00} {1}", trackEvent.IndexTrack, ((TextEvent)meta).Text);
                                        if (LogEvents)
                                        {
                                            Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Text      '{0}'", ((TextEvent)meta).Text));
                                        }
                                        break;

                                    case MetaEventType.TextEvent:
                                        TextEvent += ((TextEvent)meta).Text + " ";
                                        if (LogEvents)
                                        {
                                            Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Sequence  '{0}'", ((TextEvent)meta).Text));
                                        }
                                        break;

                                    case MetaEventType.Copyright:
                                        Copyright += ((TextEvent)meta).Text + " ";
                                        if (LogEvents)
                                        {
                                            Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Copyright '{0}'", ((TextEvent)meta).Text));
                                        }
                                        break;

                                    case MetaEventType.Lyric:     // lyric
                                    case MetaEventType.Marker:    // marker
                                    case MetaEventType.CuePoint:  // cue point
                                    case MetaEventType.DeviceName:
                                        break;
                                    }
                                    //Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Meta {0} {1}", meta.MetaEventType, meta.ToString()));
                                }
                                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
                            {
                                // Out of time, exit for loop
                                break;
                            }
                        }

                        if (notes != null)
                        {
                            //if (CancelNextReadEvents)
                            //{
                            //    notes = null;
                            //    //Debug.Log("CancelNextReadEvents");
                            //    CancelNextReadEvents = false;
                            //}
                            //else
                            //if (notes.Count > 3 && (notes[notes.Count - 1].AbsoluteQuantize - notes[0].AbsoluteQuantize) > midifile.DeltaTicksPerQuarterNote * 8)
                            //{
                            //    //notes.RemoveRange(0, notes.Count - 1);
                            //    Debug.Log("--> Too much notes " + notes.Count + " timeFromStartMS:" + Convert.ToInt32(timeFromStartMS) + " Start:" + notes[0].AbsoluteQuantize + " Ecart:" + (notes[notes.Count - 1].AbsoluteQuantize - notes[0].AbsoluteQuantize) + " CurrentPulse:" + CurrentPulse);
                            //    //notes = null;
                            //}
                        }
                    }
                    else
                    {
                        // End of midi events
                        EndMidiEvent = true;
                    }
                }
            }
            catch (System.Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
            return(notes);
        }
Esempio n. 16
0
 protected bool Equals(TempoEvent other)
 {
     return base.Equals(other) && Tempo == other.Tempo;
 }
Esempio n. 17
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. 18
0
        /// <summary>
        /// Add a TrackMidiEvent to a list of MPTKEvent.
        /// </summary>
        /// <param name="mptkEvents">Must be alloc before the call</param>
        /// <param name="trackEvent"></param>
        /// <returns></returns>
        private void ConvertToEvent(List <MPTKEvent> mptkEvents, TrackMidiEvent trackEvent)
        {
            MPTKEvent midievent = null;

            switch (trackEvent.Event.CommandCode)
            {
            case MidiCommandCode.NoteOn:
                //if (((NoteOnEvent)trackEvent.Event).OffEvent != null)
            {
                NoteOnEvent noteon = (NoteOnEvent)trackEvent.Event;
                //Debug.Log(string.Format("Track:{0} NoteNumber:{1,3:000} AbsoluteTime:{2,6:000000} NoteLength:{3,6:000000} OffDeltaTime:{4,6:000000} ", track, noteon.NoteNumber, noteon.AbsoluteTime, noteon.NoteLength, noteon.OffEvent.DeltaTime));
                if (noteon.OffEvent != null)
                {
                    midievent = new MPTKEvent()
                    {
                        Track    = trackEvent.IndexTrack,
                        Tick     = trackEvent.AbsoluteQuantize,
                        Command  = MPTKCommand.NoteOn,
                        Value    = noteon.NoteNumber,
                        Channel  = trackEvent.Event.Channel - 1,
                        Velocity = noteon.Velocity,
                        Duration = Convert.ToInt64(noteon.NoteLength * MPTK_PulseLenght),
                        Length   = noteon.NoteLength,
                    };
                    mptkEvents.Add(midievent);
                    if (LogEvents && seek_ticks < 0)
                    {
                        string notename = (midievent.Channel != 9) ?
                                          String.Format("{0}{1}", NoteNames[midievent.Value % 12], midievent.Value / 12) : "Drum";
                        Debug.Log(BuildInfoTrack(trackEvent) + string.Format("NoteOn  {0,3:000}\t{1,-4}\tLenght:{2,5}\t{3}\tVeloc:{4,3}",
                                                                             midievent.Value, notename, noteon.NoteLength, NoteLength(midievent), noteon.Velocity));
                    }
                }
                else         // It's a noteoff
                {
                    if (KeepNoteOff)
                    {
                        midievent = new MPTKEvent()
                        {
                            Track    = trackEvent.IndexTrack,
                            Tick     = trackEvent.AbsoluteQuantize,
                            Command  = MPTKCommand.NoteOff,
                            Value    = noteon.NoteNumber,
                            Channel  = trackEvent.Event.Channel - 1,
                            Velocity = noteon.Velocity,
                            Duration = Convert.ToInt64(noteon.NoteLength * MPTK_PulseLenght),
                            Length   = noteon.NoteLength,
                        };
                        mptkEvents.Add(midievent);

                        if (LogEvents && seek_ticks < 0)
                        {
                            string notename = (midievent.Channel != 9) ?
                                              String.Format("{0}{1}", NoteNames[midievent.Value % 12], midievent.Value / 12) : "Drum";
                            Debug.Log(BuildInfoTrack(trackEvent) + string.Format("NoteOff {0,3:000}\t{1,-4}\tLenght:{2}", midievent.Value, notename, " Note Off"));
                        }
                    }
                }
            }
            break;

            case MidiCommandCode.NoteOff:
                if (KeepNoteOff)
                {
                    NoteEvent noteoff = (NoteEvent)trackEvent.Event;
                    //Debug.Log(string.Format("Track:{0} NoteNumber:{1,3:000} AbsoluteTime:{2,6:000000} NoteLength:{3,6:000000} OffDeltaTime:{4,6:000000} ", track, noteon.NoteNumber, noteon.AbsoluteTime, noteon.NoteLength, noteon.OffEvent.DeltaTime));
                    midievent = new MPTKEvent()
                    {
                        Track    = trackEvent.IndexTrack,
                        Tick     = trackEvent.AbsoluteQuantize,
                        Command  = MPTKCommand.NoteOff,
                        Value    = noteoff.NoteNumber,
                        Channel  = trackEvent.Event.Channel - 1,
                        Velocity = noteoff.Velocity,
                        Duration = 0,
                        Length   = 0,
                    };

                    mptkEvents.Add(midievent);

                    if (LogEvents && seek_ticks < 0)
                    {
                        string notename = (midievent.Channel != 9) ?
                                          String.Format("{0}{1}", NoteNames[midievent.Value % 12], midievent.Value / 12) : "Drum";
                        Debug.Log(BuildInfoTrack(trackEvent) + string.Format("NoteOff {0,3:000}\t{1,-4}\tLenght:{2}", midievent.Value, notename, " Note Off"));
                    }
                }
                break;

            case MidiCommandCode.PitchWheelChange:
                PitchWheelChangeEvent pitch = (PitchWheelChangeEvent)trackEvent.Event;
                midievent = new MPTKEvent()
                {
                    Track   = trackEvent.IndexTrack,
                    Tick    = trackEvent.AbsoluteQuantize,
                    Command = MPTKCommand.PitchWheelChange,
                    Channel = trackEvent.Event.Channel - 1,
                    Value   = pitch.Pitch,    // Pitch Wheel Value 0 is minimum, 0x2000 (8192) is default, 0x3FFF (16383) is maximum
                };
                mptkEvents.Add(midievent);
                if (LogEvents && seek_ticks < 0)
                {
                    Debug.Log(BuildInfoTrack(trackEvent) + string.Format("PitchWheelChange {0}", pitch.Pitch));
                }
                break;

            case MidiCommandCode.ControlChange:
                ControlChangeEvent controlchange = (ControlChangeEvent)trackEvent.Event;
                midievent = new MPTKEvent()
                {
                    Track      = trackEvent.IndexTrack,
                    Tick       = trackEvent.AbsoluteQuantize,
                    Command    = MPTKCommand.ControlChange,
                    Channel    = trackEvent.Event.Channel - 1,
                    Controller = (MPTKController)controlchange.Controller,
                    Value      = controlchange.ControllerValue,
                };

                //if ((MPTKController)controlchange.Controller != MPTKController.Sustain)
                mptkEvents.Add(midievent);

                // Other midi event
                if (LogEvents && seek_ticks < 0)
                {
                    Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Control {0} {1}", controlchange.Controller, controlchange.ControllerValue));
                }

                break;

            case MidiCommandCode.PatchChange:
                PatchChangeEvent change = (PatchChangeEvent)trackEvent.Event;
                midievent = new MPTKEvent()
                {
                    Track   = trackEvent.IndexTrack,
                    Tick    = trackEvent.AbsoluteQuantize,
                    Command = MPTKCommand.PatchChange,
                    Channel = trackEvent.Event.Channel - 1,
                    Value   = change.Patch,
                };
                mptkEvents.Add(midievent);
                if (LogEvents && seek_ticks < 0)
                {
                    Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Patch   {0,3:000} {1}", change.Patch, PatchChangeEvent.GetPatchName(change.Patch)));
                }
                break;

            case MidiCommandCode.MetaEvent:
                MetaEvent meta = (MetaEvent)trackEvent.Event;
                midievent = new MPTKEvent()
                {
                    Track   = trackEvent.IndexTrack,
                    Tick    = trackEvent.AbsoluteQuantize,
                    Command = MPTKCommand.MetaEvent,
                    Channel = trackEvent.Event.Channel - 1,
                    Meta    = (MPTKMeta)meta.MetaEventType,
                };

                switch (meta.MetaEventType)
                {
                case MetaEventType.EndTrack:
                    midievent.Info = "End Track";
                    break;

                case MetaEventType.TimeSignature:
                    AnalyzeTimeSignature(meta, trackEvent);
                    break;

                case MetaEventType.SetTempo:
                    if (EnableChangeTempo)
                    {
                        TempoEvent tempo = (TempoEvent)meta;
                        // Tempo change will be done in MidiFilePlayer
                        midievent.Duration = (long)tempo.Tempo;
                        MPTK_MicrosecondsPerQuarterNote = tempo.MicrosecondsPerQuarterNote;
                        fluid_player_set_midi_tempo(tempo.MicrosecondsPerQuarterNote);

                        // Force exit loop
                        if (LogEvents && seek_ticks < 0)
                        {
                            Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Meta     {0,-15} Tempo:{1} MicrosecondsPerQuarterNote:{2}", meta.MetaEventType, tempo.Tempo, tempo.MicrosecondsPerQuarterNote));
                        }
                    }
                    break;

                case MetaEventType.SequenceTrackName:
                    midievent.Info = ((TextEvent)meta).Text;
                    if (!string.IsNullOrEmpty(SequenceTrackName))
                    {
                        SequenceTrackName += "\n";
                    }
                    SequenceTrackName += string.Format("T{0,2:00} {1}", trackEvent.IndexTrack, midievent.Info);
                    break;

                case MetaEventType.ProgramName:
                    midievent.Info = ((TextEvent)meta).Text;
                    ProgramName   += midievent.Info + " ";
                    break;

                case MetaEventType.TrackInstrumentName:
                    midievent.Info = ((TextEvent)meta).Text;
                    if (!string.IsNullOrEmpty(TrackInstrumentName))
                    {
                        TrackInstrumentName += "\n";
                    }
                    TrackInstrumentName += string.Format("T{0,2:00} {1}", trackEvent.IndexTrack, midievent.Info);
                    break;

                case MetaEventType.TextEvent:
                    midievent.Info = ((TextEvent)meta).Text;
                    TextEvent     += midievent.Info + " ";
                    break;

                case MetaEventType.Copyright:
                    midievent.Info = ((TextEvent)meta).Text;
                    Copyright     += midievent.Info + " ";
                    break;

                case MetaEventType.Lyric:         // lyric
                    midievent.Info = ((TextEvent)meta).Text;
                    TextEvent     += midievent.Info + " ";
                    break;

                case MetaEventType.Marker:         // marker
                    midievent.Info = ((TextEvent)meta).Text;
                    TextEvent     += midievent.Info + " ";
                    break;

                case MetaEventType.CuePoint:         // cue point
                case MetaEventType.DeviceName:
                    break;
                }

                if (LogEvents && !string.IsNullOrEmpty(midievent.Info) && seek_ticks < 0)
                {
                    Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Meta     {0,-15} '{1}'", midievent.Meta, midievent.Info));
                }

                mptkEvents.Add(midievent);
                //Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Meta {0} {1}", meta.MetaEventType, meta.ToString()));
                break;

            default:
                // Other midi event
                if (LogEvents && seek_ticks < 0)
                {
                    Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Other    {0,-15} Not handle by MPTK", trackEvent.Event.CommandCode));
                }
                break;
            }
        }
Esempio n. 19
0
        private List <TrackMidiEvent> GetMidiEvents()
        {
            //Debug.Log("GetEvents");
            try
            {
                MPTK_TickLast = -1;
                int countTracks = 0;
                List <TrackMidiEvent> events = new List <TrackMidiEvent>();
                foreach (IList <MidiEvent> track in midifile.Events)
                {
                    countTracks++;
                    foreach (MidiEvent e in track)
                    {
                        try
                        {
                            //bool keepEvent = false;
                            if (e.AbsoluteTime > MPTK_TickLast)
                            {
                                MPTK_TickLast = e.AbsoluteTime;
                            }

                            switch (e.CommandCode)
                            {
                            case MidiCommandCode.NoteOn:
                                //Debug.Log("NoteOn "+ KeepNoteOff);
                                if (e.AbsoluteTime < MPTK_TickFirstNote || MPTK_TickFirstNote == -1)
                                {
                                    //Debug.Log("NoteOn MPTK_TickFirstNote" + e.AbsoluteTime);
                                    MPTK_TickFirstNote = e.AbsoluteTime;
                                }
                                //keepEvent = true;
                                break;
                            //case MidiCommandCode.NoteOff:
                            //    //Debug.Log("NoteOff "+ KeepNoteOff);
                            //    //keepEvent = true;
                            //    break;
                            //case MidiCommandCode.ControlChange:
                            //    //ControlChangeEvent ctrl = (ControlChangeEvent)e;
                            //    //Debug.Log("NoteOff");
                            //    keepEvent = true;
                            //    break;
                            //case MidiCommandCode.PatchChange:
                            //    keepEvent = true;
                            //    break;

                            case MidiCommandCode.MetaEvent:
                                MetaEvent meta = (MetaEvent)e;
                                switch (meta.MetaEventType)
                                {
                                case MetaEventType.SetTempo:
                                    TempoEvent tempo = (TempoEvent)meta;
                                    // Calculate the real duration
                                    if (EnableChangeTempo)
                                    {
                                        MPTK_DurationMS += ((e.AbsoluteTime - timeLastSegment) * (float)MPTK_PulseLenght);
                                        timeLastSegment  = e.AbsoluteTime;
                                    }
                                    fluid_player_set_midi_tempo(tempo.MicrosecondsPerQuarterNote);
                                    // Set the first tempo value find
                                    if (MPTK_InitialTempo < 0)
                                    {
                                        MPTK_InitialTempo = tempo.Tempo;
                                    }
                                    if (MPTK_MicrosecondsPerQuarterNote == 0)
                                    {
                                        MPTK_MicrosecondsPerQuarterNote = tempo.MicrosecondsPerQuarterNote;
                                    }
                                    //Debug.Log("Partial at: " + timeLastSegment + " " + MPTK_RealDuration + " " + Math.Round(TickLengthMs, 2) + " " + Math.Round(QuarterPerMinuteValue, 2));
                                    //Debug.Log("Tempo: " + ((TempoEvent)e).Tempo + " MPTK_InitialTempo:" + MPTK_InitialTempo);
                                    break;

                                case MetaEventType.TimeSignature:
                                    AnalyzeTimeSignature(meta);
                                    break;
                                }
                                //keepEvent = true;
                                break;
                            }

                            //if (keepEvent)
                            //{
                            TrackMidiEvent tmidi = new TrackMidiEvent()
                            {
                                IndexTrack = countTracks,
                                Event      = e//.Clone()
                            };

                            events.Add(tmidi);
                            //}
                        }
                        catch (System.Exception ex)
                        {
                            MidiPlayerGlobal.ErrorDetail(ex);
                            return(null);
                        }
                    }
                }
                //DebugMidiSorted(events);

                MPTK_TrackCount = countTracks;
                List <TrackMidiEvent> midievents = events.OrderBy(o => o.Event.AbsoluteTime).ToList();
                if (midievents.Count > 0)
                {
                    long lastAbsoluteTime = midievents[midievents.Count - 1].Event.AbsoluteTime;
                    MPTK_TickLast = lastAbsoluteTime;
                    //Debug.Log("End at: " + lastAbsoluteTime + " " + MPTK_RealDuration + " " + Math.Round(TickLengthMs, 2) + " " + Math.Round(QuarterPerMinuteValue, 2));
                }
                else
                {
                    MPTK_TickLast = 0;
                }

                if (MPTK_TickLast > 0 && EnableChangeTempo)
                {
                    // Calculate the real duration, cumul all segments with tempo change
                    MPTK_DurationMS += ((MPTK_TickLast - timeLastSegment) * (float)MPTK_PulseLenght);
                }
                return(midievents);
            }
            catch (System.Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
            return(null);
        }
Esempio n. 20
0
 public TempoEventLabel(TempoEvent tempoEvent) : base(tempoEvent)
 {
 }
Esempio n. 21
0
    private List <decimal> CalculateMidiRealTime()
    {
        var strictMode = false;
        var mf         = new MidiFile("Assets/Audios/Midi Files/AgainYui.mid", strictMode);

        mf.Events.MidiFileType = 0;

        List <MidiEvent> midiEvents = new List <MidiEvent>();
        List <long>      beatsList  = new List <long>();

        for (int n = 0; n < mf.Tracks; n++)
        {
            foreach (var midiEvent in mf.Events[n])
            {
                if (!MidiEvent.IsNoteOff(midiEvent))
                {
                    var  timeSignature = mf.Events[0].OfType <TimeSignatureEvent>().FirstOrDefault();
                    long beat          = GetBeat(midiEvent.AbsoluteTime, mf.DeltaTicksPerQuarterNote, timeSignature);
                    beatsList.Add(beat);
                    midiEvents.Add(midiEvent);
                    //Debug.Log("Beat: " + beat);

                    if (midiEvent is TempoEvent)
                    {
                        //Debug.Log("Absolute Time " + (midiEvent as TempoEvent).AbsoluteTime);
                    }
                }
            }
        }


        List <decimal> eventsTimesArr = new List <decimal>();


        decimal lastRealTime     = 0m;
        decimal lastAbsoluteTime = 0m;


        decimal currentMicroSecondsPerTick = 0m;

        for (int i = 0; i < midiEvents.Count; i++)
        {
            MidiEvent  midiEvent  = midiEvents[i];
            TempoEvent tempoEvent = midiEvent as TempoEvent;

            if (midiEvent.AbsoluteTime > lastAbsoluteTime)
            {
                lastRealTime += ((decimal)midiEvent.AbsoluteTime - lastAbsoluteTime) * currentMicroSecondsPerTick;
            }

            lastAbsoluteTime = midiEvent.AbsoluteTime;

            if (tempoEvent != null)
            {
                currentMicroSecondsPerTick = (decimal)tempoEvent.MicrosecondsPerQuarterNote / (decimal)mf.DeltaTicksPerQuarterNote;

                // Remove the tempo event to make events and timings match - index-wise
                // Do not add to the eventTimes
                midiEvents.RemoveAt(i);
                beatsList.RemoveAt(i);
                i--;
                continue;
            }

            // Add the time to the collection.
            eventsTimesArr.Add(lastRealTime / 1000000m);

            Debug.Log("Time: " + lastRealTime / 1000000m);
        }
        eventsBeatsArr = beatsList.ToArray();
        //Debug.Log("Length: " + eventsBeatsArr.Length);
        return(eventsTimesArr);
    }
Esempio n. 22
0
    public void FromVegas(Vegas vegas)
    {
        // select a midi file
        MessageBox.Show("请选择一个MIDI文件。");
        OpenFileDialog openFileDialog = new OpenFileDialog();

        openFileDialog.Filter           = "*.mid|*.mid|所有文件|*.*";
        openFileDialog.RestoreDirectory = true;
        openFileDialog.FilterIndex      = 1;
        if (openFileDialog.ShowDialog() == DialogResult.OK)
        {
            midiName = openFileDialog.FileName;
        }
        else
        {
            return;
        }

        MidiFile midi = new MidiFile(midiName);

        // generate statistics of each midi track
        String[] trackInfo       = new String[midi.Events.Tracks];
        int      ticksPerQuarter = midi.DeltaTicksPerQuarterNote;
        double   msPerQuarter    = 0;

        for (int i = 0; i < midi.Events.Tracks; i++)
        {
            String info1      = "轨道 " + i.ToString() + ": ";
            String info2      = "";
            int    notesCount = 0;
            String info3      = "起音 ";

            foreach (MidiEvent midiEvent in midi.Events[i])
            {
                if ((midiEvent is NoteEvent) && !(midiEvent is NoteOnEvent))
                {
                    NoteEvent noteEvent = midiEvent as NoteEvent;
                    if (notesCount == 0)
                    {
                        info3 = info3 + noteEvent.NoteName;
                    }
                    notesCount++;
                }
                if ((midiEvent is PatchChangeEvent) && info2.Length == 0)
                {
                    PatchChangeEvent patchEvent = midiEvent as PatchChangeEvent;
                    for (int j = 4; j < patchEvent.ToString().Split(' ').Length; j++)
                    {
                        info2 += patchEvent.ToString().Split(' ')[j];
                    }
                }
                if ((midiEvent is TempoEvent) && msPerQuarter == 0)
                {
                    TempoEvent tempoEvent = midiEvent as TempoEvent;
                    msPerQuarter = Convert.ToDouble(tempoEvent.MicrosecondsPerQuarterNote) / 1000;
                }
            }

            trackInfo[i] = info1 + info2 + "; 音符数: " + notesCount.ToString() + "; " + info3;
        }

        // select a video clip
        MessageBox.Show("请选择一个视频或图片素材片段。");
        openFileDialog.Filter           = "所有文件|*.*";
        openFileDialog.RestoreDirectory = true;
        openFileDialog.FilterIndex      = 1;
        if (openFileDialog.ShowDialog() == DialogResult.OK)
        {
            clipName = openFileDialog.FileName;
        }
        else
        {
            return;
        }
        Media  media       = new Media(clipName);
        double mediaLength = media.Length.ToMilliseconds();

        // start configuration
        Form2 configForm = new Form2();

        for (int i = 1; i < midi.Events.Tracks; i++)
        {
            configForm.comboBox1.Items.Add(trackInfo[i]);
        }
        configForm.comboBox1.SelectedIndex = 0;
        Application.Run(configForm);

        // apply condiguration
        for (int i = 1; i < midi.Events.Tracks; i++)
        {
            if (trackInfo[i] == configForm.comboBox1.SelectedItem.ToString())
            {
                midiTrack = i;
            }
        }
        sheetWidth    = int.Parse(configForm.width);
        sheetPosition = int.Parse(configForm.position);
        sheetGap      = int.Parse(configForm.gap);
        if (configForm.comboBox2.Text == "2/4")
        {
            sheetTempo = 2;
        }
        if (configForm.comboBox2.Text == "3/4")
        {
            sheetTempo = 3;
        }
        if (configForm.comboBox3.Text == "低音")
        {
            sheetCelf = 1;
        }

        // start processing MIDI
        VideoTrack[] noteTracks   = new VideoTrack[100];
        int          trackCount   = -1;
        int          trackPointer = 0;
        double       barStartTime = 0;
        double       barLength    = msPerQuarter * sheetTempo;

        foreach (MidiEvent midiEvent in midi.Events[midiTrack])
        {
            if (midiEvent is NoteOnEvent)
            {
                NoteEvent   noteEvent   = midiEvent as NoteEvent;
                NoteOnEvent noteOnEvent = midiEvent as NoteOnEvent;
                double      startTime   = midiEvent.AbsoluteTime * msPerQuarter / ticksPerQuarter;
                double      duration    = noteOnEvent.NoteLength * msPerQuarter / ticksPerQuarter;
                int         pitch       = noteEvent.NoteNumber;


                // next page
                while (startTime >= barStartTime + barLength)
                {
                    barStartTime = barStartTime + barLength;
                    trackPointer = 0;
                }

                // generate video events
                if (trackPointer > trackCount)
                {
                    trackCount             = trackCount + 1;
                    noteTracks[trackCount] = vegas.Project.AddVideoTrack();
                }

                VideoEvent videoEvent = noteTracks[trackPointer].AddVideoEvent(Timecode.FromMilliseconds(startTime), Timecode.FromMilliseconds(barStartTime + barLength - startTime));
                Take       take       = videoEvent.AddTake(media.GetVideoStreamByIndex(0));
                TrackEvent trackEvent = videoEvent as TrackEvent;
                trackEvent.Loop = true;

                TrackMotionKeyframe keyFrame = noteTracks[trackPointer].TrackMotion.InsertMotionKeyframe(Timecode.FromMilliseconds(startTime));
                keyFrame.Type      = VideoKeyframeType.Hold;
                keyFrame.Width     = sheetGap * 2 * vegas.Project.Video.Width / vegas.Project.Video.Height;
                keyFrame.Height    = sheetGap * 2;
                keyFrame.PositionX = -sheetWidth / 2 + sheetWidth / barLength * (startTime - barStartTime);
                int octave = pitch / 12;
                int line   = pitchMap[pitch % 12];
                keyFrame.PositionY = sheetPosition - sheetGap * 3 + (octave - 5) * sheetGap * 3.5 + line * sheetGap * 0.5 + sheetCelf * 12;

                trackPointer = trackPointer + 1;
            }
        }
    }
Esempio n. 23
0
        private static void GetIntervals(ref NAudio.Midi.MidiFile myMidi, TempoMap tempoMap)   //main function to print the dominant channel on each interval
        {
            //File.WriteAllText(@"output.txt", string.Empty); //empty file
            //var ourStream = File.CreateText(@"output.txt"); //start writing
            var ourStream = new List <string>();


            //for the Excel output

            string output = @"C:\Users\Yoni\Desktop\ThirdStringQuartet.xlsx";

            if (File.Exists(output))
            {
                File.Delete(output);
            }

            Excel.Application oApp;
            Excel.Worksheet   oSheet;
            Excel.Workbook    oBook;

            oApp   = new Excel.Application();
            oBook  = oApp.Workbooks.Add();
            oSheet = (Excel.Worksheet)oBook.Worksheets.Item[1];
            oSheet.Cells[1, 1].EntireRow.Font.Bold = true;
            oSheet.Cells[1, 1] = "Start Time";

            int lastDominantChannel = 0;    //in case of same dominant channel as before and tie between two channels now we will choose not to change
            var currentTempoEvent   = new TempoEvent(0, 0);

            long windowSize = 0;                                                       //length of time interval
            var  startEvent = new MidiEvent(myMidi.Events[0][0].AbsoluteTime, myMidi.Events[0][0].Channel,
                                            myMidi.Events[0][0].CommandCode);          //first event in each interval
            IDictionary <int, string> patchToChannel = new Dictionary <int, string>(); //to handle patches
            IDictionary <int, int>
            mainVolumeToChannel = new Dictionary <int, int>();                         //to handle main volume in each channel

            int k = 0;
            List <NoteOnEvent> noteOnCollection2 = new List <NoteOnEvent>();

            while (myMidi.Events[0][k].AbsoluteTime == 0)   //move all noteOns to the end of the 0 absolute time series
            {
                if (myMidi.Events[0][k].CommandCode.ToString() == "NoteOn")
                {
                    var noteOnEvent = (NoteOnEvent)myMidi.Events[0][k];
                    noteOnCollection2.Add(noteOnEvent);
                    myMidi.Events[0].RemoveAt(k);
                    k--;
                }

                k++;
            }

            int s = 0;

            foreach (var noteOnEvent in noteOnCollection2)
            {
                myMidi.Events[0].Insert(k + s, noteOnEvent);
                s++;
            }
            /*for excel!*/
            int counterForExcel = 2;
            var i         = 0;
            var endOfFile = false;

            while (true)    //main loop to move between time intervals. ends when endTrack event occours
            {
                var j        = i;
                var exitLoop = false;
                IDictionary <int, int>
                sumVelocityToChannel = new Dictionary <int, int>();                               //to handle sum of velocities per channel
                IDictionary <int, double>
                meanVelocityToChannel = new Dictionary <int, double>();                           //to handle average velocity per channel
                IDictionary <int, int>    numOfNoteOnsToChannel = new Dictionary <int, int>();    //to handle number of notes on each channel
                IDictionary <int, double> dominantValue         = new Dictionary <int, double>(); //to handle dominant value on each channel
                IDictionary <int, List <NoteOnEvent> >
                noteOnsToChannel =
                    new Dictionary <int, List <NoteOnEvent> >();                //to handle list of notes on each channel
                List <NoteOnEvent> noteOnCollection = new List <NoteOnEvent>(); // list of all noteOn events

                //inner loop to go through events inside an interval. Handle each relevant event with its own unique way
                while ((myMidi.Events[0][j].AbsoluteTime - startEvent.AbsoluteTime < windowSize) || windowSize == 0)
                {
                    switch (myMidi.Events[0][j].CommandCode.ToString())
                    {
                    case @"MetaEvent":
                        var metaEvent = (MetaEvent)myMidi.Events[0][j];
                        switch (metaEvent.MetaEventType.ToString())
                        {
                        case @"TimeSignature":
                            var timeSignatureEvent = (TimeSignatureEvent)metaEvent;
                            //change window size - change from 8 to 16 or 32 if too fast shifting (from 2 bars window to 4 or 8 bars)
                            windowSize = (long)Math.Round(myMidi.DeltaTicksPerQuarterNote *
                                                          ((double)timeSignatureEvent.Numerator /
                                                           (Math.Pow(2, timeSignatureEvent.Denominator))) * 4);
                            exitLoop = true;            //exit interval -> interval size changes
                            break;

                        case @"EndTrack":
                            endOfFile = true;           //reached end of midi file
                            break;

                        default:
                            break;
                        }

                        break;

                    case @"PatchChange":
                        var patchChangeEvent = (PatchChangeEvent)myMidi.Events[0][j];
                        if (!patchToChannel.ContainsKey(patchChangeEvent.Channel))
                        {
                            patchToChannel.Add(patchChangeEvent.Channel, GetPatchName(patchChangeEvent.Patch));
                        }
                        else
                        {
                            patchToChannel[patchChangeEvent.Channel] = GetPatchName(patchChangeEvent.Patch);
                        }
                        break;

                    case @"ControlChange":
                        var controlChangeEvent = (ControlChangeEvent)myMidi.Events[0][j];
                        if (controlChangeEvent.Controller == MidiController.MainVolume)
                        {
                            if (!mainVolumeToChannel.ContainsKey(controlChangeEvent.Channel))       //if key does not exist - create it
                            {
                                mainVolumeToChannel.Add(controlChangeEvent.Channel, controlChangeEvent.ControllerValue);
                            }
                            else
                            {
                                mainVolumeToChannel[controlChangeEvent.Channel] = controlChangeEvent.ControllerValue;
                                exitLoop = true;
                            }
                        }

                        break;

                    case @"NoteOn":
                        var noteOnEvent = (NoteOnEvent)myMidi.Events[0][j];
                        if (noteOnEvent.Velocity != 0)
                        {
                            if (!noteOnsToChannel.TryGetValue(noteOnEvent.Channel, out noteOnCollection))
                            {
                                noteOnCollection = new List <NoteOnEvent>();
                                noteOnsToChannel[noteOnEvent.Channel] = noteOnCollection;
                                dominantValue[noteOnEvent.Channel]    = 0D;
                            }
                            noteOnCollection.Add(noteOnEvent);
                            noteOnsToChannel[noteOnEvent.Channel]      = noteOnCollection;
                            numOfNoteOnsToChannel[noteOnEvent.Channel] = noteOnCollection.Count;


                            if (!sumVelocityToChannel.ContainsKey(noteOnEvent.Channel))       //if key does not exist - create it
                            {
                                sumVelocityToChannel.Add(noteOnEvent.Channel, noteOnEvent.Velocity);
                            }
                            else
                            {
                                sumVelocityToChannel[noteOnEvent.Channel] += noteOnEvent.Velocity;
                            }
                        }
                        break;

                    default:
                        break;
                    }

                    if (endOfFile)
                    {
                        break;
                    }

                    j++;

                    if (exitLoop)
                    {
                        break;
                    }
                }   //end of inner loop


                foreach (KeyValuePair <int, int> pair in sumVelocityToChannel)
                {
                    meanVelocityToChannel[pair.Key] =
                        (double)pair.Value /
                        (noteOnsToChannel[pair.Key].Count); //calculate avg velocity on each channel
                }

                var endEvent = new MidiEvent(1, 1, 0);    //the end event on the current interval. If reached end of file stop!

                if (endOfFile)
                {
                    endEvent = new MidiEvent(myMidi.Events[0][j].AbsoluteTime, myMidi.Events[0][j].Channel, myMidi.Events[0][j].CommandCode);
                }
                else
                {
                    endEvent = new MidiEvent(myMidi.Events[0][j - 1].AbsoluteTime, myMidi.Events[0][j - 1].Channel, myMidi.Events[0][j - 1].CommandCode);
                }

                string value  = ""; //neccessery for default patch and main volume
                int    value1 = 100;

                foreach (KeyValuePair <int, double> pair in meanVelocityToChannel)
                {
                    if (!endOfFile)
                    {
                        if (!dominantValue.ContainsKey(pair.Key))
                        {
                            dominantValue[pair.Key] = 0D;
                        }

                        if (!noteOnsToChannel.ContainsKey(pair.Key))
                        {
                            noteOnsToChannel[pair.Key] = null;
                        }

                        if (!numOfNoteOnsToChannel.ContainsKey(pair.Key))
                        {
                            numOfNoteOnsToChannel[pair.Key] = 0;
                        }

                        if (!mainVolumeToChannel.ContainsKey(pair.Key))
                        {
                            mainVolumeToChannel[pair.Key] = 0;
                        }
                    }
                }

                foreach (KeyValuePair <int, int> pair in mainVolumeToChannel)
                {
                    if (!endOfFile)
                    {
                        if (!dominantValue.ContainsKey(pair.Key))
                        {
                            dominantValue[pair.Key] = 0D;
                        }

                        if (!noteOnsToChannel.ContainsKey(pair.Key))
                        {
                            noteOnsToChannel[pair.Key] = null;
                        }

                        if (!numOfNoteOnsToChannel.ContainsKey(pair.Key))
                        {
                            numOfNoteOnsToChannel[pair.Key] = 0;
                        }

                        if (!meanVelocityToChannel.ContainsKey(pair.Key))
                        {
                            meanVelocityToChannel[pair.Key] = 0D;
                        }
                    }
                }

                foreach (KeyValuePair <int, double> pair in dominantValue)   //default patch and channel volume in case not given in the midi file
                {
                    if (!patchToChannel.TryGetValue(pair.Key, out value))
                    {
                        patchToChannel[pair.Key] = GetPatchName(0);
                    }

                    if (!mainVolumeToChannel.TryGetValue(pair.Key, out value1))
                    {
                        mainVolumeToChannel[pair.Key] = value1;
                    }
                }


                var orderdNumOfNoteOnsToChannel = OrderIDictionary <int>(numOfNoteOnsToChannel); //sort num of note Ons

                bool isEmpty;
                bool hasNotEmptyValues = false;
                using (var dictionaryEnum = noteOnsToChannel.GetEnumerator())
                {
                    isEmpty = !dictionaryEnum.MoveNext();
                }
                hasNotEmptyValues = noteOnsToChannel
                                    .Any(pair => pair.Value != null && pair.Value.Any());

                if (!isEmpty && hasNotEmptyValues) //make sure there is at least one noteOn on what we print
                {
                    IDictionary <int, double> dominant = new Dictionary <int, double>();
                    foreach (KeyValuePair <int, double> pair in dominantValue)   //The formula to change to adapt to different genres
                    {
                        try
                        {
                            if (orderdNumOfNoteOnsToChannel.First().Value -
                                orderdNumOfNoteOnsToChannel.Last().Value != 0)
                            {
                                dominant[pair.Key] = (0.45) * meanVelocityToChannel[pair.Key] +
                                                     (0.2) * (double)mainVolumeToChannel[pair.Key] +
                                                     (0.35) * (double)(((127 * (double)(numOfNoteOnsToChannel[pair.Key] - orderdNumOfNoteOnsToChannel.Last().Value)) / (orderdNumOfNoteOnsToChannel.First().Value - orderdNumOfNoteOnsToChannel.Last().Value))); //calculate dominant value for each channel
                            }
                            else                                                                                                                                                                                                                                 //all channels have same number of noteOns. Go only by two other values
                            {
                                dominant[pair.Key] = (0.5) * meanVelocityToChannel[pair.Key] +
                                                     (0.5) * (double)mainVolumeToChannel[pair.Key];
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e);
                            throw;
                        }
                    }

                    dominantValue = dominant;
                    var orderdDominantValue = OrderIDictionary <double>(dominantValue); //sort the dominance

                    if (orderdDominantValue.First().Key != lastDominantChannel)         //different dominant channels with the last interval
                    {
                        ourStream.Add(
                            $"from time {CalcFactor(startEvent.AbsoluteTime, tempoMap)}: Channel {orderdDominantValue.First().Key} ({patchToChannel[orderdDominantValue.First().Key]})");

                        //excel
                        oSheet.Cells[counterForExcel, 1]           = CalcFactor(startEvent.AbsoluteTime, tempoMap);
                        oSheet.Cells[counterForExcel, 1].Font.Bold = true;
                        oSheet.Cells[counterForExcel, 2]           = orderdDominantValue.First().Key;

                        int v = 2;
                        foreach (KeyValuePair <int, string> pair in patchToChannel)
                        {
                            string str = "";
                            if (!patchToChannel.TryGetValue(pair.Key, out str))
                            {
                                oSheet.Cells[counterForExcel, v] = 0;
                            }
                            else if (pair.Key.Equals(orderdDominantValue.First().Key))
                            {
                                oSheet.Cells[counterForExcel, v] = 1;
                            }
                            else
                            {
                                oSheet.Cells[counterForExcel, v] = 0;
                            }

                            v++;
                        }

                        counterForExcel++;
                        lastDominantChannel = orderdDominantValue.First().Key;
                    }
                }

                startEvent = myMidi.Events[0][j]; //change to j if need big time interval... define start event for next time interval
                i          = j;                   //include this if need the big time interval
                if (endOfFile)
                {
                    ourStream.Add($"Ending: {CalcFactor(endEvent.AbsoluteTime, tempoMap)}");
                    oSheet.Cells[counterForExcel, 1].Font.Bold = true;
                    oSheet.Cells[counterForExcel, 1]           = CalcFactor(endEvent.AbsoluteTime, tempoMap);
                    oSheet.Cells[counterForExcel, 2]           = "Ending";
                    break;
                }
            }

            //ourStream.Close();
            File.WriteAllLines(@"output.txt", ourStream);

            //for excel
            int q = 2;

            foreach (KeyValuePair <int, string> pair in patchToChannel)
            {
                oSheet.Cells[1, q]           = $"{pair.Key.ToString()}_({pair.Value})";
                oSheet.Cells[1, q].Font.Bold = true;
                q++;
            }

            oBook.SaveAs(output);
            oBook.Close();
            oApp.Quit();
        }
Esempio n. 24
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);
        }
Esempio n. 25
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. 26
0
        private void MidiThread()
        {
            while (MidiTicks <= MaxMidiTicks)
            {
                Thread.Sleep(midisleeptime);

                MidiEvent[] me = null;
                MidiEventsByTick.TryGetValue(MidiTicks, out me);
                MidiTicks++;
                if (me == null)
                {
                    continue;
                }

                foreach (MidiEvent item in me)
                {
                    if (item.Channel == 10)
                    {
                        continue;
                    }
                    if (item is TempoEvent)
                    {
                        TempoEvent te     = (TempoEvent)item;
                        int        interv = te.MicrosecondsPerQuarterNote / ticksPerBeat / 1000;
                        midisleeptime = interv == 0 ? 1 : interv;
                    }
                    if (item is NoteOnEvent)
                    {
                        NoteOnEvent ne = (NoteOnEvent)item;
                        PressedKey  pk = pressedKeys.Find(x => x.midiNoteNumber == ne.NoteNumber);

                        if (pk != null)
                        {
                            if (ne.Velocity == 0 || ne.CommandCode == MidiCommandCode.NoteOff) //Keyoff
                            {
                                Channels[pk.channel].State = ChannelState.KeyOff;
                                pressedKeys.Remove(pk);
                            }
                            continue;
                        }

                        int channel = GetChannel();

                        var freq = MidiNumberToFreq[ne.NoteNumber];
                        if (freq != 0)
                        {
                            pressedKeys.Add(new PressedKey()
                            {
                                key = Key.None, channel = channel, midiNoteNumber = ne.NoteNumber
                            });
                            Channels[channel].Freq = freq;
                            if (Channels[channel].State == ChannelState.Inactive)
                            {
                                Channels[channel].State = ChannelState.KeyOn;
                            }
                            else
                            {
                                Channels[channel].State = ChannelState.ReKeyOn;
                            }
                        }
                    }
                }
            }
            return;
        }
Esempio n. 27
0
    // Use this for initialization
    void Start()
    {
        // pass selected song id from menu
        songName      = ApplicationModel.selectedSongId;
        bassAvailable = ApplicationModel.bassAvailable;
        bassKey       = ApplicationModel.bassKey;
        Debug.Log("Bass available: " + bassAvailable + " key: " + bassKey);
        // init audio
        string prefix = fPrefix + Application.streamingAssetsPath + "/" + songName + "/";

        audioSources = GetComponents <AudioSource>();
        // for each possible track, fetch the audio file from streaming assets directory
        songAudio = audioSources[0];
        StartCoroutine(fetchAudioWWW(prefix + songName, songAudio));
        bassAudio = audioSources[1];
        StartCoroutine(fetchAudioWWW(prefix + songName + "Bass", bassAudio));
        snareAudio = audioSources[2];
        StartCoroutine(fetchAudioWWW(prefix + songName + "Snare", snareAudio));
        hihatAudio = audioSources[3];
        StartCoroutine(fetchAudioWWW(prefix + songName + "Hihat", hihatAudio));
        cymbalAudio = audioSources[4];
        StartCoroutine(fetchAudioWWW(prefix + songName + "Cymbal", cymbalAudio));
        tomAudio = audioSources[5];
        StartCoroutine(fetchAudioWWW(prefix + songName + "Tom", tomAudio));
        // init midi
        midi       = new MidiFile(Application.streamingAssetsPath + "/" + songName + "/" + songName + ".mid");
        tempo      = null;
        bpm        = 1;
        totalNotes = 0;
        foreach (MidiEvent note in midi.Events[0])
        {
            // at beginning, get bpm
            if (note is NAudio.Midi.TempoEvent)
            {
                tempo = (TempoEvent)note;
                secondsPerQuarterNote = (float)tempo.MicrosecondsPerQuarterNote / 1000000;
                bpm         = (int)Mathf.Round(1 / secondsPerQuarterNote * 60);
                startBuffer = secondsPerQuarterNote * 8;
                // use default roll time to find new one
                ROLL_TIME *= secondsPerQuarterNote * 2;
                Debug.Log("Playing song with bpm " + bpm);
            }
            // for actual note hits, report back information
            if (tempo != null && note.CommandCode == MidiCommandCode.NoteOn)
            {
                totalNotes++;
                NoteOnEvent tempNote = (NoteOnEvent)note;
                // check what quarter note we are on, use that to calculate realTime
                float quarterNoteOn = (float)note.AbsoluteTime / midi.DeltaTicksPerQuarterNote;
                float realTime      = quarterNoteOn * 60 / bpm;
                // create the note and assign its data
                if (noteInDifficulty(tempNote, quarterNoteOn) && (bassAvailable || tempNote.NoteName != "C3"))
                {
                    Note noteToAdd = new global::SongManager.Note();
                    noteToAdd.value     = tempNote.NoteName;
                    noteToAdd.timestamp = realTime + startBuffer;
                    noteToAdd.rollNote  = null;
                    notes.Add(noteToAdd);
                }
            }
        }
        Debug.Log("Total drum hits in song: " + totalNotes);
        realStartTime = Time.fixedTime + AUDIO_DELAY;
        // get roll sheet
        roll = GameObject.Find("Roll");
    }
Esempio n. 28
0
        /// <summary>
        /// Add a TrackMidiEvent to a list of MPTKEvent.
        /// </summary>
        /// <param name="mptkEvents">Must be alloc before the call</param>
        /// <param name="trackEvent"></param>
        /// <returns></returns>

        private bool ConvertToEventForNote(List <MPTKEvent> mptkEvents, TrackMidiEvent trackEvent)
        {
            bool      exitLoop  = false;
            MPTKEvent midievent = null;

            switch (trackEvent.Event.CommandCode)
            {
            case MidiCommandCode.NoteOn:

                if (((NoteOnEvent)trackEvent.Event).OffEvent != null)
                {
                    NoteOnEvent noteon = (NoteOnEvent)trackEvent.Event;
                    //Debug.Log(string.Format("Track:{0} NoteNumber:{1,3:000} AbsoluteTime:{2,6:000000} NoteLength:{3,6:000000} OffDeltaTime:{4,6:000000} ", track, noteon.NoteNumber, noteon.AbsoluteTime, noteon.NoteLength, noteon.OffEvent.DeltaTime));
                    if (noteon.NoteLength > 0)
                    {
                        midievent = new MPTKEvent()
                        {
                            Tick     = trackEvent.AbsoluteQuantize,
                            Command  = MPTKCommand.NoteOn,
                            Value    = noteon.NoteNumber,
                            Channel  = trackEvent.Event.Channel - 1,
                            Velocity = noteon.Velocity,
                            Duration = noteon.NoteLength * TickLengthMs,
                            Length   = noteon.NoteLength,
                        };
                        //mptkEvents.Add(midievent);

                        // show playing note
                        //Debug.Log(midievent.Channel);
                        if (midievent.Channel == selectedChannel)
                        {
                            Kbd_PKeyGen.instance.ShowMidiNoteOn(noteon.NoteNumber);
                        }

                        if (LogEvents)
                        {
                            string notename = (midievent.Channel != 9) ?
                                              String.Format("{0}{1}", NoteNames[midievent.Value % 12], midievent.Value / 12) : "Drum";
                            Debug.Log(BuildInfoTrack(trackEvent) + string.Format("NoteOn  {0,3:000}\t{1,-4}\tLenght:{2,5}\t{3}\tVeloc:{4,3}",
                                                                                 midievent.Value, notename, noteon.NoteLength, NoteLength(midievent), noteon.Velocity));
                        }
                    }
                    else if (KeepNoteOff)
                    {
                        midievent = CreateNoteOffForNote(mptkEvents, trackEvent);
                    }
                }
                break;

            case MidiCommandCode.NoteOff:
                midievent = CreateNoteOffForNote(mptkEvents, trackEvent);
                break;

            case MidiCommandCode.ControlChange:

                ControlChangeEvent controlchange = (ControlChangeEvent)trackEvent.Event;
                midievent = new MPTKEvent()
                {
                    Tick       = trackEvent.AbsoluteQuantize,
                    Command    = MPTKCommand.ControlChange,
                    Channel    = trackEvent.Event.Channel - 1,
                    Controller = (MPTKController)controlchange.Controller,
                    Value      = controlchange.ControllerValue,
                };
                mptkEvents.Add(midievent);

                // Other midi event
                if (LogEvents)
                {
                    Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Control {0} {1}", controlchange.Controller, controlchange.ControllerValue));
                }

                break;

            case MidiCommandCode.PatchChange:
                PatchChangeEvent change = (PatchChangeEvent)trackEvent.Event;
                midievent = new MPTKEvent()
                {
                    Tick    = trackEvent.AbsoluteQuantize,
                    Command = MPTKCommand.PatchChange,
                    Channel = trackEvent.Event.Channel - 1,
                    Value   = change.Patch,
                };
                mptkEvents.Add(midievent);
                if (LogEvents)
                {
                    Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Patch   {0,3:000} {1}", change.Patch, PatchChangeEvent.GetPatchName(change.Patch)));
                }
                break;

            case MidiCommandCode.MetaEvent:
                MetaEvent meta = (MetaEvent)trackEvent.Event;
                midievent = new MPTKEvent()
                {
                    Tick    = trackEvent.AbsoluteQuantize,
                    Command = MPTKCommand.MetaEvent,
                    Channel = trackEvent.Event.Channel - 1,
                    Meta    = (MPTKMeta)meta.MetaEventType,
                };

                switch (meta.MetaEventType)
                {
                case MetaEventType.TimeSignature:
                    AnalyzeTimeSignature(meta);
                    break;

                case MetaEventType.SetTempo:
                    TempoEvent tempo = (TempoEvent)meta;
                    // Tempo change will be done in MidiFilePlayer
                    midievent.Duration = tempo.Tempo;
                    MPTK_MicrosecondsPerQuarterNote = tempo.MicrosecondsPerQuarterNote;
                    // Force exit loop
                    exitLoop = true;
                    break;

                case MetaEventType.SequenceTrackName:
                    midievent.Info = ((TextEvent)meta).Text;
                    if (!string.IsNullOrEmpty(SequenceTrackName))
                    {
                        SequenceTrackName += "\n";
                    }
                    SequenceTrackName += string.Format("T{0,2:00} {1}", trackEvent.IndexTrack, midievent.Info);
                    //if (LogEvents) Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Sequence   '{0}'", note.Info));
                    break;

                case MetaEventType.ProgramName:
                    midievent.Info = ((TextEvent)meta).Text;
                    ProgramName   += midievent.Info + " ";
                    //if (LogEvents) Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Program   '{0}'", note.Info));
                    break;

                case MetaEventType.TrackInstrumentName:
                    midievent.Info = ((TextEvent)meta).Text;
                    if (!string.IsNullOrEmpty(TrackInstrumentName))
                    {
                        TrackInstrumentName += "\n";
                    }
                    TrackInstrumentName += string.Format("T{0,2:00} {1}", trackEvent.IndexTrack, midievent.Info);
                    //if (LogEvents) Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Text      '{0}'", ((TextEvent)meta).Text));
                    break;

                case MetaEventType.TextEvent:
                    midievent.Info = ((TextEvent)meta).Text;
                    TextEvent     += midievent.Info + " ";
                    //if (LogEvents) Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Sequence  '{0}'", ((TextEvent)meta).Text));
                    break;

                case MetaEventType.Copyright:
                    midievent.Info = ((TextEvent)meta).Text;
                    Copyright     += midievent.Info + " ";
                    //if (LogEvents) Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Copyright '{0}'", ((TextEvent)meta).Text));
                    break;

                case MetaEventType.Lyric:         // lyric
                    midievent.Info = ((TextEvent)meta).Text;
                    break;

                case MetaEventType.Marker:         // marker
                case MetaEventType.CuePoint:       // cue point
                case MetaEventType.DeviceName:
                    break;
                }

                if (LogEvents && !string.IsNullOrEmpty(midievent.Info))
                {
                    Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Meta    {0,15} '{1}'", midievent.Meta, midievent.Info));
                }

                mptkEvents.Add(midievent);
                //Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Meta {0} {1}", meta.MetaEventType, meta.ToString()));
                break;

            default:
                // Other midi event
                if (LogEvents)
                {
                    Debug.Log(BuildInfoTrack(trackEvent) + string.Format("Other   {0,15} Not handle by MPTK", trackEvent.Event.CommandCode));
                }
                break;
            }

            return(exitLoop);
        }
Esempio n. 29
0
        /// <summary>
        /// Creates MusicTwo instance using midi file
        /// </summary>
        /// <param name="midiFile">Midi file to use</param>
        /// <param name="firstNoteMode">Use first note mode. If some notes appears at same time, use the first one, else the last</param>
        /// <returns>Created MusicTwo instance</returns>
        public static MusicTwo FromMidiFile(MidiFile midiFile, bool firstNoteMode)
        {
            double       tempo  = 0;
            List <Track> tracks = new List <Track>();

            for (int track_ = 1; track_ <= midiFile.Tracks; track_++)
            {
                Track track__ = new Track();
                foreach (var e in midiFile.Events)
                {
                    foreach (var ee in e)
                    {
                        if (ee is NoteEvent)
                        {
                            NoteEvent eee = (NoteEvent)ee;
                            if (eee is NoteOnEvent)
                            {
                                var  eeee = (NoteOnEvent)eee;
                                Note nt   = new Note();
                                nt.time   = (int)(eeee.AbsoluteTime / (double)midiFile.DeltaTicksPerQuarterNote * tempo);
                                nt.length = 0;
                                if (eeee.OffEvent != null)
                                {
                                    nt.length = (int)(eeee.NoteLength / (double)midiFile.DeltaTicksPerQuarterNote * tempo);
                                }
                                nt.number     = eeee.NoteNumber;
                                nt.instrument = track__.instrument;
                                if (eeee.Channel == track_)
                                {
                                    track__.notes.Add(nt);
                                }
                            }
                        }
                        if (ee is MetaEvent)
                        {
                            MetaEvent eee = (MetaEvent)ee;
                            if (eee.MetaEventType == MetaEventType.SetTempo)
                            {
                                TempoEvent eeee = (TempoEvent)eee;
                                tempo = eeee.MicrosecondsPerQuarterNote / 1000;
                            }
                        }

                        if (ee is PatchChangeEvent)
                        {
                            PatchChangeEvent eee = (PatchChangeEvent)ee;
                            if (eee.Channel == track_)
                            {
                                track__.instrument = eee.Patch;
                            }
                        }
                    }
                }
                tracks.Add(track__);
            }
            for (int i = 0; i < tracks.Count; i++)
            {
                for (int ii = 0; ii < tracks[i].notes.Count; ii++)
                {
                    if (tracks[i].notes[ii].length == 0)
                    {
                        tracks[i].notes.RemoveAt(ii);
                    }
                }
                if (tracks[i].notes.Count == 0)
                {
                    tracks.RemoveAt(i);
                    i--;
                }
            }



            MusicTwo music = new MusicTwo();

            for (int tracko = 0; tracko < tracks.Count; tracko++)
            {
                Track    track = tracks[tracko];
                TrackTwo nts   = new TrackTwo();
                NoteTwo  ntt   = new NoteTwo();
                ntt.Number = 0;
                ntt.Length = 0;
                nts.Notes.Add(ntt);
                Note lastNote = (new Note());
                Note en       = new Note();
                lastNote.time   = 0;
                lastNote.number = 0;
                lastNote.length = 0;
                en.time         = 0;
                en.number       = 0;
                en.length       = 0;
                for (int i = 0; i < track.notes.Last().time + track.notes.Last().length; i++)
                {
                    Note nowNote = en;
                    for (int ii = 0; ii < track.notes.Count; ii++)
                    {
                        if (i >= track.notes[ii].time && i <= track.notes[ii].time + track.notes[ii].length)
                        {
                            nowNote = track.notes[ii];
                            if (firstNoteMode)
                            {
                                goto c1;
                            }
                        }
                    }
c1:
                    if (nts.Notes.Last().Number == nowNote.number)
                    {
                        nts.Notes.Last().Length++;
                        continue;
                    }
                    else
                    {
                        NoteTwo nttt = new NoteTwo();
                        nttt.Number = nowNote.number;
                        nttt.Length = 1;
                        nttt.IsBass = isInstrumentBass(nowNote.instrument);
                        nts.Notes.Add(nttt);
                    }
                }
                music.tracks.Add(nts);
            }
            return(music);
        }
 protected bool Equals(TempoEvent other)
 {
     return(base.Equals(other) && Tempo == other.Tempo);
 }
Esempio n. 31
0
        /// <summary>
        /// Read midi event Tempo and Patch change from start
        /// </summary>
        /// <param name="timeFromStartMS"></param>
        /// <returns></returns>
        public List <MPTKEvent> ReadChangeFromStart(int position)
        {
            List <MPTKEvent> midievents = new List <MPTKEvent>();;

            try
            {
                if (midifile != null)
                {
                    if (position < 0 || position >= MidiSorted.Count)
                    {
                        position = MidiSorted.Count - 1;
                    }

                    for (int currentPosEvent = 0; currentPosEvent < position; currentPosEvent++)
                    {
                        TrackMidiEvent trackEvent = MidiSorted[currentPosEvent];
                        MPTKEvent      midievent  = null;
                        switch (trackEvent.Event.CommandCode)
                        {
                        case MidiCommandCode.ControlChange:
                            ControlChangeEvent controlchange = (ControlChangeEvent)trackEvent.Event;
                            midievent = new MPTKEvent()
                            {
                                Tick       = trackEvent.AbsoluteQuantize,
                                Command    = MPTKCommand.ControlChange,
                                Channel    = trackEvent.Event.Channel - 1,
                                Controller = (MPTKController)controlchange.Controller,
                                Value      = controlchange.ControllerValue,
                            };
                            break;

                        case MidiCommandCode.PatchChange:
                            PatchChangeEvent change = (PatchChangeEvent)trackEvent.Event;
                            midievent = new MPTKEvent()
                            {
                                Tick    = trackEvent.AbsoluteQuantize,
                                Command = MPTKCommand.PatchChange,
                                Channel = trackEvent.Event.Channel - 1,
                                Value   = change.Patch,
                            };
                            break;

                        case MidiCommandCode.MetaEvent:
                            MetaEvent meta = (MetaEvent)trackEvent.Event;
                            if (meta.MetaEventType == MetaEventType.SetTempo)
                            {
                                TempoEvent tempo = (TempoEvent)meta;
                                midievent = new MPTKEvent()
                                {
                                    Tick     = trackEvent.AbsoluteQuantize,
                                    Command  = MPTKCommand.MetaEvent,
                                    Channel  = trackEvent.Event.Channel - 1,
                                    Meta     = (MPTKMeta)meta.MetaEventType,
                                    Duration = tempo.Tempo,
                                };
                            }
                            break;
                        }
                        if (midievent != null)
                        {
                            midievents.Add(midievent);
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
            return(midievents);
        }