private void Form1_Load(object sender, EventArgs e)
 {
     _timedEventsManager = new TimedEventsManager(this,
                                                  new TimedEvent(1000, () => textBox1.Text += "First\n"),
                                                  new TimedEvent(5000, () => textBox1.Text += "Second\n"),
                                                  new TimedEvent(2000, () => textBox1.Text += "Third\n")
                                                  );
 }
Exemplo n.º 2
0
        internal static MidiFile Load(string filePath)
        {
            try
            {
                MMSong mmSong = JsonExtensions.DeserializeFromFileCompressed <MMSong>(filePath);

                if (mmSong.schemaVersion < 1 && mmSong.schemaVersion > 2)
                {
                    throw new FileFormatException("Error: This mmsong file format is not understood.");
                }
                // For now, just play the first available song.
                // if (mmSong.songs.Count != 1) throw new FileFormatException("Error: BMP currently only supports mmsong files with 1 song in them.");

                MMSong.Song song = mmSong.songs[0];

                MidiFile sequence = new MidiFile();
                sequence.Chunks.Add(new TrackChunk());
                sequence.TimeDivision = new TicksPerQuarterNoteTimeDivision(600);
                using (TempoMapManager tempoMapManager = sequence.ManageTempoMap()) tempoMapManager.SetTempo(0, Tempo.FromBeatsPerMinute(100));

                foreach (MMSong.Bard bard in song.bards)
                {
                    List <Note> notes   = new List <Note>();
                    bool        failure = false;

                    switch (bard.instrument)
                    {
                    case Instrument.Cymbal:
                    case Instrument.Trumpet:
                    case Instrument.Trombone:
                    case Instrument.Horn:
                    case Instrument.Tuba:
                    case Instrument.Saxophone:
                    case Instrument.Violin:
                    case Instrument.Viola:
                    case Instrument.Cello:
                    case Instrument.DoubleBass:
                        bard.sequence = bard.sequence.ToDictionary(
                            x => x.Key + 2,
                            x => x.Value);
                        break;

                    default:
                        break;
                    }

                    if (bard.sequence.Count % 2 == 0)
                    {
                        long lastTime = 0;
                        int  lastNote = 254;
                        foreach (KeyValuePair <long, int> sEvent in bard.sequence)
                        {
                            if (!failure)
                            {
                                if (lastNote == 254)
                                {
                                    if (sEvent.Value <= 60 && sEvent.Value >= 24 && ((sEvent.Key * 25 % 100) == 50 || (sEvent.Key * 25) % 100 == 0))
                                    {
                                        lastNote = sEvent.Value + 24;
                                        lastTime = sEvent.Key * 25;
                                    }
                                    else
                                    {
                                        failure = true;
                                    }
                                }
                                else
                                {
                                    if (sEvent.Value == 254)
                                    {
                                        long dur = (sEvent.Key * 25) - lastTime;
                                        notes.Add(new Note((SevenBitNumber)lastNote, dur, lastTime)
                                        {
                                            Channel     = (FourBitNumber)14,
                                            Velocity    = (SevenBitNumber)(int)127,
                                            OffVelocity = (SevenBitNumber)(int)0
                                        });
                                        lastNote = 254;
                                        lastTime = sEvent.Key * 25;
                                    }
                                    else
                                    {
                                        failure = true;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        failure = true;
                    }

                    if (failure)
                    {
                        throw new FileFormatException("Error: This mmsong file is corrupted");
                    }

                    TrackChunk currentChunk = new TrackChunk(new SequenceTrackNameEvent(bard.instrument.ToString()));
                    currentChunk.AddNotes(notes);
                    notes = null;
                    sequence.Chunks.Add(currentChunk);
                    currentChunk = null;
                }

                using (var manager = new TimedEventsManager(sequence.GetTrackChunks().First().Events))
                    manager.Events.Add(new TimedEvent(new MarkerEvent(), (sequence.GetDuration <MetricTimeSpan>().TotalMicroseconds / 1000) + 100));

                return(sequence);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Exemplo n.º 3
0
        public static Section ReadMidi(string filepath)
        {
            var midi = MidiFile.Read(filepath);

            var section = new Section(Path.GetFileNameWithoutExtension(filepath));

            foreach (var midiChunk in midi.Chunks)
            {
                if (!(midiChunk is TrackChunk chunk))
                {
                    continue;
                }

                var phrase = new Phrase();

                var programEvent = chunk.Events.OfType <ProgramChangeEvent>().FirstOrDefault();
                if (programEvent != null)
                {
                    phrase.Instrument = (MidiInstrument)(int)programEvent.ProgramNumber;
                }

                var nameEvent = chunk.Events.OfType <SequenceTrackNameEvent>().FirstOrDefault();
                if (nameEvent != null)
                {
                    phrase.Description = nameEvent.Text.Replace("\0", "");
                }

                var tempoEvent = chunk.Events.OfType <SetTempoEvent>().FirstOrDefault();
                if (tempoEvent != null)
                {
                    phrase.Bpm = Math.Round(1M / (tempoEvent.MicrosecondsPerQuarterNote / 60M) * 1000000M, 2);
                }

                var panEvent = chunk.Events
                               .OfType <ControlChangeEvent>().FirstOrDefault(x => x.ControlNumber == (SevenBitNumber)10);
                if (panEvent != null)
                {
                    phrase.Panning = (panEvent.ControlValue / 126M * 2M) - 1M;
                }


                using (var manager = new TimedEventsManager(chunk.Events))
                {
                    phrase.Elements = manager.Events
                                      .Where(x => x.Event is NoteOnEvent)
                                      .Select(GetNewPhraseElement)
                                      .ToList();

                    var offNotes = manager.Events
                                   .Where(x => x.Event is NoteOffEvent)
                                   .Select(x => new Tuple <decimal, int>(Convert.ToDecimal(x.Time) / 24M,
                                                                         ((NoteOffEvent)x.Event).NoteNumber - NoteOffset))
                                   .ToList();

                    foreach (var element in phrase.Elements)
                    {
                        var offNote = offNotes
                                      .FirstOrDefault(x => x.Item1 > element.Position && x.Item2 == element.Note);
                        if (offNote == null)
                        {
                            throw new ApplicationException("No off note found");
                        }
                        element.Duration = offNote.Item1 - element.Position;
                    }
                }

                phrase.IsDrums = chunk.Events.OfType <NoteOnEvent>().Any(x => x.Channel == (FourBitNumber)DrumChannel);

                phrase.PhraseLength = NoteHelper.GetTotalDuration(phrase);

                phrase.Elements = phrase.Elements.OrderBy(x => x.Position).ThenBy(x => x.Note).ToList();

                section.Phrases.Add(phrase);
            }

            if (section.Phrases.Count == 0)
            {
                throw new ApplicationException("Invalid Midi File");
            }

            // remove blank tempo phrase
            if (section.Phrases.Count > 1 &&
                section.Phrases[0].PhraseLength == 0 &&
                section.Phrases[0].Instrument == MidiInstrument.AcousticGrandPiano &&
                !section.Phrases[0].IsDrums)
            {
                section.Phrases.RemoveAt(0);
            }

            return(section);
        }
Exemplo n.º 4
0
        public List <List <ChartCommand> > ParseMidi()
        {
            List <List <ChartCommand> > commands = new List <List <ChartCommand> >();

            commands.Add(new List <ChartCommand>());
            commands.Add(new List <ChartCommand>());
            commands.Add(new List <ChartCommand>());
            int commandIndex = 0;

            MidiFile midiFile = MidiFile.Read(this.path);

            TempoMap tempoMap = midiFile.GetTempoMap();

            foreach (var x in midiFile.GetTrackChunks())
            {
                string trackName = "";

                using (TimedEventsManager timedEventsManager = x.ManageTimedEvents()) {
                    foreach (var e in timedEventsManager.Events)
                    {
                        if (e.Event is SequenceTrackNameEvent)
                        {
                            //Console.WriteLine(((SequenceTrackNameEvent)e.Event).Text);
                            trackName = ((SequenceTrackNameEvent)e.Event).Text;
                            switch (trackName)
                            {
                            case ("PART VOCALS"):
                                commandIndex = -1;
                                break;

                            case ("HARM1"):
                                commandIndex = 0;
                                break;

                            case ("HARM2"):
                                commandIndex = 1;
                                break;

                            case ("HARM3"):
                                commandIndex = 2;
                                break;
                            }
                        }
                        if (commandIndex != -1)
                        {
                            if (e.Event is NoteOnEvent)
                            {
                                if (((NoteOnEvent)e.Event).NoteNumber == 105)
                                {
                                    ChartCommand noteOnCommand =
                                        new ChartCommand()
                                    {
                                        Command         = "phrase_start",
                                        Parameter       = "",
                                        Tick            = (long)e.Time,
                                        OriginalCommand = "",
                                        TimeInMs        = e.TimeAs <MetricTimeSpan>(tempoMap).TotalMicroseconds / 1000d
                                    };
                                    commands[commandIndex].Add(noteOnCommand);
                                    if (commandIndex == 1)
                                    {
                                        commands[2].Add(noteOnCommand);
                                    }
                                }
                            }
                            if (e.Event is NoteOffEvent)
                            {
                                if (((NoteOffEvent)e.Event).NoteNumber == 105)
                                {
                                    ChartCommand noteOffCommand =
                                        new ChartCommand()
                                    {
                                        Command         = "phrase_end",
                                        Parameter       = "",
                                        Tick            = (long)e.Time,
                                        OriginalCommand = "",
                                        TimeInMs        = e.TimeAs <MetricTimeSpan>(tempoMap).TotalMicroseconds / 1000d
                                    };
                                    commands[commandIndex].Add(noteOffCommand);
                                    if (commandIndex == 1)
                                    {
                                        commands[2].Add(noteOffCommand);
                                    }
                                }
                            }
                        }

                        if (e.Event is Melanchall.DryWetMidi.Core.TextEvent)
                        {
                            if (trackName.StartsWith("HARM"))
                            {
                                string line = ((Melanchall.DryWetMidi.Core.TextEvent)e.Event).Text;
                                if (!line.StartsWith("[") && !line.EndsWith("]"))
                                {
                                    if (line != "+")
                                    {
                                        MetricTimeSpan metricTime = e.TimeAs <MetricTimeSpan>(tempoMap);
                                        double         timeInMs   = metricTime.TotalMicroseconds / 1000d;
                                        var            curCommand = new ChartCommand()
                                        {
                                            Tick            = (int)e.Time,
                                            TimeInMs        = timeInMs,
                                            Command         = "lyric",
                                            Parameter       = line,
                                            OriginalCommand = ""
                                        };
                                        commands[commandIndex].Add(curCommand);
                                    }
                                }
                            }
                        }

                        /*
                         * if (e.EventType == MidiEventType.Text)
                         * {
                         *  Console.WriteLine(((TextEvent)e).Text);
                         * }
                         */
                    }
                }
            }
            commands[0] = commands[0].OrderBy(o => o.TimeInMs).ToList();
            commands[1] = commands[1].OrderBy(o => o.TimeInMs).ToList();
            commands[2] = commands[2].OrderBy(o => o.TimeInMs).ToList();
            return(commands);
        }
Exemplo n.º 5
0
    void _ParseAuthoring()
    {
        _authoring.Clear();

        if (!_HasMidiFile())
        {
            return;
        }

        TrackChunk authTrack = _FindAuthoringTracks();

        if (authTrack == null)
        {
            return;
        }

        using (TimedEventsManager timedEventsManager = authTrack.ManageTimedEvents())
        {
            // Get timed events ordered by time
            TimedEventsCollection events = timedEventsManager.Events;

            AuthoringEvent newEvent = null;
            int            curNote  = -1;
            foreach (var midiEvent in events)
            {
                if (!(midiEvent.Event is SequenceTrackNameEvent) && !(midiEvent.Event is BaseTextEvent) && (midiEvent.Event is NoteOnEvent)) //ignore text events!
                {
                    newEvent         = new AuthoringEvent();
                    curNote          = (midiEvent.Event as NoteOnEvent).NoteNumber;
                    newEvent.NoteIdx = curNote - BaseInstrumentNote;

                    if (newEvent.NoteIdx < 0) //note was less than our BaseInstrumentNote, so ignore!
                    {
                        continue;
                    }

                    float startSecs = midiEvent.TimeAs <MetricTimeSpan>(_tempoMap).TotalMicroseconds / 1000000.0f;
                    newEvent.NoteOnBeat = SecsToBeats(startSecs);

                    _authoring.Add(newEvent);

                    //now find a nearby  note-off pair

                    /*foreach (var pairedEvent in events)
                     * {
                     * if (_IsNearEvent(pairedEvent, midiEvent) && (pairedEvent.Event is NoteOffEvent) && (curNote >= 0) && (curNote == (pairedEvent.Event as NoteOffEvent).NoteNumber)) //found paired note off
                     * {
                     *    float endSecs = pairedEvent.TimeAs<MetricTimeSpan>(_tempoMap).TotalMicroseconds / 1000000.0f;
                     *    newEvent.NoteOffBeat = SecsToBeats(endSecs);
                     *
                     *    if (newEvent.IsValid()) //done?
                     *    {
                     *       _authoring.Add(newEvent);
                     *
                     *       //Debug.Log("added event " + newEvent.NoteOnBeat + " -> " + newEvent.NoteOffBeat);
                     *    }
                     *
                     *    break;
                     * }
                     * }*/
                }
            }
        }

        Debug.Log("Found " + _authoring.Count + " authoring events!");
    }