waveOutWrite 和 waveOutGetPosition 死锁问题

2024-04-17

我正在开发一个使用连续播放音频的应用程序waveOut...API来自winmm.dll。该应用程序使用“leapfrog”缓冲区,它基本上是一堆转储到音频队列中的样本数组。 Windows 按顺序无缝播放它们,并且当每个缓冲区完成时,Windows 调用回调函数。在这个函数中,我将下一组样本加载到缓冲区中,对它们进行处理,然后将缓冲区转储回音频队列中。这样,音频就可以无限播放。

出于动画目的,我正在尝试合并waveOutGetPosition进入应用程序(因为“缓冲完成”回调非常不规则,足以导致动画不稳定)。waveOutGetPosition返回当前播放位置,因此非常精确。

问题是在我的应用程序中,调用waveOutGetPosition最终导致应用程序锁定 - 声音停止并且呼叫永远不会返回。我将事情归结为一个简单的应用程序来演示该问题。您可以在此处运行该应用程序:

http://www.musigenesis.com/SO/waveOut%20demo.exe http://www.musigenesis.com/SO/waveOut%20demo.exe

如果你只是一遍又一遍地听到一点点钢琴声,那就说明它起作用了。这只是为了证明问题。这个项目的源代码在这里(所有的内容都在LeapFrogPlayer.cs中):

http://www.musigenesis.com/SO/WaveOutDemo.zip http://www.musigenesis.com/SO/WaveOutDemo.zip

第一个按钮以蛙跳模式运行应用程序,而无需调用waveOutGetPosition。如果您单击此按钮,应用程序将永远播放而不会中断(X 按钮将关闭它并将其关闭)。第二个按钮启动蛙跳器,并启动一个表单计时器,该计时器调用waveOutGetPosition并显示当前位置。单击此按钮,应用程序将运行一小会儿,然后锁定。在我的笔记本电脑上,它通常会在 15-30 秒内锁定;最多需要一分钟。

我不知道如何解决这个问题,因此非常欢迎任何帮助或建议。我发现关于这个问题的帖子很少,但似乎存在潜在的死锁,无论是多次调用waveOutGetPosition或从调用该和waveOutWrite是同时发生的。我可能调用此函数的频率太高,系统无法处理。

Edit:忘了提及,我在 Windows Vista 上运行它。在其他操作系统上可能根本不会发生这种情况。

Edit 2:除了这些(未答复的)帖子之外,我在网上几乎找不到有关此问题的信息:

http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/thread/c6a1e80e-4a18-47e7-af11-56a89f638ad7 http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/thread/c6a1e80e-4a18-47e7-af11-56a89f638ad7

Edit 3: 嗯,我现在可以随意重现这个问题了。如果我打电话waveOutGetPosition之后立马waveOutWrite(在下面的代码行中)应用程序每次都会挂起。它也以一种特别糟糕的方式挂起 - 它似乎锁定了我的整个操作系统一段时间,而不仅仅是应用程序本身。所以看来waveOutGetPosition如果死锁发生在nearly同时waveOutWrite,不仅仅是字面上的同时,这可能解释了为什么锁对我不起作用。是的。


它在 mmsys API 代码内部陷入死锁。当主线程忙于执行waveOutWrite()时,在回调内调用waveOutGetPosition()会导致死锁。它是可以修复的,您需要一个锁,以便这两个函数不能同时执行。将此字段添加到 LeapFrogPlayer:

    private object mLocker = new object();

并在 GetElapsedMilliseconds() 中使用它:

        if (!noAPIcall)
        {
          lock (mLocker) {
            ret = WaveOutX.waveOutGetPosition(_hWaveOut, ref _timestruct,
                _timestructsize);
          }
        }

和 HandleWaveCallback():

        // play the next buffer
        lock (mLocker) {
          int ret = WaveOutX.waveOutWrite(_hWaveOut, ref _header[_currentBuffer],
              Marshal.SizeOf(_header[_currentBuffer]));
          if (ret != WaveOutX.MMSYSERR_NOERROR) {
            throw new Exception("error writing audio");
          }
        }

