public SimpleMidiMessage GetNext() { //If both lists are empty. if (Empty) { throw new NoMoreMusicException(); } //If _storage is empty or if the next object to play is in progressQueque. if (_storage.Count == 0 || (_partialQueue.Count != 0 && _partialQueue.Last().Timestamp <= _storage.Last().ToneStartTime)) { return(_partialQueue.PopLast()); } else //Get new message from _storage. { SingleBeatWithChannel beatWithChannel = _storage.PopLast(); //If the right channel is already assigned. if (beatWithChannel.InstrumentType == _channelInstruments[beatWithChannel.Channel]) { //X, Y reverse order as list should be in that order _partialQueue.MergeInsert(StopMidiMessage(beatWithChannel), CompareSimpleMidi); return(StartMidiMessage(beatWithChannel)); } else //If a channel needs to be allocated before playing. { _channelInstruments[beatWithChannel.Channel] = beatWithChannel.InstrumentType; _partialQueue.MergeInsert(StartMidiMessage(beatWithChannel), CompareSimpleMidi); _partialQueue.MergeInsert(StopMidiMessage(beatWithChannel), CompareSimpleMidi); return(ChangeChannelMidiMessage(beatWithChannel)); } } }
private SimpleMidiMessage StopMidiMessage(SingleBeatWithChannel beatWithChannel) { return(new SimpleMidiMessage(MakeMidiEvent(0x8, beatWithChannel.Channel, beatWithChannel.Tone, beatWithChannel.ToneVelocity), beatWithChannel.ToneEndTime)); }
private SimpleMidiMessage ChangeChannelMidiMessage(SingleBeatWithChannel beatWithChannel) { return(new SimpleMidiMessage(MakeMidiEvent(0xC, beatWithChannel.Channel, (byte)((int)beatWithChannel.InstrumentType & 0x7F), 0), beatWithChannel.ToneStartTime)); }