Example #1
0
        public void TestProcess()
        {
            Porcupine p = new Porcupine(Path.Combine(Environment.CurrentDirectory, "porcupine_params.pv"), keywordFilePath: $"{GetAbsRootPath()}resources/keyword_files/porcupine_{GetEnvironmentName()}.ppn", sensitivity: 0.5f);

            Assert.AreEqual(PicoVoiceStatus.SUCCESS, p.Status, "the status of the creation of the recognition system has failed");
            WAVFile file = new WAVFile();

            file.Open("porcupine.wav", WAVFile.WAVFileMode.READ);
            Assert.AreEqual(p.SampleRate() / 1000, file.BitsPerSample, "The samplerate is not equal!!!");
            List <short> data = new List <short>();

            while (file.NumSamplesRemaining > 0)
            {
                data.Add(BitConverter.ToInt16(file.GetNextSample_ByteArray()));
            }

            int framecount = (int)Math.Floor((decimal)(data.Count / p.FrameLength()));
            var results    = new List <bool>();

            for (int i = 0; i < framecount; i++)
            {
                int          start = i * p.FrameLength();
                int          count = p.FrameLength();
                List <short> frame = data.GetRange(start, count);
                p.Process(frame.ToArray(), out bool result);
                results.Add(result);
            }

            var res = results.Count(x => x);

            Assert.AreEqual(1, res, $"The result is not as expected, expected {1} got {res}");
            p.Dispose();
        }
Example #2
0
        public void MultipleKeywords()
        {
            var modelFilePath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "porcupine_params.pv"));

            Assert.IsTrue(File.Exists(modelFilePath), $"File.Exists(modelFilePath) --> {modelFilePath}");
            paths.ForEach(keywordFilePath => Assert.IsTrue(File.Exists(keywordFilePath), $"File.Exists(keywordFilePath) --> {keywordFilePath}"));

            Porcupine p = new Porcupine(modelFilePath, keywordFilePaths: paths, sensitivities: senses);

            Assert.AreEqual(PicoVoiceStatus.SUCCESS, p.Status, "the status of the creation of the recognition system has failed");
            WAVFile file = new WAVFile();

            file.Open("multiple_keywords.wav", WAVFile.WAVFileMode.READ);
            Assert.AreEqual(p.SampleRate(), file.AudioFormat.SampleRateHz, "The samplerate is not equal!!!");
            List <short> data = new List <short>();

            while (file.NumSamplesRemaining > 0)
            {
                data.Add(BitConverter.ToInt16(file.GetNextSample_ByteArray()));
            }
            int framecount = (int)Math.Floor((decimal)(data.Count / p.FrameLength()));
            var results    = new List <int>();

            for (int i = 0; i < framecount; i++)
            {
                int             start  = i * p.FrameLength();
                int             count  = p.FrameLength();
                List <short>    frame  = data.GetRange(start, count);
                PicoVoiceStatus status = p.ProcessMultipleKeywords(frame.ToArray(), out int result);
                if (result >= 0)
                {
                    results.Add(result);
                }
                Assert.AreEqual(PicoVoiceStatus.SUCCESS, status, "The status is not as expected");
            }

            var requiredRes = new[] { 8, 0, 1, 2, 3, 4, 5, 7, 8, 9 };

            Assert.AreEqual(requiredRes.Length, results.Count, $"expected results length are different expected {requiredRes.Length} got {results.Count}");
            for (var i = 0; i < results.Count; i++)
            {
                Assert.AreEqual(requiredRes[i], results[i], $"The result is not as expected, expected {requiredRes[i]} got {results[i]}");
            }

            p.Dispose();
        }