这可能有副作用,但我没有注意到。看看NAudio 项目。 http://www.codeplex.com/naudio

下次创建项目的可上传 .zip 时,请使用“构建 + 清理”。

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

waveOutWrite 和 waveOutGetPosition 死锁问题 的相关文章

  • 更改 Android 中的媒体音量?

    我可以更改媒体音量吗 如何 到目前为止我用过这个 setVolumeControlStream AudioManager STREAM MUSIC 但有一个搜索栏并且想要更改媒体音量 而不是铃声音量 那么有人可以告诉我如何更改媒体音量onC
  • 是否可以从 C++ 应用程序调用 C# 应用程序?

    我是一名编程学生 现在我已经上了两门 C 课程 这个学期我将参加我的第一门 C 课程 出于好奇 是否可以从 C 应用程序调用 C 应用程序 如果是的话 是否还可以检查运行该程序的计算机是否具有 NET框架 我只是很好奇 我想如果可能的话 这
  • 无法将 std::min 传递给函数,std::min 的副本有效

    Passing std min函数无法编译 我复制了 libcpp 声明std min进入我的源文件并且它可以工作 std 版本有什么问题 clang 和 gcc 也会发生同样的情况 在 Godbolt 上测试 https godbolt
  • MFC CList 支持复制分配吗?

    我在 MSVC 中查找了 CList 定义afxtempl h http www cppdoc com example mfc classdoc MFC AFXTEMPL H html并记录在MSDN http msdn microsoft
  • 在 ASP.NET MVC 中将模型从视图传递到控制器

    我正在 ASP NET MVC 中开发我的第一个应用程序 但遇到了一个我无法解决的问题 即使在阅读了整个互联网之后也是如此 因此 我有几个使用视图模型创建的视图 它们是报告 这些视图模型是根据用户选择标准填充的 我正在尝试构建一种接受模型并
  • C# 编译器数字文字

    有谁知道 C 编译器数字文字修饰符的完整列表 默认情况下 声明 0 使其成为 Int32 声明 0 0 使其成为 Double 我可以在末尾使用文字修饰符 f 来确保某些内容被视为 Single 例如像这样 var x 0 x is Int
  • 静态类与类的实例

    我有一个静态类 用于访问我的公共属性 整个应用程序的全局属性 和我在应用程序运行期间使用的方法 例如 我在静态类中设置了一些属性 并且在应用程序运行时我可以从属性中获取值 但我可以使用单例模式创建非静态类并以相同的方式使用它 问题 对于我的
  • 你好,我最近正在开发我的新游戏,我遇到了*无限跳跃*的问题

    所以基本上当我按跳跃 空格键时我会跳跃但是如果我连续按空格键它 只是跳啊跳啊跳等等 我不想要我只想它跳一次 code if Input GetKeyDown space isGrounded velocity y Mathf Sqrt ju
  • 通过 C# Mailkit / Mimekit 发送电子邮件,但出现服务器证书错误

    Visual Studio 2015 中的 0 代码 1 我正在使用 Mailkit 最新版本 1 18 1 1 从我自己的电子邮件服务器发送电子邮件 2 电子邮件服务器具有不受信任的自签名证书 3 我在代码中添加了以下两行 以忽略服务器证
  • 使用 C# 中的 Google 地图 API 和 SSIS 包获取行驶距离

    更新 找到了谷歌距离矩阵并尝试相应地修改我的代码 我在这里收到无效参数错误 return new GeoLocation dstnc uri ToString catch return new GeoLocation 0 0 https 基
  • 用于连接 DataTable 上的动态列的动态 LINQ

    我目前遇到的情况不确定如何继续 我有两个从数据库填充的数据表 我还有一个可用的列名称列表 可用于将这两个数据表连接在一起 我希望编写一组 LINQ 查询 这些查询将 显示两个数据表中的行 内部联接 用于从一个数据表更新另一个数据表 显示一个
  • doxygen c++:记录由“using”声明公开的私有继承成员

    作为一个例子 我有以下课程 class A public void methodOne class B private A public Brief description using A methodOne 我还没有找到强制 doxyge
  • ALTER TABLE ... ADD CONSTRAINT 失败时将事务回滚到保存点

    有没有办法在事务中添加检查约束and如果失败回滚到以前的保存点 而不是回滚整个事务 就我而言 当 ALTER TABLE ADD CONSTRAINT 命令失败时 事务无法回滚到保存点 尝试这样做会引发 InvalidOperationEx
  • EnumDisplayDevices 与 WMI Win32_DesktopMonitor,如何检测活动监视器?

    对于我当前的 C 项目 我需要为在大量计算机上连接并处于活动状态的每个监视器检测一个唯一的字符串 研究指出了两种选择 使用 WMI 并查询 Win32 DesktopMonitor 以获取所有活动监视器 使用 PNPDeviceID 来唯一
  • 无法在 C# 中为 EventArgs 分配使用派生类型的事件处理程序

    所以我有一个事件声明如下 public event EventHandler OnChangeDetected 然后我有以下处理程序被分配给该事件 myObject OnChangeDetected OnTableChanged 我的理解是
  • 浮点字节序?

    我正在为实时海上模拟器编写客户端和服务器 并且由于我必须通过套接字发送大量数据 因此我使用二进制数据来最大化可以发送的数据量 我已经了解整数字节顺序以及如何使用htonl and ntohl为了规避字节顺序问题 但我的应用程序与几乎所有模拟
  • Linq.Select() 中的嵌套表达式方法调用

    I use Select i gt new T 每次手动点击数据库后将我的实体对象转换为 DTO 对象 以下是一些示例实体和 DTOS 用户实体 public partial class User public int Id get set
  • 如何将 int 作为“void *”传递给线程启动函数?

    我最初有一个用于斐波那契变量数组的全局变量 但发现这是不允许的 我需要进行基本的多线程处理并处理竞争条件 但我无法在 pthread 创建中将 int 作为 void 参数提供 我尝试过使用常量指针 但没有成功 由于某些奇怪的原因 void
  • 如果“嵌入式”SQL 2008 数据库文件不存在,如何创建它?

    我使用 C ADO Net 和在 Server Management Studio 中创建的嵌入式 MS SQL 2008 数据库文件 附加到 MS SQL 2008 Express 创建了一个数据库应用程序 有人可以向我指出一个资源 该资
  • 嵌入式二进制资源 - 如何枚举嵌入的图像文件?

    我按照中的说明进行操作这本书 http www apress com book view 9781430225492 关于资源等的章节 我不太明白的是 如何替换它 images Add new BitmapImage new Uri Ima

