/// <summary>
    /// Update this instance.
    /// </summary>
    void Update()
    {
        if (!audioSource)
        {
            return;
        }

        // If user called Play on the acutal AudioSource, account for this
        // NOTE: There may be a potential issue with calling AudioSource.Stop on a
        // looping sound, since the Update may not catch this. We might need to catch
        // this edge case at some point; a one-shot sound will stop automatically and
        // return spatialization resources.
        if ((isPlaying == false) && (audioSource.isPlaying))
        {
            // This is a copy of OSPAudioSource Play function, minus
            // calling Play on audio source since it's already been called

            // Bail if manager has not even started
            if (OSPManager.IsInitialized() == false)
            {
                return;
            }

            // We will grab a context at this point, and set the right values
            // to allow for spatialization to take effect
            Aquire();

            // We will set the relative position of this sound now before we start playing
            SetRelativeSoundPos(true);

            // We are ready to play the sound
            // Commented out, kept for readability
            // audioSource.Play();

            lock (this) isPlaying = true;
        }

        // If sound is playing on it's own and dies off, we need to
        // Reset
        if (isPlaying == true)
        {
            // If we stopped the sound using AudioSource, Release resources
            if (audioSource.isPlaying == false)
            {
                lock (this) isPlaying = false;
                Release();
                return;
            }

            // We will go back and forth between spatial processing
            // and native 2D panning
            if ((Bypass == true) || (OSPManager.GetBypass() == true))
            {
#if (!UNITY5)
                audioSource.spatialBlend = panLevel;
#else
                audioSource.spatialBlend = panLevel;
#endif
                audioSource.spread = spread;
            }
            else
            {
                // We want to remove FMod curve attenuation if we are doing our
                // own internal calc
                float pl = sSetPanLevel;
                if (OSPManager.GetUseInverseSquareAttenuation() == true)
                {
                    pl = sSetPanLevelInvSq;
                }
#if (!UNITY5)
                audioSource.spatialBlend = pl;
#else
                audioSource.spatialBlend = pl;
#endif
                audioSource.spread = sSetSpread;
            }

            // Update FrequencyHints and local reflection enable/disable
            if (context != sNoContext)
            {
                OSPManager.SetFrequencyHint(context, frequencyHint);
                OSPManager.SetDisableReflectionsOnSound(context, disableReflections);
            }

            // return the context when the sound has finished playing
            if ((audioSource.time >= audioSource.clip.length) && (audioSource.loop == false))
            {
                // One last pass to allow for the tail portion of the sound
                // to finish
                drainTime = OSPManager.GetDrainTime(context);
                drain     = true;
            }
            else
            {
                // We must set all positional properties here, not in
                // OnAudioFilterRead. We might consider a better approach
                // to interpolate the current location for better localization,
                // should the resolution of setting it here sound jittery due
                // to thread frequency mismatch.
                SetRelativeSoundPos(false);

#if DEBUG_AudioSource
                // Time main thread and audio thread
                if (debugOn)
                {
                    // Get audio frequency
                    if (audioFrames == 0)
                    {
                        float ct = 1.0f / (GetTime(false) - dTimeMainLoop);
                        Debug.LogWarning(System.String.Format("U: {0:F0}", ct));
                        ct = 100.0f / (GetTime(true) - PrevAudioTime);
                        Debug.LogWarning(System.String.Format("A: {0:F0}", ct));
                        audioFrames   = 100;
                        PrevAudioTime = (float)GetTime(true);
                    }

                    dTimeMainLoop = (float)GetTime(false);
                }
#endif
            }

            if (drain == true)
            {
                // Keep playing until we safely drain out the early reflections
                drainTime -= Time.deltaTime;
                if (drainTime < 0.0f)
                {
                    drain = false;

                    lock (this) isPlaying = false;
                    // Stop will both stop audio from playing (keeping OnAudioFilterRead from
                    // running with a held audio source) as well as release the spatialization
                    // resources via Release()
                    Stop();
                }
            }
        }
    }