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);
 }
예제 #2
0
 /// <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);
     }
 }
예제 #3
0
 /// <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);
     }
 }
예제 #4
0
        /// <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;
            }
        }