mirror of
https://github.com/9ParsonsB/Pulsar.git
synced 2025-12-16 04:44:56 +01:00
observatory herald (#30)
* WIP: initial commit for observatory herald * Plugin error handling refactor * make error window non-modal * tidy up plugin error handling * first pass for basic herald functionality * corrections for linux env * Use FNV hash directly instead of managing through dictionary/index file * resolve audio queuing issue, switch to personal NetCoreAudio fork * merge cleanup * add enable setting, populate defaults * framework xml doc update * Adjust settings, add style selection, replace locale with demonym in dropdown list. * Test is position is on screen before saving/loading. * use a default that's actually in the list
This commit is contained in:
94
ObservatoryHerald/HeraldQueue.cs
Normal file
94
ObservatoryHerald/HeraldQueue.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using Observatory.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using NetCoreAudio;
|
||||
using System.Threading;
|
||||
|
||||
namespace Observatory.Herald
|
||||
{
|
||||
class HeraldQueue
|
||||
{
|
||||
private Queue<NotificationArgs> notifications;
|
||||
private bool processing;
|
||||
private string voice;
|
||||
private string style;
|
||||
private VoiceSpeechManager azureCacheManager;
|
||||
private Player audioPlayer;
|
||||
|
||||
public HeraldQueue(VoiceSpeechManager azureCacheManager)
|
||||
{
|
||||
this.azureCacheManager = azureCacheManager;
|
||||
processing = false;
|
||||
notifications = new();
|
||||
audioPlayer = new();
|
||||
}
|
||||
|
||||
|
||||
internal void Enqueue(NotificationArgs notification, string selectedVoice, string selectedStyle = "")
|
||||
{
|
||||
voice = selectedVoice;
|
||||
style = selectedStyle;
|
||||
notifications.Enqueue(notification);
|
||||
|
||||
if (!processing)
|
||||
{
|
||||
processing = true;
|
||||
ProcessQueueAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async void ProcessQueueAsync()
|
||||
{
|
||||
await Task.Factory.StartNew(ProcessQueue);
|
||||
}
|
||||
|
||||
private void ProcessQueue()
|
||||
{
|
||||
while (notifications.Any())
|
||||
{
|
||||
var notification = notifications.Dequeue();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(notification.TitleSsml))
|
||||
{
|
||||
Speak(notification.Title);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpeakSsml(notification.TitleSsml);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(notification.DetailSsml))
|
||||
{
|
||||
Speak(notification.Detail);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpeakSsml(notification.DetailSsml);
|
||||
}
|
||||
}
|
||||
|
||||
processing = false;
|
||||
}
|
||||
|
||||
private void Speak(string text)
|
||||
{
|
||||
SpeakSsml($"<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><voice name=\"\">{text}</voice></speak>");
|
||||
}
|
||||
|
||||
private void SpeakSsml(string ssml)
|
||||
{
|
||||
string file = azureCacheManager.GetAudioFileFromSsml(ssml, voice, style);
|
||||
|
||||
// For some reason .Wait() concludes before audio playback is complete.
|
||||
audioPlayer.Play(file);
|
||||
while (audioPlayer.Playing)
|
||||
{
|
||||
Thread.Sleep(20);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user