/// <summary> /// Processes a frame of the incoming audio stream. Upon detection of wake word and completion of follow-on command /// inference invokes user-defined callbacks. /// </summary> /// <param name="pcm"> /// A frame of audio samples. The number of samples per frame can be found by calling `.FrameLength`. /// The incoming audio needs to have a sample rate equal to `.SampleRate` and be 16-bit linearly-encoded. /// Picovoice operates on single-channel audio. /// </param> public void Process(short[] pcm) { if (pcm.Length != FrameLength) { throw new ArgumentException(string.Format("Input audio frame size ({0}) was not the size specified by Picovoice engine ({1}). ", pcm.Length, FrameLength) + "Use picovoice.FrameLength to get the correct size."); } if (_porcupine == null || _rhino == null) { throw new ObjectDisposedException("picovoice", "Cannot process frame - resources have been released."); } if (!_isWakeWordDetected) { int keywordIndex = _porcupine.Process(pcm); if (keywordIndex >= 0) { _isWakeWordDetected = true; _wakeWordCallback.Invoke(); } } else { bool isFinalized = _rhino.Process(pcm); if (isFinalized) { _isWakeWordDetected = false; _inferenceCallback.Invoke(_rhino.GetInference()); } } }
/// <summary> /// Action to catch audio frames as voice processor produces them /// </summary> /// <param name="pcm">Frame of pcm audio</param> private void OnFrameCaptured(short[] pcm) { try { int keywordIndex = _porcupine.Process(pcm); if (keywordIndex >= 0) { if (_wakeWordCallback != null) { _wakeWordCallback.Invoke(keywordIndex); } } } catch (Exception ex) { if (_errorCallback != null) { _errorCallback(ex); } else { Debug.LogError(ex.ToString()); } } }