Безопасное отображение MIDI-данных в C # - PullRequest
3 голосов
/ 21 сентября 2009

В качестве побочного проекта я реализую матрицу MIDI для соединения нескольких клавиатур MIDI с источниками звука. Ключевым требованием здесь является эхо MIDI-данных, полученных на входном порте, на выбранный выходной порт.

Создав необходимые объявления и оболочки P / Invoke, я заметил, что документация Win32 MIDI для MidiInProc гласит: «Приложения не должны вызывать какие-либо мультимедийные функции изнутри функции обратного вызова, поскольку это может вызвать тупик» .

Учитывая, что небезопасно вызывать midiOutShortMsg из MidiInProc, мое текущее решение - записать 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 (хотя и в другая тема).

Этот подход безопасен?

Ответы [ 2 ]

3 голосов
/ 21 сентября 2009

Мне кажется безопасным: даже если два ваших потока работают одновременно, блокировать может только рабочий поток, так что это не заблокирует входной обратный вызов.

1 голос
/ 21 сентября 2009

Ваш вопрос может быть немного специфичным для домена для StackOverflow. Если здесь никто не отвечает, проверьте: http://groups.google.com/group/mididev?hl=en&lnk=

...