Пример #1
0
        private void playMidi()
        {
            int       notesPlayed = 0;
            byte      tempChannel = 0;
            byte      tempVel     = 0;
            MidiEvent tempEvent;

            while (allowPlayMidi || midiSequence.GetTracks()[0].Events.Count > notesPlayed)
            {
                tempEvent = midiSequence.GetTracks()[0].Events.GetEvent(notesPlayed);
                Thread.Sleep((int)tempEvent.DeltaTime);
                MidiPlayer.Play(tempEvent);
                notesPlayed++;
            }
        }
Пример #2
0
        /// <summary>
        /// Creates a notechart from the specified midi path and the actual charttype
        /// (i.e. ExpertSingle from notes.mid).  Due to the overhead necessary to
        /// parse a midi file.  I am going to cram all midi->chart operations into
        /// one function call.
        /// This function uses the Toub midi parser which is much faster than Sanford,
        /// but will throw an exception on certian midi files.
        /// </summary>
        /// <param name="chartSelection">
        /// The information on which particular notechart to use.
        /// </param>
        /// <param name="chartInfo">The metadata on the chart.</param>
        /// <param name="BPMChanges">The list of BPM changes for this chart.</param>
        /// <returns>
        /// A filled out Notechart containing the needed information from the *.mid file.
        /// </returns>
        public static Notes ParseMidiInformationToub(ChartSelection chartSelection,
                                                     Info chartInfo,
                                                     List <BPMChange> BPMChanges)
        {
            Notes notechartToReturn = new Notes();

            notechartToReturn.instrument = chartSelection.instrument;
            notechartToReturn.difficulty = chartSelection.difficulty;

            // The following two switch's are used to get the proper midi terminology for
            // the selected track and difficulty.
            string instrumentPart = null;
            string greenKey       = null;
            string redKey         = null;
            string yellowKey      = null;
            string blueKey        = null;
            string orangeKey      = null;

            switch (chartSelection.instrument)
            {
            case "Single":
                instrumentPart = "PART GUITAR";
                break;

            case "DoubleGuitar":
                instrumentPart = "PART GUITAR COOP";
                break;

            case "DoubleBass":
                instrumentPart = "PART BASS";
                break;

            case "Drums":
                instrumentPart = "PART DRUMS";
                break;

            default:
                instrumentPart = "PART GUITAR";
                break;
            }

            switch (chartSelection.difficulty)
            {
            case "Expert":
                greenKey  = "C8";
                redKey    = "C#8";
                yellowKey = "D8";
                blueKey   = "D#8";
                orangeKey = "E8";
                break;

            case "Hard":
                greenKey  = "C7";
                redKey    = "C#7";
                yellowKey = "D7";
                blueKey   = "D#7";
                orangeKey = "E7";
                break;

            case "Medium":
                greenKey  = "C6";
                redKey    = "C#6";
                yellowKey = "D6";
                blueKey   = "D#6";
                orangeKey = "E6";
                break;

            case "Easy":
                greenKey  = "C5";
                redKey    = "C#5";
                yellowKey = "D5";
                blueKey   = "D#5";
                orangeKey = "E5";
                break;

            default:
                greenKey  = "C8";
                redKey    = "C#8";
                yellowKey = "D8";
                blueKey   = "D#8";
                orangeKey = "E8";
                break;
            }

            MidiSequence mySequence = MidiSequence.Import(chartSelection.directory + "\\notes.mid");

            MidiTrack[] myTracks = mySequence.GetTracks();
            chartInfo.resolution = mySequence.Division;

            MidiTrack trackToUse     = new MidiTrack();
            uint      totalTickValue = 0;

            // Go through each event in the first track (which contains the BPM changes)
            // and parse the resulting string.
            for (int i = 0; i < myTracks[0].Events.Count; i++)
            {
                Toub.Sound.Midi.MidiEvent currEvent = myTracks[0].Events[i];
                string   eventString      = currEvent.ToString();
                string[] splitEventString = eventString.Split('\t');

                // Since ticks are stored relative to each other (e.g. 300 ticks
                // until next note), we must maintain the total tick amout.
                totalTickValue += Convert.ToUInt32(splitEventString[1]);
                if (splitEventString[0] == "Tempo")
                {
                    // In midi files, bpm chages are stored as "microseconds per quarter note"
                    // and must be converted to BPM, and then into the non decimal format the game
                    // uses.
                    double currBPMDouble = 60000000 / Convert.ToDouble(splitEventString[3]);
                    uint   BPMToAdd      = (uint)(currBPMDouble * 1000);
                    BPMChanges.Add(new BPMChange(totalTickValue, BPMToAdd));
                }
            }

            trackToUse = new MidiTrack();
            // Find the specified instrument's track
            foreach (MidiTrack currTrack in myTracks)
            {
                string   trackHeader = currTrack.Events[0].ToString();
                string[] splitHeader = trackHeader.Split('\t');

                // -If we come across a "T1 GEMS" track, we're in GH1 territory.
                // -GH2/FoF has both PART BASS and PART RHYTHM (one or the other depending
                //  on the chart).
                if (((splitHeader[3] == instrumentPart) || (splitHeader[3] == "T1 GEMS")) ||
                    ((splitHeader[3] == "PART RHYTHM") && (instrumentPart == "PART BASS")))
                {
                    trackToUse = currTrack;
                }
            }

            totalTickValue = 0;
            uint currTickValue = 0;
            Note currNote      = new Note();
            bool blankNote     = true;

            // Scan through and record every note specific to the selected difficulty
            for (int i = 0; i < trackToUse.Events.Count; i++)
            {
                string   currEvent  = trackToUse.Events[i].ToString();
                string[] splitEvent = currEvent.Split('\t');
                currTickValue   = Convert.ToUInt32(splitEvent[1]);
                totalTickValue += currTickValue;

                // We need to specify wether a note is blank or not so we don't add
                // blank notes from other difficulties into the chart, but if we have
                // a filled out note, any nonzero tick value means we are moving to a
                // new note, so we must cut our ties and add this note to the chart.
                if ((currTickValue != 0) && !blankNote)
                {
                    notechartToReturn.notes.Add(currNote);
                    currNote  = new Note();
                    blankNote = true;
                }

                // The "0x64" I think means "not was hit."  There is another
                // set of notes that use "0x00" that all appear slightly after
                // the "0x64" notes.
                if ((splitEvent[0] == "NoteOn") && (splitEvent[4] != "0x00"))
                {
                    // Only consider notes within the octave our difficulty is in.
                    if ((splitEvent[3] == greenKey) || (splitEvent[3] == redKey) ||
                        (splitEvent[3] == yellowKey) || (splitEvent[3] == blueKey) ||
                        (splitEvent[3] == orangeKey))
                    {
                        // If it's a new note, we need to setup the tick value of it.
                        if (blankNote)
                        {
                            currNote.tickValue = totalTickValue;
                            blankNote          = false;
                        }
                        if (splitEvent[3] == greenKey)
                        {
                            currNote.addNote(0);
                        }
                        else if (splitEvent[3] == redKey)
                        {
                            currNote.addNote(1);
                        }
                        else if (splitEvent[3] == yellowKey)
                        {
                            currNote.addNote(2);
                        }
                        else if (splitEvent[3] == blueKey)
                        {
                            currNote.addNote(3);
                        }
                        else if (splitEvent[3] == orangeKey)
                        {
                            currNote.addNote(4);
                        }
                    }
                }
            }

            return(notechartToReturn);
        }