Example #1
0
        /// <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();
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <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();
        }
Example #4
0
        /// <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."));
            }
        }
Example #5
0
        /// <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();
        }