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(); }
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(); }
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); } }