随机推荐

  • 无法在 gitlab-ci runner 上运行最新的 docker

    我正在测试 gitlab ci 并尝试从 Dockerfile 在注册表上生成图像 我有相同的代码只是为了测试 gitlab ci image docker latest tages build deploy build applicati
  • 如何从向量或数组中随机选择一个元素?

    我有一个向量 其中元素是 String String 我如何随机选择这些元素之一 你想要的rand https crates io crates rand 板条箱 特别是choose https docs rs rand 0 7 2 ran
  • 如何从 Laravel 资源控制器中删除 show() 函数

    我的 Laravel 项目中有资源控制器 Route Route resource products ProductsController 在 ProductController 中 我不想使用show id 函数 因为我的项目中不需要这个
  • 未捕获的类型错误:无法读取未定义的属性“draw”

    for var i 0 i lt reduced length i var innerdata for var j 0 j lt days length j var rev 0 each reduced i data function ti
  • 如何替换 Google 云端硬盘中的文件?

    使用以下代码 该代码取自android 快速入门 如果您拍摄多张照片 此代码可以生成多个同名文件 如何修改才能保证同名文件被替换呢 public class MainActivity extends Activity implements
  • 带箭头的线图

    我有一个折线图 我想使用箭头而不是线条来绘制 也就是说 连续的点对之间的线应该是从第一个点到第二个点的箭头 我知道的arrow功能 但这似乎只做单个箭头 在我找到一种方法来尝试使用它来完成整个情节之前 是否有更好的方法来做到这一点 你可以这
  • TortoiseHg无法提交--“系统找不到指定的文件”

    我刚刚选择了 TortoiseHg 用于 Windows 上的分布式源代码控制 并将其安装在我的 C 驱动器上 然后我创建了一个存储库 位于 D projects 中 当我尝试提交更改时 它给了我错误 abort None 系统找不到 指定
  • 应用程序未安装在模拟器上:警告:打开音频输入失败

    我创建了一个 你好 项目 我没有更改 eclipse 生成的默认模板的任何内容 然后我运行了该应用程序 我没有收到任何错误 但是 该应用程序并未安装在模拟器上 环境 windows7 x64 jdk 7u7 windows x64 inst
  • 获取ASP.NET网站用户的MAC

    我正在寻找一种解决方案来查找使用 asp net 网站的用户的 MAC 号码 我知道你可以获得一个IP地址 不知道为什么 但它不会很复杂 但是我可以找出具有该IP的MAC地址吗 编辑 我的意思是在 NET中以编程方式 而不是手动 IP 地址
  • Godoc 文档不输出列表

    在整个项目中 我负责测试和记录 为函数和方法创建了文档 格式如下 CheckPermissionArray checks that values is an array that contains the expectedValue Par
  • Android 模拟器无法在 Eclipse 中启动

    我刚刚安装了整个 shebang 以便在 Eclipse 中开发 Android 应用程序 我运行的是 64 位 gentoo 一切似乎都很顺利 我创建了开发组的 hello world 示例 package com nfshost fly
  • 如何调整 svg 的大小(使用蜡染)并显示它?

    我有一个 100x100 像素的 svg 文件 例如 我正在使用蜡染 如果我做一个 JSVGCanvas svg new JSVGCanvas svg setSize 10 10 它只会显示图片的这一部分 而不显示调整大小的图像 你知道如何
  • 如何在 Core Data 中进行 NSManagedObject 的深度复制

    我正在尝试复制核心数据中现有的 NSManagedObject 和相关子对象 我似乎找不到一个简单的方法来做到这一点 我有一个从核心数据数据库填充的 NSArrayController 我想获取 SelectionIndex 处的对象并进行
  • 从 Zend Framework 2 中的路由获取 $_GET 参数

    Zend Framework 1 有一种非常简单的方法来解析 URL 路由并在 GET 超全局中设置找到的参数以便于访问 当然 您可以在控制器内使用 gt getParam something 但如果在 URL 中找到参数 则它是also可
  • 独立脚本可以为绑定到电子表格的另一个脚本创建触发器吗?

    我正在尝试为电子表格绑定脚本创建一个可安装的 onEdit 触发器 我想使用单独的独立脚本以编程方式执行此操作 根据文档看来这应该是可能的 请注意 与简单的 onOpen 触发器不同 可安装触发器的脚本不需要绑定到电子表格 要从独立脚本创建
  • 今天的google doodle世界博览会是如何实现的? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我想知道它
  • Javascript,CSS:将变换原点更改为手势更改的中心点

    我想将变换原点更改为捏合手势的中心点 此工作代码 safariDevSample 应用缩放和旋转而不改变transform origin window angle 0 global to store data for later reset
  • ValidationError:选项对象无效。复制插件已使用与 API 架构不匹配的选项对象进行初始化

    由于存在漏洞 我刚刚更新了 package json 中的一些包 所有漏洞均已修复 但当我执行 npm run 时出现以下错误 复制插件包在我的漏洞修复过程中得到了更新 我尝试从旧提交中复制 package json 并重新安装所有软件包
  • 对 F# 联合类型列表进行操作

    这是我的问题的延续F 联合类型列表 https stackoverflow com questions 13770911 f list of union types 感谢有用的反馈 我能够创建一个列表Reports with Report要
  • waveOutWrite 和 waveOutGetPosition 死锁问题

    我正在开发一个使用连续播放音频的应用程序waveOut API来自winmm dll 该应用程序使用 leapfrog 缓冲区 它基本上是一堆转储到音频队列中的样本数组 Windows 按顺序无缝播放它们 并且当每个缓冲区完成时 Windo