在MIDI回调功能中播放声音

时间:2014-08-19 12:04:30

标签: c++ midi

我得到了一小段代码,现在工作正常。但是我想在回调函数中播放声音,但是我在MSDN页面中读到了:

  

“应用程序不应该从回调函数内部调用任何多媒体函数,因为这样做会导致死锁。可以安全地从回调中调用其他系统函数。”

我对编程很陌生,我的问题是:如何解决这个问题,并且当MIDI键被击中时仍能播放声音。

#include<iostream>
#include<cstdlib>
#include<windows.h>
#include<Mmsystem.h>
#include<stdio.h>
using namespace std;

void CALLBACK midiCallback(HMIDIIN handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
    {
    switch (uMsg)
        {
        case MIM_OPEN:
             cout << "-----OPENED.-----" << endl;
             break;
        case MIM_CLOSE:
             cout << "-----EVERYTHING IS CLOSING.-----" << endl;
             break;
        case MIM_DATA:
             cout << "-----APPARENTLY THERE I5 DATA.-----" << endl;
             break;
        case MIM_LONGDATA:
             cout << "-----LONGDATA'D.-----" << endl;
             break;
        case MIM_ERROR:
             cout << "-----ERROR.-----" << endl;
             break;
        case MIM_LONGERROR:
             cout << "-----LONGERROR.  EVEN WORSE.-----" << endl;
             break;
        }
         cout << "dwInstance is " << dwInstance << endl;
         cout << "Handle is " << handle << endl;
         cout << "dwParam1 is " << dwParam1 << endl; //dwParam1 is the bytes of the MIDI Message packed into an unsigned long
         cout << "dwParam1_hiword is " << HIWORD(dwParam1) << endl; //velocity
         cout << "dwParam1_loword is " << LOWORD(dwParam1) << endl; //keyID
         cout << "dwParam2 is " << dwParam2 << endl; //dwParam2 is the timestamp of key press
         cout << "uMsg is " << uMsg << endl;
         cout << "-----" << endl;
    }


void MidiThing() {
        MIDIINCAPS     mic;

        unsigned long result;
        HMIDIIN      inHandle;

        unsigned long    iNumDevs, i;
        iNumDevs = midiInGetNumDevs();  /* Get the number of MIDI In devices in this computer */

        /* Go through all of those devices, displaying their names */
        for (i = 0; i < iNumDevs; i++)
        {
            /* Get info about the next device */
            if (!midiInGetDevCaps(i, &mic, sizeof(MIDIINCAPS)))
            {
                /* Display its Device ID and name */
                cout << "Device ID [" << i << "]: " << mic.szPname << endl;
            }
        }
        cout << endl;

        // Open the default MIDI In device. (DevID 0)
        result = midiInOpen(&inHandle, 0, (DWORD)midiCallback, 0, CALLBACK_FUNCTION);

        if (result != MMSYSERR_NOERROR) {
            cout << "midiInOpen() failed...rv= " << result << endl;
        }
        else
        {
            midiInStart(inHandle);

        }

         cout << endl;
         cout << "Press \"ESC\" to quit." << endl;
           while (1) {
                if (GetAsyncKeyState(VK_ESCAPE))
                {
                    break;
                    cout << "exit=true." << endl;
                }
                Sleep(100);
           }

         midiInStop(inHandle);
         midiInReset(inHandle);
         midiInClose(inHandle);

         cout << endl;
         cout << inHandle << " was the MIDIIN handle." << endl;
         cout << endl;
         cout << "MIDI is closed now." << endl;
}

int main(int argc, char *argv[])
{
    MidiThing();
    cout << "Exit is success." << endl;
    return EXIT_SUCCESS;
}  

1 个答案:

答案 0 :(得分:2)

从回调中唤醒另一个线程。