private void FillWorkingBuffer() { lock (this) { /*Break the process loop into sections representing the smallest timeframe before the midi controls need to be updated * the bigger the timeframe the more efficent the process is, but playback quality will be reduced.*/ var sampleIndex = 0; var anySolo = _isAnySolo; for (int x = 0; x < MicroBufferCount; x++) { if (_midiEventQueue.Length > 0) { for (int i = 0; i < _midiEventCounts[x]; i++) { var m = _midiEventQueue.RemoveLast(); if (m.IsMetronome) { NoteOff(_metronomeChannel, 37); NoteOn(_metronomeChannel, 37, 95); } else { ProcessMidiMessage(m.Event); } } } //voice processing loop var node = _voiceManager.ActiveVoices.First; //node used to traverse the active voices while (node != null) { var channel = node.Value.VoiceParams.Channel; // channel is muted if it is either explicitley muted, or another channel is set to solo but not this one. var isChannelMuted = _mutedChannels.ContainsKey(channel) || (anySolo && !_soloChannels.ContainsKey(channel)); node.Value.Process(sampleIndex, sampleIndex + MicroBufferSize * SynthConstants.AudioChannels, isChannelMuted); //if an active voice has stopped remove it from the list if (node.Value.VoiceParams.State == VoiceStateEnum.Stopped) { var delnode = node; //node used to remove inactive voices node = node.Next; _voiceManager.RemoveVoiceFromRegistry(delnode.Value); _voiceManager.ActiveVoices.Remove(delnode); _voiceManager.FreeVoices.AddFirst(delnode.Value); } else { node = node.Next; } } sampleIndex += MicroBufferSize * SynthConstants.AudioChannels; } TypeUtils.ClearIntArray(_midiEventCounts); } }
private void FillWorkingBuffer() { /*Break the process loop into sections representing the smallest timeframe before the midi controls need to be updated * the bigger the timeframe the more efficent the process is, but playback quality will be reduced.*/ var sampleIndex = 0; for (int x = 0; x < MicroBufferCount; x++) { if (MidiEventQueue.Length > 0) { for (int i = 0; i < MidiEventCounts[x]; i++) { var m = MidiEventQueue.RemoveLast(); ProcessMidiMessage(m.Event); } } //voice processing loop var node = _voiceManager.ActiveVoices.First; //node used to traverse the active voices while (node != null) { node.Value.Process(sampleIndex, sampleIndex + MicroBufferSize * AudioChannels); //if an active voice has stopped remove it from the list if (node.Value.VoiceParams.State == VoiceStateEnum.Stopped) { var delnode = node; //node used to remove inactive voices node = node.Next; _voiceManager.RemoveVoiceFromRegistry(delnode.Value); _voiceManager.ActiveVoices.Remove(delnode); _voiceManager.FreeVoices.AddFirst(delnode.Value); } else { node = node.Next; } } sampleIndex += MicroBufferSize * AudioChannels; } TypeUtils.ClearIntArray(MidiEventCounts); }