在 C# 中安全回显 MIDI 数据

发布于 2024-08-04 21:17:39 字数 992 浏览 8 评论 0原文

作为一个业余项目,我正在实现一个 MIDI 矩阵,以将多个 MIDI 键盘与声源互连。这里的关键要求是将输入端口上接收到的 MIDI 数据回显到选定的输出端口。

创建必要的 P/Invoke 声明和包装器,我注意到 MidiInProc 的 Win32 MIDI 文档指出:“应用程序不应从回调函数内部调用任何多媒体函数,因为这样做可能会导致死锁”

鉴于从 MidiInProc 中调用 midiOutShortMsg 是不安全的,我当前的解决方案是将 MIDI 数据写入队列并设置一个事件。工作线程等待该事件并调用 midiOutShortMsg。总体思路是这样的:-

static void InputCallback( int hMidiIn, uint wMsg, uint dwInstance, uint dwParam1, uint dwParam2 )
{
    if( wMsg == MM_MIM_DATA )
    {
        data.EnQueue( dwParam1 );       //data is a Queue<uint>
        dataReady.Set();            //dataReady is AutoResetEvent
    }
}


void ThreadProc
{
    while( !_done )
    {
        dataReady.WaitOne();
        midiOutShortMsg( hMidiOut, data.DeQueue() );
    }
}

然而,虽然这在测试中运行良好,但在调用 dataReady.Set()InputCallBack 之间似乎存在一个机会之窗> 返回期间抢占可能允许工作线程调用 midiOutShortMsg(尽管在另一个线程中)。

这种方法安全吗?

As a side project, I am implementing a MIDI matrix to interconnect a number of MIDI keyboards with sound sources. The key requirement here is to echo MIDI data received on an input port to a selected output port.

Having created the necessary P/Invoke declarations & wrappers, I notice that the Win32 MIDI documentation for MidiInProc states: "Applications should not call any multimedia functions from inside the callback function, as doing so can cause a deadlock".

Given that it is unsafe to call midiOutShortMsg from within a MidiInProc, my current solution is to write MIDI data to a queue and set an event. A worker thread waits on the event and calls midiOutShortMsg. The general idea is this:-

static void InputCallback( int hMidiIn, uint wMsg, uint dwInstance, uint dwParam1, uint dwParam2 )
{
    if( wMsg == MM_MIM_DATA )
    {
        data.EnQueue( dwParam1 );       //data is a Queue<uint>
        dataReady.Set();            //dataReady is AutoResetEvent
    }
}


void ThreadProc
{
    while( !_done )
    {
        dataReady.WaitOne();
        midiOutShortMsg( hMidiOut, data.DeQueue() );
    }
}

However, whilst this has been working fine in testing, there appears to be a window of opportunity between the call to dataReady.Set() and InputCallBack returning during which preemption could allow the worker thread to call midiOutShortMsg (albeit in another thread).

Is this approach safe?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浪漫人生路 2024-08-11 21:17:39

对我来说看起来很安全:即使您的两个线程同时运行,它仍然只有工作线程可能会阻塞,因此这不会导致您的输入回调死锁。

Looks safe to me: even if your two threads are running at the same time, it's still only the worker thread that might block, so this won't deadlock your input callback.

大姐,你呐 2024-08-11 21:17:39

您的问题可能有点针对 StackOverflow 领域。如果这里没有人回答,请查看:http://groups.google .com/group/mididev?hl=en&lnk=

Your question might be a bit domain-specific for StackOverflow. If no one here answers it, check out: http://groups.google.com/group/mididev?hl=en&lnk=

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文