Я делаю инструмент, который использует службу когнитивной речи MS и Naudio для синтеза текстовой речи и воспроизведения ее на указанном аудиоустройстве. Я использую PushAudioOutputStreamCallback для записи аудиоданных, которые из лазури передаются поставщику волн Naudio. Но при вызове SpeakTextAsync возникает исключение "Обратный вызов делегата, собранного из мусора". Как это исправить?
Этот код вызовет исключение в await 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) 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, обратный вызов System.Threading.ContextCallback, состояние объекта, bool saveSyncCtx) mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task cur rentTaskSlot) mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()
txtSpeech.Text
переменной, прежде чем использовать ее в операторе if и передать эту переменную в тест if и асинхронный вызов? - person Joshua Drake   schedule 25.06.2019