首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WinMM图书馆问题

WinMM图书馆问题
EN

Stack Overflow用户
提问于 2009-04-02 17:01:35
回答 1查看 1.8K关注 0票数 0

我编写了一个WinMM库包装库,它公开了WaveOut和WaveIn类,以便记录和播放原始音频流。

一切都很好,但是为了遵循关于如何处理已完成的缓冲区的操作系统规范,我添加了一个线程来解除缓冲区的准备并释放内存。我还关闭了所有的同步,这样类才是可靠的和线程安全的。

但是,似乎存在一个罕见的问题:我向WaveOut设备添加了一个缓冲区,操作系统返回了一个成功的代码,但是如果设备在结束后立即重置,操作系统不会将缓冲区标记为已完成并将其返回给应用程序。

它似乎正在失去缓冲。因此,问题在于,我正在跟踪发送到设备的单个缓冲区的数量,并阻止将Close()函数连接到清理它们的线程。

有什么想法吗?还是已知的虫子?

PS:这似乎并不发生在Vista的四核上,而是发生在我的XP pro的双核上。

EDIT1:一旦上传并在codeplex上获得了属性许可,我完全愿意公开完整的源代码,如果这对任何人都有帮助的话。

EDIT2:将库张贴到CodePlex:

以下是造成这一问题的原因:

代码语言:javascript
复制
public partial class MainView : Form
{
    private WaveIn waveIn = new WaveIn(WaveIn.WaveInMapperDeviceId);
    private WaveOut waveOut = new WaveOut(WaveOut.WaveOutMapperDeviceId);

    public MainView()
    {
        InitializeComponent();

        WaveFormat format = WaveFormat.Pcm44Khz16BitMono;

        waveOut.Open(format);

        waveIn.DataReady += new EventHandler<DataReadyEventArgs>(WaveIn_DataReady);

        // Tweaking these values affects the internal buffering thread.
        // Setting too small of a QueueSize with too small of a BufferSize
        //  will cause buffer underruns, which will sound like choppy audio.
        waveIn.BufferQueueSize = 200;
        waveIn.BufferSize = 64;

        waveIn.Open(format);

        waveIn.Start();
    }

    void WaveIn_DataReady(object sender, DataReadyEventArgs e)
    {
        if (waveOut != null)
        {
            lock (waveOut)
            {
                // We have to check for null after the lock,
                //  because waveOut may have been disposed
                //  inside another lock.
                if (waveOut != null)
                {
                    waveOut.Write(e.Data);
                }
            }
        }
    }

    private void MainView_FormClosed(object sender, FormClosedEventArgs e)
    {
        if (waveIn != null)
        {
            lock (waveIn)
            {
                waveIn.Dispose();
                waveIn = null;
            }
        }

        if (waveOut != null)
        {
            lock (waveOut)
            {
                waveOut.Dispose();
                waveOut = null;
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2009-04-23 19:17:28

我首先要创建一个单独的object来锁定它。这应该会简化大量的空检查逻辑(因为您检查了锁的前后,大约减少了一半)。

其次,Dispose不会将变量设置为null,因此其他检查仍然会通过,因为对象不是null,只有已释放。所以我会这么做

代码语言:javascript
复制
waveOut.Dispose();
waveout = null;

以确保将其明确设置为null。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/710650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档