问题waveOutWrite和waveOutGetPosition僵局 [英] Problem with waveOutWrite and waveOutGetPosition deadlock

查看:443
本文介绍了问题waveOutWrite和waveOutGetPosition僵局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从 WINMM.DLL waveout的... API的应用程序>。应用程序使用蛙跳的缓冲区,这基本上是一帮您转储到音频队列样本的阵列。窗口播放它们无缝顺序,并在每个缓冲完成Windows调用回调函数。在这个函数中,我的下一个样本集加载到缓冲器中,但处理它们,然后转储缓冲器放回音频队列。在这种方式中,音频播放无限期

I'm working on an app that plays audio continuously using the waveOut... API from winmm.dll. The app uses "leapfrog" buffers, which are basically a bunch of arrays of samples that you dump into the audio queue. Windows plays them seamlessly in sequence, and as each buffer completes Windows calls a callback function. Inside this function, I load the next set of samples into the buffer, process them however, and then dump the buffer back into the audio queue. In this way, the audio plays indefinitely.

有关动画的目的,我试图将 waveOutGetPosition 进入应用程序(因为缓冲完成回调是足够的不规则导致生涩的动画)。 waveOutGetPosition 返回播放的当前位置,所以它的hyper- precise。

For animation purposes, I'm trying to incorporate waveOutGetPosition into the application (since the "buffer done" callbacks are irregular enough to cause jerky animation). waveOutGetPosition returns the current position of playback, so it's hyper-precise.

问题是,在我的应用程序,使得以 waveOutGetPosition 通话最终导致锁定应用程序 - 声音停止,呼叫永远不会返回。我煮的东西到一个简单的应用程序演示该问题。你可以在这里运行的应用程序:

The problem is that in my application, making calls to waveOutGetPosition eventually causes the application to lock up - the sound stops and the call never returns. I've boiled things down to a simple app that demonstrates the problem. You can run the app here:

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

如果你只是听到钢琴的一点点了个遍,它的工作。这只是为了说明问题。该人士$ ​​C $ C这个项目是在这里(所有的肉是LeapFrogPlayer.cs):

If you just hear a tiny bit of piano over and over, it's working. It's just meant to demonstrate the problem. The source code for this project is here (all the meat is in LeapFrogPlayer.cs):

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

第一个按钮在运行模式跨越应用程序未做调用 waveOutGetPosition 。如果单击此,应用程序将永远打不破(X按钮将其关闭,并关闭它)。第二个按钮启动leapfrogger也启动一个定时器形式调用 waveOutGetPosition 并显示当前位置。点击后程序会运行很短的一段时间,然后锁定。在我的笔记本电脑,它通常是在15-30秒锁定了;顶多它采取一分钟。

The first button runs the app in leapfrog mode without making the calls to waveOutGetPosition. If you click this, the app will play forever without breaking (the X button will close it and shut it off). The second button starts the leapfrogger and also starts a forms timer that calls the waveOutGetPosition and displays the current position. Click this and the app will run for a short while and then lock up. On my laptop, it usually locks up in 15-30 seconds; at most it's taken a minute.

我不知道如何解决这个问题,所以任何帮助或建议将是最受欢迎的。我发现在这个问题上非常少的职位,但似乎有一个潜在的僵局,无论是从多次调用 waveOutGetPosition 或调用的和 waveOutWrite 发生在同一时间。这可能是我打电话这种过于频繁的系统来处理。

I have no idea how to fix this, so any help or suggestions would be most welcome. I've found very few posts on this issue, but it seems that there is a potential deadlock, either from multiple calls to waveOutGetPosition or from calls to that and waveOutWrite that occur at the same time. It's possible that I'm calling this too frequently for the system to handle.

修改:忘了提,我在Windows Vista上运行此。这可能不能在其他操作系统都发生了。

Edit: forgot to mention, I'm running this on Windows Vista. This might not happen at all on other OSes.

编辑2 :我发现一些关于这个问题网上,除了这些(未)的帖子:

Edit 2: I've found little about this problem online, except for these (unanswered) posts:

<一个href=\"http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/thread/c6a1e80e-4a18-47e7-af11-56a89f638ad7\" rel=\"nofollow\">http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/thread/c6a1e80e-4a18-47e7-af11-56a89f638ad7

修改3 :好了,我现在可以随心所欲地重现此问题。如果我称之为 waveOutGetPosition 应用程序挂起每次后立即 waveOutWrite (以下行code的)。它也挂在一个特别糟糕的方式 - 它似乎锁定了我的一段时间整个操作系统,而不仅仅是应用程序本身。所以看来 waveOutGetPosition 死锁如果发生在的的同一时间 waveOutWrite ,不只是字面上的同时,这或许可以解释为什么锁不会为我工作。 Yeesh。

Edit 3: Well, I'm now able to reproduce this problem at will. If I call waveOutGetPosition immediately after waveOutWrite (in the following line of code) the application hangs every time. It also hangs in an especially bad way - it seems to lock up my whole OS for awhile, not just the app itself. So it appears that waveOutGetPosition deadlocks if it occurs at nearly the same time as waveOutWrite, not just literally at the same time, which might explain why the locks aren't working for me. Yeesh.

推荐答案

解决这个问题的解决方案是非常简单的(感谢拉里·奥斯特曼):有取而代之的WndProc回调

The solution to this was very simple (thanks to Larry Osterman): replace the callback with a WndProc.

该waveOutOpen方法可以或者委托(回调)或窗口句柄。我用的是委托的方式,这显然是天生容易出现死锁(是有道理的,尤其是在管理code)。我可以简单地拥有我的播放器类继承控制并重写的WndProc 方法,做同样的东西在这个方法我在做回调。现在,我可以叫 waveOutGetPosition 永远和它永远不会锁定。

The waveOutOpen method can take either a delegate (for callback) or a window handle. I was using the delegate approach, which is apparently inherently prone to deadlocking (makes sense, especially in managed code). I was able to simply have my player class inherit from Control and override the WndProc method, and do the same stuff in this method that I was doing in the callback. Now I can call waveOutGetPosition forever and it never locks up.

这篇关于问题waveOutWrite和waveOutGetPosition僵局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