internal MidiContext() { Channels = _InitChannels(); RunningStatus = 0; ChannelPrefix = 0xFF; MicroTempo = 0; TimeSignature = MidiTimeSignature.Default; }
/// <summary> /// Creates a new instance with the specified tempo /// </summary> /// <param name="timeSignature">The time signature</param> public MidiMessageMetaTimeSignature(MidiTimeSignature timeSignature) : base(0x58, new byte[] { timeSignature.Numerator, unchecked ((byte)(Math.Log(timeSignature.Denominator) / Math.Log(2))), timeSignature.MidiTicksPerMetronomeTick, timeSignature.ThirtySecondNotesPerQuarterNote }) { }
/// <summary> /// Process a message, adjusting the MIDI context /// </summary> /// <param name="message">The message to process</param> public void ProcessMessage(MidiMessage message) { var hasStatus = true; if (0 != message.Status) { RunningStatus = message.Status; } else { hasStatus = false; } int cn = (hasStatus ? message.Status & 0xF : (0XFF != ChannelPrefix ? ChannelPrefix : (RunningStatus & 0xF))); switch (RunningStatus & 0xF0) { case 0xC0: var mb = message as MidiMessageByte; Channels[cn].Patch = mb.Data1; break; case 0xD0: mb = message as MidiMessageByte; Channels[cn].ChannelPressure = mb.Data1; break; case 0x80: var mw = message as MidiMessageWord; Channels[cn].Notes[mw.Data1] = 0; break; case 0x90: mw = message as MidiMessageWord; Channels[cn].Notes[mw.Data1] = mw.Data2; break; case 0xA0: mw = message as MidiMessageWord; Channels[cn].KeyPressure[mw.Data1] = mw.Data2; break; case 0xB0: mw = message as MidiMessageWord; // respect send all notes off as necessary if (mw.Data1 >= 123 && mw.Data2 >= 127) { for (int i = 0; i < 128; ++i) { var b = Channels[cn].Notes[i]; if (0xFF != b) { Channels[cn].Notes[i] = 0; } } } Channels[cn].Controls[mw.Data1] = mw.Data2; break; case 0xE0: mw = message as MidiMessageWord; Channels[cn].PitchWheel = mw.Data; break; case 0xF0: switch (RunningStatus & 0xF) { case 0xF: var mbs = message as MidiMessageMeta; switch (mbs.Data1) { case 0x20: ChannelPrefix = mbs.Data[0]; break; case 0x51: if (BitConverter.IsLittleEndian) { MicroTempo = (mbs.Data[0] << 16) | (mbs.Data[1] << 8) | mbs.Data[2]; } else { MicroTempo = (mbs.Data[2] << 16) | (mbs.Data[1] << 8) | mbs.Data[0]; } break; case 0x58: TimeSignature = new MidiTimeSignature(mbs.Data[0], (byte)Math.Pow(mbs.Data[1], 2), mbs.Data[2], mbs.Data[3]); break; } break; } break; } }