public void NoteOffImmediate(int channel, int note) { VoiceManager.VoiceNode node = voiceManager.registry[channel, note]; while (node != null) { node.Value.StopImmediately(); node = node.Next; } voiceManager.RemoveFromRegistry(channel, note); }
/// <summary> /// Attempts to stop a voice by putting it into its release phase. /// If there is no release phase defined the voice will stop immediately. /// </summary> /// <param name="channel">The channel of the voice.</param> /// <param name="note">The key of the voice.</param> public void NoteOff(int channel, int note) { if (holdPedal[channel]) { VoiceManager.VoiceNode node = voiceManager.registry[channel, note]; while (node != null) { node.Value.VoiceParams.noteOffPending = true; node = node.Next; } } else { VoiceManager.VoiceNode node = voiceManager.registry[channel, note]; while (node != null) { node.Value.Stop(); node = node.Next; } voiceManager.RemoveFromRegistry(channel, note); } }
/// <summary> /// Attempts to stop a voice by putting it into its release phase. /// If there is no release phase defined the voice will stop immediately. /// </summary> /// <param name="channel">The channel of the voice.</param> /// <param name="note">The key of the voice.</param> public void NoteOff(int channel, int note) { UnityMainThreadDispatcher.Instance().Enqueue(ThisWillBeExecutedOnTheMainThread(note, false)); if (synthChannels[channel].holdPedal) { VoiceManager.VoiceNode node = voiceManager.registry[channel, note]; while (node != null) { node.Value.VoiceParams.noteOffPending = true; node = node.Next; } } else { VoiceManager.VoiceNode node = voiceManager.registry[channel, note]; while (node != null) { node.Value.Stop(); node = node.Next; } voiceManager.RemoveFromRegistry(channel, note); } }
/// <summary> /// Starts a voice with the given key and velocity. /// </summary> /// <param name="channel">The midi channel this voice is on.</param> /// <param name="note">The key the voice will play in.</param> /// <param name="velocity">The volume of the voice.</param> public void NoteOn(int channel, int note, int velocity) { // Get the correct instrument depending if it is a drum or not Patch inst = bank.GetPatch(bankSelect[channel], programs[channel]); if (inst == null) { return; } // A NoteOn can trigger multiple voices via layers List <Patch> layers = new List <Patch>(); if (inst is MultiPatch) { ((MultiPatch)inst).FindPatches(channel, note, velocity, layers); if (layers.Count == 0) { return; } } else { layers.Add(inst); } // If a key with the same note value exists, stop it if (voiceManager.registry[channel, note] != null) { VoiceManager.VoiceNode node = voiceManager.registry[channel, note]; while (node != null) { node.Value.Stop(); node = node.Next; } voiceManager.RemoveFromRegistry(channel, note); } // Check exclusive groups for (int x = 0; x < layers.Count; x++) { bool notseen = true; for (int i = x - 1; i >= 0; i--) { if (layers[x].ExclusiveGroupTarget == layers[i].ExclusiveGroupTarget) { notseen = false; break; } } if (layers[x].ExclusiveGroupTarget != 0 && notseen) { LinkedListNode <Voice> node = voiceManager.activeVoices.First; while (node != null) { if (layers[x].ExclusiveGroupTarget == node.Value.Patch.ExclusiveGroup) { node.Value.Stop(); voiceManager.RemoveFromRegistry(node.Value); } node = node.Next; } } } // Assign a voice to each layer for (int x = 0; x < layers.Count; x++) { Voice voice = voiceManager.GetFreeVoice(); voice.Configure(channel, note, velocity, layers[x]); voiceManager.AddToRegistry(voice); voiceManager.activeVoices.AddLast(voice); voice.Start(); } }
/// <summary> /// Starts a voice with the given key and velocity. /// </summary> /// <param name="channel">The midi channel this voice is on.</param> /// <param name="note">The key the voice will play in.</param> /// <param name="velocity">The volume of the voice.</param> public void NoteOn(int channel, int note, int velocity) { // Get the correct instrument depending if it is a drum or not SynthParameters sChan = synthChannels[channel]; Patch inst = bank.GetPatch(sChan.bankSelect, sChan.program); if (inst == null) { return; } // A NoteOn can trigger multiple voices via layers int layerCount; if (inst is MultiPatch) { layerCount = ((MultiPatch)inst).FindPatches(channel, note, velocity, layerList); } else { layerCount = 1; layerList[0] = inst; } // If a key with the same note value exists, stop it if (voiceManager.registry[channel, note] != null) { VoiceManager.VoiceNode node = voiceManager.registry[channel, note]; while (node != null) { node.Value.Stop(); node = node.Next; } voiceManager.RemoveFromRegistry(channel, note); } // Check exclusive groups for (int x = 0; x < layerCount; x++) { bool notseen = true; for (int i = x - 1; i >= 0; i--) { if (layerList[x].ExclusiveGroupTarget == layerList[i].ExclusiveGroupTarget) { notseen = false; break; } } if (layerList[x].ExclusiveGroupTarget != 0 && notseen) { LinkedListNode <Voice> node = voiceManager.activeVoices.First; while (node != null) { if (layerList[x].ExclusiveGroupTarget == node.Value.Patch.ExclusiveGroup) { node.Value.Stop(); voiceManager.RemoveFromRegistry(node.Value); } node = node.Next; } } } // Assign a voice to each layer for (int x = 0; x < layerCount; x++) { Voice voice = voiceManager.GetFreeVoice(); if (voice == null)// out of voices and skipping is enabled { break; } voice.Configure(channel, note, velocity, layerList[x], synthChannels[channel]); voiceManager.AddToRegistry(voice); voiceManager.activeVoices.AddLast(voice); voice.Start(); } // Clear layer list for (int x = 0; x < layerCount; x++) { layerList[x] = null; } }