Пример #1
0
        /// <summary>
        /// In MIDI Format 1, this would be the first track (index = 0).
        /// Otherwise Format 0: index = 0 and with
        /// Format 2, each track will essentially be like a Format 0 track.
        ///
        /// This method collects information from the 'tempo map' track such as
        ///
        /// - Tempo Information
        /// - SMPTE Offset
        /// - Time Signature
        /// - Key Signatuer
        /// - Sequencer Specific Data
        /// - System Exclusive Data (in tempo map)
        /// </summary>
        int GetTempoMap(int nTrackIndex, int nTrackOffset, int delta)
        {
            int  DELTA_Returned = delta;
            var  msg16          = FileHandle.Get16Bit(nTrackIndex, nTrackOffset);
            byte msg8           = (byte)(msg16 & 0xFF);

            CurrentStatus = msg16; // This is just an attempt at aligning running status.
            // var hexMsg = $"{msg16:X2}";
            if (msg16 >= 0xFF00 && msg16 <= 0xFF0C)
            {
                DELTA_Returned = FileHandle.Tracks[nTrackIndex].DeltaSeek(nTrackOffset);
                return(++DELTA_Returned);
            }
            switch (msg16)
            {
            // text
            case Stat16.SequenceNumber: // 0xFF00
            case Stat16.ChannelPrefix:  // 0xFF20
            case Stat16.PortMessage: /* 0xFF21 */ DELTA_Returned = FileHandle.Tracks[nTrackIndex].DeltaSeek(nTrackOffset); break;

            case Stat16.EndOfTrack: /* 0xFF2F */ DELTA_Returned = FileHandle.Tracks[nTrackIndex].Data.Length - 1; break;

            case Stat16.SetTempo: // 0xFF51
                var muspqn = FileHandle[ReaderIndex].ReadU24(nTrackOffset + 3);
                TempoMap.Push(muspqn, Division, CurrentTrackPulse);
                DELTA_Returned = FileHandle.Tracks[nTrackIndex].DeltaSeek(nTrackOffset);
                break;

            case Stat16.SMPTEOffset: // 0xFF54
                SMPTE.SetSMPTE(
                    FileHandle.Tracks[nTrackIndex].Data[nTrackOffset + 3],
                    FileHandle.Tracks[nTrackIndex].Data[nTrackOffset + 4],
                    FileHandle.Tracks[nTrackIndex].Data[nTrackOffset + 5],
                    FileHandle.Tracks[nTrackIndex].Data[nTrackOffset + 6],
                    FileHandle.Tracks[nTrackIndex].Data[nTrackOffset + 7]
                    );
                DELTA_Returned = FileHandle.Tracks[nTrackIndex].DeltaSeek(nTrackOffset);
                break;

            case Stat16.TimeSignature: // 0xFF58
                TimeSignature.SetSignature(
                    (int)this[nTrackIndex, nTrackOffset + 3],
                    (int)Math.Pow(-this[nTrackIndex, nTrackOffset + 4], 2),
                    (int)this[nTrackIndex, nTrackOffset + 5],
                    (int)this[nTrackIndex, nTrackOffset + 6]
                    );
                DELTA_Returned = FileHandle.Tracks[nTrackIndex].DeltaSeek(nTrackOffset);
                break;

            case Stat16.KeySignature: // 0xFF59
                KeySignature.SetSignature(
                    this[nTrackIndex, nTrackOffset + 3],
                    this[nTrackIndex, nTrackOffset + 4]);
                DELTA_Returned = FileHandle.Tracks[nTrackIndex].DeltaSeek(nTrackOffset);
                break;

            case Stat16.SequencerSpecific_70: // 0xFF70
            case Stat16.SequencerSpecific_71: // 0xFF71
            case Stat16.SequencerSpecific_72: // 0xFF72
            case Stat16.SequencerSpecific_73: // 0xFF73
            case Stat16.SequencerSpecific_74: // 0xFF74
            case Stat16.SequencerSpecific_75: // 0xFF75
            case Stat16.SequencerSpecific_76: // 0xFF76
            case Stat16.SequencerSpecific_77: // 0xFF77
            case Stat16.SequencerSpecific_78: // 0xFF78
            case Stat16.SequencerSpecific_79: // 0xFF79
            case Stat16.SequencerSpecific_7A: // 0xFF7A
            case Stat16.SequencerSpecific_7B: // 0xFF7B
            case Stat16.SequencerSpecific_7C: // 0xFF7C
            case Stat16.SequencerSpecific_7D: // 0xFF7D
            case Stat16.SequencerSpecific_7E: // 0xFF7E
            case Stat16.SequencerSpecific:    // 0xFF7F
                DELTA_Returned = FileHandle.Tracks[nTrackIndex].DeltaSeek(nTrackOffset);
                break;

            case Stat16.SystemExclusive:
                var pLastIndex = FileHandle[nTrackIndex].GetEndOfSystemExclusive(nTrackOffset);
                DELTA_Returned = pLastIndex;
                break;

            default:
            {
                if (FileHandle.Tracks[nTrackIndex].Data[nTrackOffset] < 0x80)
                {
                    CurrentStatus = CurrentRunningStatus16;
                    // Running Status
                    // int ExpandedRSE = CurrentTrackRunningStatus;// << 8;
                    int ExpandedRSE = CurrentRunningStatus8;// << 8;
                    int delta1      = -1;
                    if ((delta1 = Increment(nTrackOffset)) == -1)
                    {
                        int test = GetOffset(nTrackIndex, nTrackOffset);
                        Debug.Assert(false, string.Format("warning… {0:X2}, {1:X}|{1:N0}", ExpandedRSE, test));
                    }
                    else
                    {
                        DELTA_Returned = delta1;
                    }
                }
                else if (StatusQuery.IsMidiMessage(msg8))
                {
                    CurrentRunningStatus8  = msg8;
                    CurrentRunningStatus16 = msg16;
                    DELTA_Returned         = Increment(nTrackOffset + 1);
                    return(++DELTA_Returned);
                }
                else
                {
                    throw new FormatException("Bad format!\nThere is probably a problem with the Input File unless we made an error reading it!)");
                }
            }

            break;
            }
            return(++DELTA_Returned);
        }