我正在制作一个工具,它使用MS认知语音服务和N音频来合成文本语音,并在指定的音频设备上播放。我使用PushAudioOutputStreamCallback来编写音频数据,这些数据从天蓝色传输到N音频的波形提供商。但是,当SpeakTextAsync调用时,会抛出一个异常“对垃圾收集的委托进行回调”。怎么修呢?
此代码将在等待speecher.SpeakTextAsync(txtSpeech.Text)的引发异常。
public partial class MainWindow : Window
{
WaveOut device;
BufferedWaveProvider playback;
SpeechSynthesizer speecher;
PushNAudio push;
public MainWindow()
{
InitializeComponent();
var fmt = new WaveFormat();
fmt = fmt.AsStandardWaveFormat();
playback = new BufferedWaveProvider(fmt);
var cfg = SpeechConfig.FromSubscription("xxxxx", "xxxxx");
var asfmt = AudioStreamFormat.GetWaveFormatPCM((uint)fmt.SampleRate, (byte)fmt.BitsPerSample, (byte)fmt.Channels);
push = new PushNAudio(playback);
AudioConfig acfg = AudioConfig.FromStreamOutput(push, asfmt);
speecher = new SpeechSynthesizer (cfg, acfg);
device = new WaveOut();
device.DeviceNumber = 1;
device.Init(playback);
device.Play();
}
public class PushNAudio : PushAudioOutputStreamCallback
{
private BufferedWaveProvider _provider;
public PushNAudio(BufferedWaveProvider provider)
{
_provider = provider;
}
public override uint Write(byte[] dataBuffer)
{
_provider.AddSamples(dataBuffer, 0, dataBuffer.Length);
return (uint)dataBuffer.Length;
}
}
private async void DoSpeech()
{
if (string.IsNullOrWhiteSpace(txtSpeech.Text))
return;
/*Exception*/
var result = await speecher.SpeakTextAsync(txtSpeech.Text);
if (result.Reason == ResultReason.Canceled)
{
var details = SpeechSynthesisCancellationDetails.FromResult(result);
}
}
private void TxtSpeech_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
DoSpeech();
e.Handled = true;
}
}这一例外情况:
对'Microsoft.CognitiveServices.Speech.csharp!Microsoft.CognitiveServices.Speech.Internal.PushAudioStreamWriteDelegate::Invoke'.类型的垃圾收集委托进行回调。这可能会导致应用程序崩溃、损坏和数据丢失。当将委托传递给非托管代码时,托管应用程序必须使它们保持活动状态,直到保证它们永远不会被调用为止。
堆叠:
Microsoft.CognitiveServices.Speech.csharp.dll!Microsoft.CognitiveServices.Speech.SpeechSynthesizer.SpeakTextAsync.AnonymousMethod__1() Microsoft.CognitiveServices.Speech.csharp.dll!Microsoft.CognitiveServices.Speech.SpeechSynthesizer.DoAsyncSynthesisAction(System.Action synthImplAction) Microsoft.CognitiveServices.Speech.csharp.dll!Microsoft.CognitiveServices.Speech.SpeechSynthesizer.SpeakTextAsync.AnonymousMethod__0() mscorlib.dll!System.Threading.Tasks.Task.InnerInvoke() mscorlib.dll!System.Threading.Tasks.Task.Execute() mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext,mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext,System.Threading.ContextCallback回调,object状态,bool preserveSyncCtx) mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot) mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()
发布于 2019-06-28 07:36:33
经过多次尝试,我发现当目标.net内核时,这些代码可以很好地工作。我认为Microsoft.CognitiveServices.Speech可能还没有在.net框架下进行充分的测试。
https://stackoverflow.com/questions/56705572
复制相似问题