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

2024-01-13

Problem

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

API支持

本文 https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/how-to-use-audio-input-streams解释如何实现 APIRecognizer (link https://learn.microsoft.com/en-us/dotnet/api/microsoft.cognitiveservices.speech.recognizer) with 自定义音频流,这总是需要抽象类的实现PullAudioInputStream (link https://learn.microsoft.com/en-us/dotnet/api/microsoft.cognitiveservices.speech.audio.pullaudioinputstream)以创建所需的AudioConfig对象使用CreatePullStream方法 (link https://learn.microsoft.com/en-us/dotnet/api/microsoft.cognitiveservices.speech.audio.audioinputstream.createpullstream)。也就是说,要实现我的要求,就必须实现一个回调接口。

实施尝试

由于我的数据被写入 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();
    }

}

The 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();

Outcome

当应用程序运行时,我没有收到任何异常,也没有收到除 API 之外的任何响应SessionStarted and SessionStopped,如下图我的应用程序的日志窗口所示。

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


The Read()的回调PullAudioInputStream如果没有立即可用的数据,则应阻塞。和Read()仅当流到达末尾时才返回 0。 SDK 将在之后关闭流Read()返回 0(查找 API 参考文档here https://learn.microsoft.com/en-us/dotnet/api/microsoft.cognitiveservices.speech.audio.pullaudioinputstreamcallback.read?view=azure-dotnet#returns).

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

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

或者,我建议使用PushAudioInputStream,它允许您直接将数据写入流中。对于你的情况,在_soundSource.DataAvailable事件,而不是将数据写入MemoryStream,可以直接写入PushAudioInputStream。您可以找到以下样品PushAudioInputStream here https://github.com/Azure-Samples/cognitive-services-speech-sdk/blob/master/samples/csharp/sharedcontent/console/speech_recognition_samples.cs#L309.

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

谢谢你!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Microsoft 认知语音 API 和非麦克风实时音频流进行语音识别 的相关文章

  • 谁能建议我一种在 C++ 中分割名称的简单方法

    我一直在尝试将名称分为名字和姓氏 但我确信我的实现就简单性而言并不是最好的 string name John Smith string first string last name name find getting lastname fo
  • 通过 SocketCAN 进行 boost::asio

    我正在考虑利用升压阿西奥 http www boost org doc libs 1 49 0 doc html boost asio html从a读取数据套接字CAN http en wikipedia org wiki SocketCA
  • 使用 mono/nunit-console/4 在 Mac OS X 控制台上运行测试

    我安装了 Max OS X 10 11 1 上面装有 Xamarin 我编写了简单的测试类 只是为了测试在 Mac OS X 和 Ubuntu 上运行 Nunit 测试 该类实际上有一个返回字符串的方法 using System names
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 防止 boost::asio::io_context 在空轮询调用时停止

    此代码调用发布的句柄 boost asio io context ioc boost asio post ioc std cout lt lt lol lt lt std endl ioc poll 而这并没有 boost asio io
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • GCC 和 ld 找不到导出的符号...但它们在那里

    我有一个 C 库和一个 C 应用程序 尝试使用从该库导出的函数和类 该库构建良好 应用程序可以编译 但无法链接 我得到的错误遵循以下形式 app source file cpp text 0x2fdb 对 lib namespace Get
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • 在 JSQMessagesViewController 中显示 LocationMediaItem

    我刚刚尝试实施LocationMediaItem in my Xamarin iOS应用程序使用JSQMessagesViewController 一切都很顺利 唯一的问题是UICollectionView应该显示位置的单元格永远停留在加载
  • Visual Studio Code:如何配置 includePath 以获得更好的 IntelliSense 结果

    我是使用 Visual Studio Code 的完全初学者 我不知道我在做什么 我已经四处搜索 也许还不够 但我找不到像我这样的人如何配置的简单解释c cpp properties json每当我单击带有绿色波浪线下划线的行旁边的黄色灯泡
  • C# 构建一个 webservice 方法,它接受 POST 方法,如 HttpWebRequest 方法

    我需要一个接受 POST 方法的 Web 服务 访问我的服务器正在使用 POST 方法 它向我发送了一个 xml 我应该用一些 xml 进行响应 另一方面 当我访问他时 我已经使用 HttpWebRequest 类进行了管理 并且工作正常
  • 将二进制数据从 C# 上传到 PHP

    我想将文件从 Windows C 应用程序上传到运行 PHP 的 Web 服务器 我知道 WebClient UploadFile 方法 但我希望能够分块上传文件 以便我可以监控进度并能够暂停 恢复 因此 我正在读取文件的一部分并使用 We
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 在 EnvDTE 中调试时捕获 VS 局部变量

    是否可以使用 EnvDTE 进行 vsix Visual Studio 扩展来捕获本地和调试窗口使用的调试数据 或者可以通过其他方法吗 我想创建一个自定义的本地窗口 我们可以修改它以根据需要显示一些较重的内容 而无需为高级用户牺牲原始的本地
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 在简单注入器中解析具有自定义参数的类

    我正在使用以下命令创建 WPF MVVM 应用程序简易注射器作为 DI 容器 现在 当我尝试从简单注入器解析视图时遇到一些问题 因为我需要在构造时将参数传递到构造函数中 而不是在将视图注册到容器时 因此这不是适用的 简单注入器将值传递到构造
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐

  • NSNumberFormatter 前导 0 和小数

    有什么方法可以格式化带有前导 0 和小数的 NSNumber 吗 例如 我需要能够写 4 5 和 000 目前我拥有它 它允许小数 但不允许前导 0 NSNumberFormatter f NSNumberFormatter alloc i
  • 用C#改变单元格的背景

    我正在开发一个使用 C 来操作 Excel 文档的程序 并且我正在使用 Microsoft Office Interop Excel Worksheet worksheet 当我将某些内容插入 x y 单元格时 我使用 worksheet
  • 在 free() 后将指针设置为 NULL 总是一个好习惯吗? [复制]

    这个问题在这里已经有答案了 可能的重复 释放后将变量设置为 NULL https stackoverflow com questions 1025589 setting variable to null after free 我正在学习良好
  • java.exe 的服务器选项

    服务器热点和客户端热点有什么区别 有什么理由将生产环境切换到 server 请分享您的实践经验 有性能提升吗 与 Oracle UCM 10g 相关 是的 可以有一个huge在某些情况下性能提升 在对我的 Protocol Buffers
  • 在java中设置代理

    我创建了一项通过互联网发布内容的服务 一切都很好 但是当我将其部署到我们的服务器时 我得到连接状态 403 禁止 我认为这是因为我们的服务器不允许在未先登录的情况下直接访问互联网 我们必须首先使用我们的用户名 密码在浏览器中登录才能访问互联
  • 通过地址栏加载远程 JavaScript 文件

    是否可以从地址栏加载远程 JavaScript 文件 我一直试图将其放入地址栏 javascript src http depot com file js funcname 我不会用它来做坏事 我只是测试我的网站 仅此而已 如果你想保护你的
  • 如何将 javaw.exe 控制台输出重定向到日志文件?

    我想从批处理文件启动我的 Java 程序 这是我想用来启动应用程序的脚本 但问题是我无法将控制台输出重定向到日志文件 任何人都可以提供任何提示 而无需编辑任何代码 并使用 Java 命令行选项或其他东西吗 echo off set TASK
  • 如何在不换行的情况下打印完整的 NumPy 数组(在 Jupyter Notebook 中)

    这个问题与这个问题不同 如何打印完整的 NumPy 数组而不截断 https stackoverflow com questions 1987694 how to print the full numpy array without tru
  • Android Studio 在 M1 Apple Silicon 芯片上非常滞后

    我已从第 7 代升级到 M1 芯片 2020 Macbook Air 英特尔芯片电脑 总的来说 我对此感到非常高兴和满意 但当谈到我经常使用的 Android Studio 性能时 我很抱歉地说 非常令人失望 Apple Silicon 兼
  • 如何在 Android 上的 ListActivity 中实现上下文菜单?

    如何实现通过长按或点击使用内置布局和 ListAdapter 的 ListActivity 触发的上下文菜单 在 onCreate 方法调用上注册上下文菜单 http developer android com reference andr
  • Tensorflow GradientTape 间歇性地出现“变量不存在梯度”

    在训练我的网络时 我偶尔会遇到警告 W0722 11 47 35 101842 140641577297728 optimizer v2 py 928 Gradients does not exist for variables model
  • 在 Ubuntu 上导入 matplotlib

    所以我下载并安装了matplotlib 奇怪的是 当它们放置在 home user Desktop 中时 我可以很好地运行这些示例 但是当我将它们移动到 home user Documents 时 它们停止工作 并且我收到以下消息 Docu
  • 拍摄嵌入式 Linux 帧缓冲区的屏幕截图

    我在评估套件 Zoom OMAP35x Torpedo 开发套件 上运行嵌入式 Linux 该板有一个 LCD 我希望能够拍摄屏幕截图并将其转换为 gif 或 png 我可以通过执行以下操作来获取原始数据 cp dev fb0 screen
  • jqgrid搜索/过滤器

    这与我的最新问题有关link https stackoverflow com questions 5775022 edited how to display the searched data on the jgrid 我已经弄清楚错误是什
  • 在 Angular UI Bootstrap 中打开模式时出现 404 Not Found 错误

    我在使用 UI Bootstrap 时遇到一个非常奇怪的问题 即使是最简单的例子也不起作用 这就是我的情况 我有一个使用 yeoman 插件的 Play Framework 应用程序 https github com tuplejump p
  • Python:无法捕获 IndexError

    免责声明 这看起来像是重复的 但找到这个特定问题的答案不仅仅是微不足道的 我希望其他人能更轻松地找到这个问题 答案 当我运行以下代码时 它无法捕获第二个 IndexError 而是引发它 try raise ValueError excep
  • 如何向 Xbox Live Restful API 发送请求?

    我想向 Xbox Live Restful API 的配置文件 URI 和人员 URI 发送请求 我无法理解这两个接口的授权部分 POST 用户 批 配置文件 设置 https learn microsoft com en us windo
  • 在azure构建管道中,一旦推送,如何从自托管代理清理docker镜像(作为管道的一部分创建)?

    我正在使用自托管代理来运行我的构建管道 代理机器已下载基础 docker 映像 管道使用第一个任务构建并推送新的 docker 映像 基于基础映像的顶部 如以下屏幕截图所示 一旦构建了映像并将其推送到容器注册表 我希望从自托管代理中清理映像
  • 覆盖 Django Forms 中的标签

    我有 3 个具有相同字段的部分 除了 标题 字段上的标签 对于所有这些 我都使用相同的 Django 表单 在我的观点中 def get self context self CONTEXT CLASS self MODEL CLASS co
  • 使用 Microsoft 认知语音 API 和非麦克风实时音频流进行语音识别

    Problem 我的项目由一个实时录制音频的桌面应用程序组成 我打算为此接收来自 API 的实时识别反馈 与一个麦克风 使用 Microsoft 新的 Speech to Text API 进行实时实现是微不足道的 我的场景与此的不同之处仅