/// <summary> /// Creates an instance of the Porcupine wake word engine. /// </summary> /// <param name="modelPath">Absolute path to file containing model parameters.</param> /// <param name="keywordPaths">A list of absolute paths to keyword model files.</param> /// <param name="sensitivities"> /// A list of sensitivity values for each keyword. A higher sensitivity value lowers miss rate at the cost of increased /// false alarm rate. A sensitivity value should be within [0, 1]. /// </param> private Porcupine(string modelPath, IEnumerable <string> keywordPaths, IEnumerable <float> sensitivities) { PorcupineStatus status = pv_porcupine_init(modelPath, keywordPaths.Count(), keywordPaths.ToArray(), sensitivities.ToArray(), out _libraryPointer); if (status != PorcupineStatus.SUCCESS) { throw PorcupineStatusToException(status); } Version = Marshal.PtrToStringAnsi(pv_porcupine_version()); SampleRate = pv_sample_rate(); FrameLength = pv_porcupine_frame_length(); }
/// <summary> /// Process a frame of audio with the wake word engine. /// </summary> /// <param name="pcm"> /// A frame of audio samples to be assessed by Porcupine. The required audio format is found by calling `.SampleRate` to get the required /// sample rate and `.FrameLength` to get the required frame size. Audio must be single-channel and 16-bit linearly-encoded. /// </param> /// <returns> /// Index of the detected keyword, or -1 if no detection occurred /// </returns> public int Process(short[] pcm) { if (pcm.Length != FrameLength) { throw new ArgumentException($"Input audio frame size ({pcm.Length}) was not the size specified by Porcupine engine ({FrameLength}). " + $"Use Porcupine.FrameLength to get the correct size."); } int keywordIndex; PorcupineStatus status = pv_porcupine_process(_libraryPointer, pcm, out keywordIndex); if (status != PorcupineStatus.SUCCESS) { throw PorcupineStatusToException(status); } return(keywordIndex); }
/// <summary> /// Creates an instance of the Porcupine wake word engine. /// </summary> /// <param name="modelPath">Absolute path to file containing model parameters.</param> /// <param name="keywordPaths">A list of absolute paths to keyword model files.</param> /// <param name="sensitivities"> /// A list of sensitivity values for each keyword. A higher sensitivity value lowers miss rate at the cost of increased /// false alarm rate. A sensitivity value should be within [0, 1]. /// </param> public Porcupine(string modelPath, IEnumerable <string> keywordPaths, IEnumerable <float> sensitivities) { if (string.IsNullOrWhiteSpace(modelPath) || keywordPaths == null || keywordPaths.Count() == 0 || sensitivities == null || sensitivities.Count() == 0) { throw new ArgumentNullException("One or more of the constructor arguments were null or empty. "); } if (!File.Exists(modelPath)) { throw new IOException($"Couldn't find model file at '{modelPath}'"); } foreach (string path in keywordPaths) { if (!File.Exists(path)) { throw new IOException($"Couldn't find keyword file at '{path}'"); } } if (sensitivities.Any(s => s < 0 || s > 1)) { throw new ArgumentException("Sensitivities should be within [0, 1]."); } if (keywordPaths.Count() != sensitivities.Count()) { throw new ArgumentException($"Number of keywords ({keywordPaths.Count()}) does not match number of sensitivities ({sensitivities.Count()})"); } PorcupineStatus status = pv_porcupine_init(modelPath, keywordPaths.Count(), keywordPaths.ToArray(), sensitivities.ToArray(), out _libraryPointer); if (status != PorcupineStatus.SUCCESS) { throw PorcupineStatusToException(status); } Version = Marshal.PtrToStringAnsi(pv_porcupine_version()); SampleRate = pv_sample_rate(); FrameLength = pv_porcupine_frame_length(); }
/// <summary> /// Coverts status codes to relavent .NET exceptions /// </summary> /// <param name="status">Picovoice library status code.</param> /// <returns>.NET exception</returns> private static PorcupineException PorcupineStatusToException( PorcupineStatus status, string message = "") { switch (status) { case PorcupineStatus.OUT_OF_MEMORY: return(new PorcupineMemoryException(message)); case PorcupineStatus.IO_ERROR: return(new PorcupineIOException(message)); case PorcupineStatus.INVALID_ARGUMENT: return(new PorcupineInvalidArgumentException(message)); case PorcupineStatus.STOP_ITERATION: return(new PorcupineStopIterationException(message)); case PorcupineStatus.KEY_ERROR: return(new PorcupineKeyException(message)); case PorcupineStatus.INVALID_STATE: return(new PorcupineInvalidStateException(message)); case PorcupineStatus.RUNTIME_ERROR: return(new PorcupineRuntimeException(message)); case PorcupineStatus.ACTIVATION_ERROR: return(new PorcupineActivationException(message)); case PorcupineStatus.ACTIVATION_LIMIT_REACHED: return(new PorcupineActivationLimitException(message)); case PorcupineStatus.ACTIVATION_THROTTLED: return(new PorcupineActivationThrottledException(message)); case PorcupineStatus.ACTIVATION_REFUSED: return(new PorcupineActivationRefusedException(message)); default: return(new PorcupineException("Unmapped error code returned from Porcupine.")); } }
/// <summary> /// Creates an instance of the Porcupine wake word engine. /// </summary> /// <param name="accessKey">AccessKey obtained from Picovoice Console (https://console.picovoice.ai/).</param> /// <param name="modelPath">Absolute path to file containing model parameters.</param> /// <param name="keywordPaths">A list of absolute paths to keyword model files.</param> /// <param name="sensitivities"> /// A list of sensitivity values for each keyword. A higher sensitivity value lowers miss rate at the cost of increased /// false alarm rate. A sensitivity value should be within [0, 1]. /// </param> private Porcupine( string accessKey, IEnumerable <string> keywordPaths, string modelPath = null, IEnumerable <float> sensitivities = null) { if (string.IsNullOrEmpty(accessKey)) { throw new PorcupineInvalidArgumentException("No AccessKey provided to Porcupine"); } modelPath = modelPath ?? DEFAULT_MODEL_PATH; if (!File.Exists(modelPath)) { throw new PorcupineIOException($"Couldn't find model file at '{modelPath}'"); } if (keywordPaths == null || keywordPaths.Count() == 0) { throw new PorcupineInvalidArgumentException("No keyword file paths were provided to Porcupine"); } foreach (string path in keywordPaths) { if (!File.Exists(path)) { throw new PorcupineIOException($"Couldn't find keyword file at '{path}'"); } } if (sensitivities == null) { sensitivities = Enumerable.Repeat(0.5f, keywordPaths.Count()); } else { if (sensitivities.Any(s => s < 0 || s > 1)) { throw new PorcupineInvalidArgumentException("Sensitivities should be within [0, 1]."); } } if (sensitivities.Count() != keywordPaths.Count()) { throw new PorcupineInvalidArgumentException($"Number of keywords ({keywordPaths.Count()}) does not match number of sensitivities ({sensitivities.Count()})"); } PorcupineStatus status = pv_porcupine_init( accessKey, modelPath, keywordPaths.Count(), keywordPaths.ToArray(), sensitivities.ToArray(), out _libraryPointer); if (status != PorcupineStatus.SUCCESS) { throw PorcupineStatusToException(status, "Porcupine init failed."); } Version = Marshal.PtrToStringAnsi(pv_porcupine_version()); SampleRate = pv_sample_rate(); FrameLength = pv_porcupine_frame_length(); }