コード例 #1
0
    static private MIDIMetaEvent ReadMetaEvent(int deltaTicks)
    {
        int metaEventType = ReadByte();
        int dataLength    = ReadVariableLengthInt();

        switch (metaEventType)
        {
        case (int)MIDIMetaEventType.Tempo:
            MIDITempoEvent tempoEvent = new MIDITempoEvent();
            tempoEvent.deltaTicks = deltaTicks;
            tempoEvent.tempo      = ReadMultiByteInt((uint)dataLength);
            tempoEvent.dataLength = dataLength;
            return(tempoEvent);

        case (int)MIDIMetaEventType.Time_Signature:
            MIDITimeSignatureEvent timeSignatureEvent = new MIDITimeSignatureEvent();
            timeSignatureEvent.deltaTicks               = deltaTicks;
            timeSignatureEvent.numerator                = ReadByte();
            timeSignatureEvent.denominator              = (int)Mathf.Pow(2, ReadByte());
            timeSignatureEvent.ticksPerMetronomeClick   = ReadByte();
            timeSignatureEvent.numberOf32ndNotesPerBeat = ReadByte();
            timeSignatureEvent.dataLength               = dataLength;
            return(timeSignatureEvent);

        case (int)MIDIMetaEventType.Key_Signature:
            MIDIKeySignatureEvent keySignatureEvent = new MIDIKeySignatureEvent();
            keySignatureEvent.deltaTicks = deltaTicks;
            keySignatureEvent.key        = ReadByte();
            if (ReadByte() == 0)
            {
                keySignatureEvent.isMajor = true;
            }
            else
            {
                keySignatureEvent.isMajor = false;
            }
            keySignatureEvent.dataLength = dataLength;
            return(keySignatureEvent);

        default:
            ReadBytes((uint)dataLength);
            return(null);
        }
    }
コード例 #2
0
    static private void CalcEventTimestamps()
    {
        float elapsedTime    = 0.0f;
        float secondsPerTick = CalcSecondsPerTick(m_defaultMicrosecondsPerQuarterNote);

        List <MIDIEvent> nextEventList = new List <MIDIEvent>();

        foreach (MIDITrack track in m_song.tracks)
        {
            nextEventList.Add(track.events[0]);
        }

        MIDIEvent minNextEvent;

        do
        {
            minNextEvent = FindMinNextEvent(nextEventList);

            if (minNextEvent != null)
            {
                elapsedTime           += secondsPerTick * minNextEvent.deltaTicks;
                minNextEvent.timestamp = elapsedTime;

                CorrectDeltaTicksOfNextEvents(minNextEvent, nextEventList);
                ForwardMinNextEvent(minNextEvent, nextEventList);

                // adjust tempo if respective event occurs
                if (minNextEvent.GetType() == typeof(MIDITempoEvent))
                {
                    MIDITempoEvent tempoEvent = minNextEvent as MIDITempoEvent;
                    secondsPerTick = CalcSecondsPerTick(tempoEvent.tempo);
                }
            }
        }while (minNextEvent != null);

        m_song.duration = elapsedTime;
    }
コード例 #3
0
    static private void CalcMeasureTimestamps()
    {
        m_song.measureTimestamps = new List <float>();

        // GetMetaEvents
        List <MIDIEvent> metaEvents = new List <MIDIEvent>();

        foreach (MIDITrack track in m_song.tracks)
        {
            foreach (MIDIEvent midiEvent in track.events)
            {
                if (midiEvent.GetType().IsSubclassOf(typeof(MIDIMetaEvent)))
                {
                    metaEvents.Add(midiEvent);
                }
            }
        }

        // Sort MetaEvents by Timestamp
        metaEvents.Sort(new MIDIEventComparer());

        // calc timing metrics
        float microsecondsPerQuarterNote = m_defaultMicrosecondsPerQuarterNote;
        float beatsPerMeasure            = 4.0f;
        float beatNoteLength             = 1.0f / 4.0f;
        float quarterNotesPerBeat        = 4.0f * beatNoteLength;
        float secondsPerMeasure          = CalcSecondsPerMeasure(microsecondsPerQuarterNote, quarterNotesPerBeat, beatsPerMeasure);

        // iterate through measures
        for (float elapsedTime = 0.0f; elapsedTime < m_song.duration + secondsPerMeasure; elapsedTime += secondsPerMeasure)
        {
            List <MIDIEvent> metaEventsToRemove = new List <MIDIEvent>();
            foreach (MIDIEvent metaEvent in metaEvents)
            {
                if (metaEvent.timestamp <= elapsedTime)
                {
                    if (metaEvent.GetType() == typeof(MIDITempoEvent))
                    {
                        MIDITempoEvent tempoEvent = metaEvent as MIDITempoEvent;
                        microsecondsPerQuarterNote = tempoEvent.tempo;
                        secondsPerMeasure          = CalcSecondsPerMeasure(microsecondsPerQuarterNote, quarterNotesPerBeat, beatsPerMeasure);
                    }
                    else if (metaEvent.GetType() == typeof(MIDITimeSignatureEvent))
                    {
                        MIDITimeSignatureEvent timeSignatureEvent = metaEvent as MIDITimeSignatureEvent;
                        beatsPerMeasure     = timeSignatureEvent.numerator;
                        beatNoteLength      = 1.0f / timeSignatureEvent.denominator;
                        quarterNotesPerBeat = 4.0f * beatNoteLength;
                        secondsPerMeasure   = CalcSecondsPerMeasure(microsecondsPerQuarterNote, quarterNotesPerBeat, beatsPerMeasure);
                    }
                    metaEventsToRemove.Add(metaEvent);
                }
            }
            foreach (MIDIEvent metaEventToRemove in metaEventsToRemove)
            {
                metaEvents.Remove(metaEventToRemove);
            }

            m_song.measureTimestamps.Add(elapsedTime);
        }

        m_song.firstMeasureDuration = m_song.measureTimestamps[1] - m_song.measureTimestamps[0];
    }