BroadcastStream() public method

public BroadcastStream ( float data, int offset, bool isEmptyData ) : void
data float
offset int
isEmptyData bool
return void
Ejemplo n.º 1
0
        protected virtual void OnAudioFilterRead(float[] data, int numChannels)
        {
            int dataLength = data.Length;

            _audioThreadStreamProxy.BroadcastStream(data, 0, false);

            if (!playThrough)
            {
                System.Array.Clear(data, 0, dataLength);
            }
        }
Ejemplo n.º 2
0
        void OnAudioFilterRead(float [] data, int numChannels)
        {
                        #if GAT_DEBUG
            if (_FiltersHandler.NbOfFilteredChannels != numChannels)
            {
                Debug.LogError("This player was setup for " + GATInfo.NbOfChannels + " channels output, current is " + numChannels + ". Disabling player.");
                _shouldDisable = true;
                return;
            }
                        #endif
            BufferedSample sample;
            bool           shouldRemove;
            int            i;
            int            dataLength;
            bool           noData = false;

            dataLength = data.Length;
            //*********************************************************************************************
            //First, we check if any samples in the scheduled queue need to be moved to the playing queue

            shouldRemove = false;
            sample       = _scheduledSamples.head.next;       // caching the first item of the linked queue: thread safe iteration

            if (sample != null)
            {
                double nextBufferDSPTime = AudioSettings.dspTime + GATInfo.AudioBufferDuration;

                while (sample != null)
                {
                    if (nextBufferDSPTime > sample.scheduledDspTime)                      //flag samples which need to be moved
                    {
                        sample.shouldBeRemoved = true;
                        shouldRemove           = true;
                        sample.OffsetInBuffer  = ( int )((sample.scheduledDspTime - AudioSettings.dspTime) * GATInfo.OutputSampleRate);
                    }
                    sample = sample.next;
                }

                if (shouldRemove)                  //move to playing queue
                {
                    lock ( _scheduledSamples )     // make sure no sample is added from the main thread whilst removing
                    {
                        _scheduledSamples.TrimAndKeepDiscarded(_discardedSamples);
                    }

                    _playingSamples.Enqueue(_discardedSamples);                       // no need to lock on the playing queue: it is only accessed by the audio thread
                }
            }

            //*************************************************************************
            //Second, we check the PlayImmediate queue

            lock ( _samplesToEnqueue )            //make sure no play immediate sample gets added by the main thread whilst we concatenate the 2 queues
            {
                if (_samplesToEnqueue.head.next != null)
                {
                    _playingSamples.Enqueue(_samplesToEnqueue);
                    _samplesToEnqueue.Clear();
                }
            }
            //***********************************************************
            //Third, we mix the samples of the Playing queue

            sample = _playingSamples.head.next;

            if (onPlayerWillMix != null)
            {
                onPlayerWillMix();
            }

            //Even if there is no samples to play, filters might add to the mix:
            if (sample == null)
            {
                noData = true;

                //Check tracks
                for (i = 0; i < _tracks.Count; i++)
                {
                    if (ReferenceEquals(_tracks[i], null) == false)
                    {
                        if (_tracks[i].FXAndMixTo(data))
                        {
                            noData = false;
                        }
                    }
                }

                //Check Master Filters
                if (_FiltersHandler.HasFilters)
                {
                    if (_FiltersHandler.ApplyFilters(data, 0, dataLength, noData))
                    {
                        noData = false;
                    }
                }

                //Broadcast stream
                _audioThreadStreamProxy.BroadcastStream(data, 0, noData);

                //Stop there.
                if (onPlayerDidMix != null)
                {
                    onPlayerDidMix();
                }

                return;
            }

            shouldRemove = false;

            while (sample != null)
            {
                if (sample.MixNow(data) == true)
                {
                    shouldRemove = true;
                }
                sample = sample.next;
            }

            //****************************************************
            //Then, we remove samples which ended and clip the mix if needed
            if (shouldRemove)
            {
                _playingSamples.TrimAndReleaseDiscarded();
            }

            //****************************************************
            //Now, we check and mix tracks
            for (i = 0; i < _tracks.Count; i++)
            {
                if (ReferenceEquals(_tracks[i], null) == false)
                {
                    _tracks[i].FXAndMixTo(data);
                }
            }

            //Filter the mix, includes a default gain filter which will clip if set so
            if (_FiltersHandler.HasFilters)
            {
                _FiltersHandler.ApplyFilters(data, 0, dataLength, false);
            }

            //****************************************************
            //Finally, we fire the last callback

            _audioThreadStreamProxy.BroadcastStream(data, 0, false);

            if (onPlayerDidMix != null)
            {
                onPlayerDidMix();
            }

            if (_releasePlaying)
            {
                _playingSamples.ReleaseAllAndPool(this);
                _releasePlaying = false;
                float deltaGain = 1f / (data.Length / numChannels);
                float gain      = 1f;
                for (i = 0; i < data.Length; i += numChannels)
                {
                    data[i]     *= gain;
                    data[i + 1] *= gain;
                    gain        -= deltaGain;
                }
            }
        }