-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAudioTargetQueue.cs
103 lines (83 loc) · 2.55 KB
/
AudioTargetQueue.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System;
using System.Speech.Synthesis;
using System.Collections.Generic;
using System.IO;
using System.Speech.Synthesis;
using NAudio.Wave;
using System.Threading;
using System.Threading.Tasks;
public class AudioTargetQueue
{
private Queue<string> _textQueue = new Queue<string>();
private bool _isPlaying = false;
private CancellationTokenSource _cancellationTokenSource;
private string _target = "None";
public AudioTargetQueue()
{
_cancellationTokenSource = new CancellationTokenSource();
}
public void SetTarget(string t)
{
_target = t;
}
public void EnqueueText(string text)
{
_textQueue.Enqueue(text);
if (!_isPlaying)
{
var cancellationToken = _cancellationTokenSource.Token;
_ = PlayQueueAsync(cancellationToken);
}
}
public void Stop()
{
_textQueue.Clear();
if (_isPlaying)
{
_cancellationTokenSource.Cancel();
_cancellationTokenSource = new CancellationTokenSource();
}
}
private async Task PlayQueueAsync(CancellationToken cancellationToken)
{
_isPlaying = true;
while (_textQueue.Count > 0 && !cancellationToken.IsCancellationRequested)
{
var text = _textQueue.Dequeue();
try
{
await SynthesizeAndPlayAsync(text, cancellationToken);
}
catch (OperationCanceledException)
{
// Handle cancellation gracefully
break;
}
}
_isPlaying = false;
}
private async Task SynthesizeAndPlayAsync(string text, CancellationToken cancellationToken)
{
using (var ms = new MemoryStream())
{
using (var synthesizer = new SpeechSynthesizer())
{
synthesizer.SetOutputToWaveStream(ms);
synthesizer.SpeakSsml(text);
}
ms.Position = 0;
using (var waveOut = new WaveOutEvent())
using (var rawSource = new RawSourceWaveStream(ms, new WaveFormat(22000, 1)))
{
var stereo = new MonoToStereoProvider(rawSource, _target);
waveOut.Init(stereo);
waveOut.Play();
while (waveOut.PlaybackState == PlaybackState.Playing && !cancellationToken.IsCancellationRequested)
{
await Task.Delay(100, cancellationToken);
}
waveOut.Stop();
}
}
}
}