繁体   English   中英

使用 Microsoft Cognitive Speech API 和非麦克风实时音频流进行语音识别

[英]Speech recognition with Microsoft Cognitive Speech API and non-microphone real-time audio stream

问题

我的项目包括一个实时录制音频的桌面应用程序,我打算接收来自 API 的实时识别反馈。 使用麦克风,使用 Microsoft 新的 Speech-to-Text API 的实时实现是微不足道的,我的场景与我的场景的不同之处仅在于我的数据写入MemoryStream对象。

API 支持

本文解释了如何使用自定义音频流实现 API 的Recognizer链接),这总是需要实现抽象类PullAudioInputStream链接),以便使用CreatePullStream方法( 链接)创建所需的AudioConfig对象。 换句话说,要实现我的要求,必须实现回调接口。

实施尝试

由于我的数据被写入 MemoryStream(我使用的库只会记录到文件或 Stream 对象),在下面的代码中,我只是将缓冲区复制到实现的类(可能是草率的方式? )解决分歧在方法签名中。

class AudioInputCallback : PullAudioInputStreamCallback
{
    private readonly MemoryStream memoryStream;

    public AudioInputCallback(MemoryStream stream)
    {
        this.memoryStream = stream;
    }

    public override int Read(byte[] dataBuffer, uint size)
    {
        return this.Read(dataBuffer, 0, dataBuffer.Length);
    }

    private int Read(byte[] buffer, int offset, int count)
    {
        return memoryStream.Read(buffer, offset, count);
    }

    public override void Close()
    {
        memoryStream.Close();
        base.Close();
    }

}

Recognizer实现如下:

private SpeechRecognizer CreateMicrosoftSpeechRecognizer(MemoryStream memoryStream)
{
    var recognizerConfig = SpeechConfig.FromSubscription(SubscriptionKey, @"westus");
    recognizerConfig.SpeechRecognitionLanguage =
        _programInfo.CurrentSourceCulture.TwoLetterISOLanguageName;

    // Constants are used as constructor params)
    var format = AudioStreamFormat.GetWaveFormatPCM(
        samplesPerSecond: SampleRate, bitsPerSample: BitsPerSample, channels: Channels);

    // Implementation of PullAudioInputStreamCallback
    var callback = new AudioInputCallback(memoryStream);
    AudioConfig audioConfig = AudioConfig.FromStreamInput(callback, format);

    //Actual recognizer is created with the required objects
    SpeechRecognizer recognizer = new SpeechRecognizer(recognizerConfig, audioConfig);

    // Event subscriptions. Most handlers are implemented for debugging purposes only.
    // A log window outputs the feedback from the event handlers.
    recognizer.Recognized += MsRecognizer_Recognized;
    recognizer.Recognizing += MsRecognizer_Recognizing;
    recognizer.Canceled += MsRecognizer_Canceled;
    recognizer.SpeechStartDetected += MsRecognizer_SpeechStartDetected;
    recognizer.SpeechEndDetected += MsRecognizer_SpeechEndDetected;
    recognizer.SessionStopped += MsRecognizer_SessionStopped;
    recognizer.SessionStarted += MsRecognizer_SessionStarted;

    return recognizer;
}

如何将数据提供给识别器(使用 CSCore):

MemoryStream memoryStream = new MemoryStream(_finalSource.WaveFormat.BytesPerSecond / 2);
byte[] buffer = new byte[_finalSource.WaveFormat.BytesPerSecond / 2];

_soundInSource.DataAvailable += (s, e) =>
{
    int read;
    _programInfo.IsDataAvailable = true;

    // Writes to MemoryStream as event fires
    while ((read = _finalSource.Read(buffer, 0, buffer.Length)) > 0)
        memoryStream.Write(buffer, 0, read);
};

// Creates MS recognizer from MemoryStream
_msRecognizer = CreateMicrosoftSpeechRecognizer(memoryStream);

//Initializes loopback capture instance
_soundIn.Start();

await Task.Delay(1000);

// Starts recognition
await _msRecognizer.StartContinuousRecognitionAsync();

结果

当应用程序运行时,我没有收到任何异常,也没有来自 API 的任何响应,除了SessionStartedSessionStopped ,如下面我的应用程序的日志窗口所示。

在此处输入图片说明

我可以使用不同方法的建议来实现我的实现,因为我怀疑将记录的DataAvailable事件与实际向 API 发送数据相关联时存在一些时间问题,这使得它过早地丢弃会话。 由于没有关于我的请求为何不成功的详细反馈,我只能猜测原因。

如果没有立即可用的数据, PullAudioInputStreamRead()回调应该阻塞。 只有当流到达末尾时, Read()返回 0。 然后,在Read()返回 0 后,SDK 将关闭流Read() 在此处找到 API 参考文档)。

但是,C# MemoryStream 的 Read() 的行为不同:如果缓冲区中没有可用数据,则返回 0。 这就是为什么您只看到SessionStartSessionStop事件,而看不到识别事件的原因。

为了解决这个问题,您需要在PullAudioInputStream::Read()MemoryStream::Write()之间添加某种同步,以确保PullAudioInputStream::Read()将等到MemoryStream::Write()将一些数据写入缓冲区。

或者,我建议使用PushAudioInputStream ,它允许您直接将数据写入流。 对于你的情况,在_soundSource.DataAvailable事件,而不是将数据写入MemoryStream ,你可以直接把它写到PushAudioInputStream 您可以在此处找到PushAudioInputStream示例。

我们将更新文档以提供有关如何使用 Pull 和 Push AudioInputStream的最佳实践。 带来不便敬请谅解。

谢谢!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM