예제 #1
0
        public void CombineTracks()
        {
            var finalTrack = MergeTracks();
            var absEvents  = new MidiEvent[Tracks.Length][];

            for (int i = 0; i < Tracks.Length; i++)
            {
                absEvents[i] = new MidiEvent[Tracks[i].MidiEvents.Length];
                var totalDeltaTime = 0;
                for (int j = 0; j < Tracks[i].MidiEvents.Length; j++)
                {
                    absEvents[i][j]           = Tracks[i].MidiEvents[j];
                    totalDeltaTime           += absEvents[i][j].DeltaTime;
                    absEvents[i][j].DeltaTime = totalDeltaTime;
                }
            }

            var eventCount = 0;
            var delta      = 0;
            var nextdelta  = int.MaxValue;
            var counters   = new int[absEvents.Length];

            TypeUtils.ClearIntArray(counters);
            while (eventCount < finalTrack.MidiEvents.Length)
            {
                for (int x = 0; x < absEvents.Length; x++)
                {
                    while (counters[x] < absEvents[x].Length && absEvents[x][counters[x]].DeltaTime == delta)
                    {
                        finalTrack.MidiEvents[eventCount] = absEvents[x][counters[x]];
                        eventCount++;
                        counters[x]++;
                    }
                    if (counters[x] < absEvents[x].Length && absEvents[x][counters[x]].DeltaTime < nextdelta)
                    {
                        nextdelta = absEvents[x][counters[x]].DeltaTime;
                    }
                }
                delta     = nextdelta;
                nextdelta = int.MaxValue;
            }
            finalTrack.EndTime = finalTrack.MidiEvents[finalTrack.MidiEvents.Length - 1].DeltaTime;
            var deltaDiff = 0;

            for (int x = 0; x < finalTrack.MidiEvents.Length; x++)
            {
                var oldTime = finalTrack.MidiEvents[x].DeltaTime;
                finalTrack.MidiEvents[x].DeltaTime -= deltaDiff;
                deltaDiff = oldTime;
            }

            Tracks      = new MidiTrack[] { finalTrack };
            TrackFormat = MidiTrackFormat.SingleTrack;
        }
예제 #2
0
 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);
     }
 }
예제 #3
0
        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);
        }