Example #3
0
        protected override async Task DoWorkAsync(CancellationToken cancellationToken)
        {
            Console.WriteLine("Starting voice assistant runner for " + _user.Username);
            try
            {
                var entryDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

                string[] keywordFiles;
                if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                {
                    keywordFiles = new string[] {
                        Path.Join(entryDirectory, "picovoice_windows.ppn"),
                        Path.Join(entryDirectory, "porcupine_windows.ppn"),
                        Path.Join(entryDirectory, "bumblebee_windows.ppn"),
                    };
                }
                else
                {
                    keywordFiles = new string[] {
                        Path.Join(entryDirectory, "alexa_linux.ppn"),
                        Path.Join(entryDirectory, "porcupine_linux.ppn"),
                        Path.Join(entryDirectory, "snowboy_linux.ppn"),
                        Path.Join(entryDirectory, "dank_ditties_linux.ppn"),
                    };
                }

                using var porcupine = new Porcupine(
                          Path.Join(entryDirectory, "porcupine_params.pv"),
                          keywordFiles,
                          keywordFiles.Select(_ => 0.5f).ToArray()
                          );

                var userStream = _user.AudioStream;
                if (userStream == null)
                {
                    return;
                }

                var picoFrameLength = porcupine.FrameLength();
                var picoSampleRate  = porcupine.SampleRate();
                var picoBuffer      = new short[picoFrameLength];

                await using var clip = new StreamClip(userStream).UseMemoryBuffer(3840);
                await clip.PrepareAsync();

                await using var monoClip = clip.Downsample(96000, 48000);
                await monoClip.PrepareAsync();

                await using var downsampledClip = monoClip.Downsample(48000, picoSampleRate);
                await downsampledClip.PrepareAsync();

                while (!cancellationToken.IsCancellationRequested)
                {
                    Console.WriteLine("Waiting for wake word");
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        await downsampledClip.ReadAsync(picoBuffer, 0, picoFrameLength, cancellationToken);

                        var status = porcupine.Process(picoBuffer);
                        if (status != -1)
                        {
                            break;
                        }
                    }

                    Console.WriteLine("Wake word detected");
                    clip.Seek(-picoFrameLength * 6 * (48000 / picoSampleRate), SeekOrigin.Current);

                    try
                    {
                        var data = await _witAiClient.ParseAudioStream(monoClip, cancellationToken);

                        if (data != null)
                        {
                            var text = data.Text?.Trim();
                            if (!string.IsNullOrWhiteSpace(text))
                            {
                                Console.WriteLine(_user.Username + ": " + text);
                                var playSongIntent = data.Intents.FirstOrDefault(i => i.Name == "play_song");

                                if (text.ToLower().StartsWith("i'm "))
                                {
                                    _voiceChannelWorker.Say("Hello " + text.Substring("i'm ".Length) + ", I'm Dank Ditties bot.");
                                }
                                else if (text.ToLower().StartsWith("play "))
                                {
                                    var searchString = text.Substring("play ".Length);

                                    if (searchString == "next")
                                    {
                                        _voiceChannelWorker?.TrySkip();
                                    }
                                    else
                                    {
                                        var matches = from post in await _metadataManager.GetReadyToPlayMetadataAsync()
                                                      let relevance = FuzzySharp.Fuzz.Ratio(post.Title, searchString)
                                                                      select(post, relevance);

                                        var topMatch = matches.OrderByDescending(m => m.relevance);
                                        Console.WriteLine("matches: \n" + string.Join("\n", topMatch.Take(3).Select(m => $"{m.post.Title}: {m.relevance}")));
                                        Console.WriteLine();
                                        var closestMatch = topMatch.FirstOrDefault().post;
                                        if (closestMatch != null)
                                        {
                                            _voiceChannelWorker.EnqueueSong(closestMatch.Id);
                                            _voiceChannelWorker.Say("I have added your song, " + closestMatch.Title + " to the queue");
                                            Console.WriteLine("Added " + closestMatch.Title + " to queue");
                                        }
                                    }
                                }
                                else if (text.ToLower() == "what song is this" || text.ToLower() == "what's playing" || text.ToLower() == "song" || text.ToLower() == "song name" || text.ToLower() == "damn son whered you find this")
                                {
                                    _voiceChannelWorker.Say("I am currently playing " + _voiceChannelWorker?.CurrentSong.Title);
                                }
                                else
                                {
                                    //_voiceChannelWorker.Say("I'm sorry, I didn't understand that!");
                                    _voiceChannelWorker.Say(text);
                                }
                            }
                            else
                            {
                                _voiceChannelWorker.Say("I'm sorry, I didn't understand that!");
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
                }
                _voiceChannelWorker.Say("Goodbye, " + _user.Nickname ?? _user.Username);
            }
            finally
            {
                Console.WriteLine("Stopping voice assistant runner for " + _user.Username);
            }
        }