public void OnAudioFilterRead([NotNull] float[] data, int channels) { //If there is no session, clear filter and early exit var maybeSession = Session; if (!maybeSession.HasValue) { Array.Clear(data, 0, data.Length); return; } _sessionLock.EnterUpgradeableReadLock(); try { //Check if there is no session again, this time protected by a lock maybeSession = Session; if (!maybeSession.HasValue) { Array.Clear(data, 0, data.Length); return; } //Detect if the session has changed since the last call to this method, if so reset var session = maybeSession.Value; if (!session.Context.Equals(_lastPlayedSessionContext)) { _lastPlayedSessionContext = maybeSession.Value.Context; ApplyReset(); } // Read data from pipeline float arv; var complete = Filter(session, data, channels, _temp, _diagnosticOutput, out arv); _arv = arv; //Clean up now that this session is complete if (complete) { Log.Debug("Finished playback of speech session. id={0}", session.Context.Id); //Clear the session _sessionLock.EnterWriteLock(); try { Session = null; } finally { _sessionLock.ExitWriteLock(); } //Reset the state ApplyReset(); //Discard the diagnostic recorder if necessary if (_diagnosticOutput != null) { _diagnosticOutput.Dispose(); _diagnosticOutput = null; } } } finally { _sessionLock.ExitUpgradeableReadLock(); } }