void Update()
        {
            // case needs to update PV information
            if (id >= 0)
            {
                // case this object is currently playing: update the emission, and update the output
                if (source)
                {
                    PlaneverbContext.UpdateEmission(id, transform.position);
                    PlaneverbDSPContext.UpateEmitter(id, transform.position, transform.forward);
                    output = PlaneverbContext.GetOutput(id);
                }
                // case this emission has ended since the last frame: end emission and reset the id
                else
                {
                    OnEndEmission();
                    id = -1;
                }

                if (PlaneverbContext.GetInstance().debugDraw)
                {
                    Debug.DrawRay(transform.position, transform.forward);
                }
            }
        }
        private void Awake()
        {
            globalContext = this;

            PlaneverbDSPInit(config.maxCallbackLength, config.samplingRate,
                             config.dspSmoothingFactor, config.useSpatialization, config.wetGainRatio);
        }
        private void OnAudioFilterRead(float[] data, int channels)
        {
            int dataBufferLength = data.Length;

            // case: first reverb component to run during this audio frame, and there are emitters playing
            if (runtimeIndex == 0 && pvSources != null)
            {
                // copy over PVDSP Audio sources into threaded buffer
                int numSources = pvSources.Length;
                for (int i = 0; i < pvSources.Length; ++i)
                {
                    audioThreadSources[i] = pvSources[i];
                }

                // get source buffer from each PVDSP Audio Source
                float[] buffer;
                for (int i = 0; i < numSources; ++i)
                {
                    buffer = audioThreadSources[i].GetSource(dataBufferLength, channels);
                    PlaneverbDSPContext.SendSource(
                        pvSources[i].GetEmissionID(),
                        pvSources[i].GetInput(),
                        buffer, dataBufferLength,
                        channels);
                }

                // Tell the DSP Context to process the source and prepare into the 3 output buffers
                // ProcessOutput returns a flag on whether or not the output was successful
                pvDSPProcessFlag = PlaneverbDSPContext.ProcessOutput();
            }

            // increment the runtime index looping back around to zero from 3
            runtimeIndex = (runtimeIndex + 1) % MAX_REVERBS;

            // fill the in/out data buffer IFF output was processed successfully
            if (pvDSPProcessFlag == true)
            {
                // fetch the respective output buffer from the context
                // (each reverb has it's own output buffer based off of myIndex)
                PlaneverbDSPContext.GetOutputBuffer(myIndex, ref outputBuffer);

                // choose the right length in case data buffer too big
                dataBufferLength = (dataBufferLength > outputBuffer.Length) ? outputBuffer.Length : dataBufferLength;

                // memcpy the data over
                Array.Copy(outputBuffer, data, dataBufferLength);
            }
            // case that the PVDSP module couldn't generate valid output
            else
            {
                // fill output with 0
                for (int i = 0; i < dataBufferLength; ++i)
                {
                    data[i] = 0f;
                }
            }
        }
        void Start()
        {
            // enable singleton pattern
            Debug.AssertFormat(instance == null, "More than one instance of the PlaneverbListener created! Singleton violated.");
            instance = this;

            // init listener information in both contexts
            PlaneverbContext.SetListenerPosition(transform.position);
            PlaneverbDSPContext.SetListenerTransform(transform.position, transform.forward);
        }
        void Update()
        {
            // update listener information in both contexts
            PlaneverbContext.SetListenerPosition(transform.position);
            PlaneverbDSPContext.SetListenerTransform(transform.position, transform.forward);
            oldPosition = transform.position;

            if (PlaneverbContext.GetInstance().debugDraw)
            {
                Debug.DrawRay(transform.position, transform.forward, new Color(0f, 0f, 1f));
            }
        }
        // two versions of Emit. one for playing stored Clip, other for AudioSource.PlayOneShot functionality

        public void Emit()
        {
            // start the emission and create the source
            id = PlaneverbContext.Emit(transform.position);
            PlaneverbDSPContext.UpateEmitter(id, transform.position, transform.forward);
            PlaneverbDSPContext.SetEmitterDirectivityPattern(id, DirectivityPattern);
            output = PlaneverbContext.GetOutput(id);
            source = PlaneverbAudioManager.pvDSPAudioManager.Play(Clip, id, this, Loop);
            if (source == null)
            {
                OnEndEmission();
            }
        }