Win32 MIDI API 无限循环和奇怪的延迟需要

问题描述 投票:0回答:0

这是我的 midi sysex 发送/接收函数的代码:

void Send_Sysex_Message (int selected_midi_out_device, int selected_midi_in_device, HWND        dialog_handle, std::string input_text, bool record_input)
{
int midi_in_result=0;
int midi_out_result;
HMIDIOUT midi_out_device;
MIDIHDR temp_midi_out_message;
HMIDIIN midi_in_device;
MIDIHDR temp_midi_in_message;
char midibuffer[270];
int limit_receiving=0;

//set the sysex message
input_text="F0" + Manufacturer_Id + Convert_IntDecimal_To_HexaDecimalString (atoi(Device_Id.c_str())-1) + Model_Id + Command_Id + input_text + Calculate_CheckSum (input_text) +"F7";
//Convert Hexa to Ascii
input_text=Convert_HexaDecimalString_To_AsciiString(input_text);
//set the temp_midi_out_message structure
temp_midi_out_message.dwFlags=0;
temp_midi_out_message.dwBufferLength=input_text.length();
temp_midi_out_message.dwBytesRecorded=0;
temp_midi_out_message.lpData=(LPSTR)input_text.c_str();

if (record_input==1)
{
    //set the temp_midi_in_message structure
    temp_midi_in_message.dwFlags=0;
    temp_midi_in_message.dwBufferLength=sizeof(midibuffer);
    temp_midi_in_message.lpData=(LPSTR) &midibuffer;

    //Opening Midi In Device
    midi_in_result=midiInOpen (&midi_in_device,selected_midi_in_device,(DWORD_PTR)MidiInProc,0, CALLBACK_FUNCTION);
    if (midi_in_result!=MMSYSERR_NOERROR)
    {
       //Get the message error
       midiInGetErrorText(midi_in_result, FileNameBuffer, sizeof(FileNameBuffer));
       //Display the dialog box Common_Message_Dialog
       DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIINFUNCTION);
    }
    else
    {
        //Prepare the midi input buffer
        midi_in_result=midiInPrepareHeader (midi_in_device, &temp_midi_in_message, sizeof(MIDIHDR));
        //Display error message
        if (midi_in_result!=MMSYSERR_NOERROR)
        {
            //Get the message error
            midiInGetErrorText(midi_in_result, FileNameBuffer, sizeof(FileNameBuffer));
            //Display the dialog box Common_Message_Dialog
            DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIINFUNCTION);
        }
        //Add the midi input buffer to queue
        midi_in_result=midiInAddBuffer (midi_in_device, &temp_midi_in_message, sizeof(MIDIHDR));
        //Display error message
        if (midi_in_result!=MMSYSERR_NOERROR)
        {
            //Get the message error
            midiInGetErrorText(midi_in_result, FileNameBuffer, sizeof(FileNameBuffer));
            //Display the dialog box Common_Message_Dialog
            DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIINFUNCTION);
        }
        //Start Midi In Recording
        midi_in_result=midiInStart(midi_in_device);
        //Display error message
        if (midi_in_result!=MMSYSERR_NOERROR)
        {
            //Get the message error
            midiInGetErrorText(midi_in_result, FileNameBuffer, sizeof(FileNameBuffer));
            //Display the dialog box Common_Message_Dialog
            DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIINFUNCTION);
        }
    }

}
//Open Midi Out Device
midi_out_result=midiOutOpen (&midi_out_device,selected_midi_out_device,0,0,CALLBACK_NULL);
if (midi_out_result!=MMSYSERR_NOERROR)
{
    //Get the message error
    midiOutGetErrorText(midi_out_result, FileNameBuffer, sizeof(FileNameBuffer));
    //Display the dialog box Common_Message_Dialog
    DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIOUTFUNCTION);
}
//Prepare the midi output buffer
midi_out_result=midiOutPrepareHeader (midi_out_device, &temp_midi_out_message, sizeof(MIDIHDR));
//Display error message
if (midi_out_result!=MMSYSERR_NOERROR)
{
    //Get the message error
    midiOutGetErrorText(midi_out_result, FileNameBuffer, sizeof(FileNameBuffer));
    //Display the dialog box Common_Message_Dialog
    DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIOUTFUNCTION);
}
//Send the midi output buffer
midi_out_result=midiOutLongMsg(midi_out_device,&temp_midi_out_message, sizeof(MIDIHDR));
//Display error message
if (midi_out_result!=MMSYSERR_NOERROR)
{
    //Get the message error
    midiOutGetErrorText(midi_out_result, FileNameBuffer, sizeof(FileNameBuffer));
    //Display the dialog box Common_Message_Dialog
    DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIOUTFUNCTION);
}
//Sleep for the command to be processed ???
Sleep(20);
//Wait for the buffer to be recorded
while (midiOutUnprepareHeader (midi_out_device, &temp_midi_out_message, sizeof(MIDIHDR))==MIDIERR_STILLPLAYING)
{
    Sleep(100);
}
//Clear the buffer from temp_midi_out_message structure
midi_out_result=midiOutUnprepareHeader (midi_out_device, &temp_midi_out_message, sizeof(MIDIHDR));
//Display error message
if (midi_out_result!=MMSYSERR_NOERROR)
{
    //Get the message error
    midiOutGetErrorText(midi_out_result, FileNameBuffer, sizeof(FileNameBuffer));
    //Display the dialog box Common_Message_Dialog
    DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIOUTFUNCTION);
}
//Closing the actual opened midi Out device
midi_out_result=midiOutClose(midi_out_device);
if (midi_out_result!=MMSYSERR_NOERROR)
{
    //Get the message error
    midiOutGetErrorText(midi_out_result, FileNameBuffer, sizeof(FileNameBuffer));
    //Display the dialog box Common_Message_Dialog
    DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIOUTFUNCTION);
}

if (record_input==1)
{
    if (midi_in_result==0)
    {
        //Wait for the buffer to be recorded
        while (midiInUnprepareHeader (midi_in_device, &temp_midi_in_message, sizeof(MIDIHDR))==MIDIERR_STILLPLAYING )//&& limit_receiving<=10)
        {
            Sleep(100);
            //limit_receiving=limit_receiving+1;
        }
        //Stop Midi In Recording
        midi_in_result=midiInStop(midi_in_device);
        //Display error message
        if (midi_in_result!=MMSYSERR_NOERROR)
        {
            //Get the message error
            midiInGetErrorText(midi_in_result, FileNameBuffer, sizeof(FileNameBuffer));
            //Display the dialog box Common_Message_Dialog
            DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIINFUNCTION);
        }
        //Clear the buffer from temp_midi_in_message structure
        midi_in_result=midiInUnprepareHeader (midi_in_device, &temp_midi_in_message, sizeof(MIDIHDR));
        //Display error message
        if (midi_in_result!=MMSYSERR_NOERROR)
        {
            //Get the message error
            midiInGetErrorText(midi_in_result, FileNameBuffer, sizeof(FileNameBuffer));
            //Display the dialog box Common_Message_Dialog
            DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIINFUNCTION);
        }
        //Closing the actual opened midi in device
        midi_in_result=midiInClose(midi_in_device);
        //Display error message
        if (midi_in_result!=MMSYSERR_NOERROR)
        {
            //Get the message error
            midiInGetErrorText(midi_in_result, FileNameBuffer, sizeof(FileNameBuffer));
            //Display the dialog box Common_Message_Dialog
            DialogBoxParam((HINSTANCE) GetWindowLong(dialog_handle, GWL_HINSTANCE),MAKEINTRESOURCE(ID_COMMONMESSAGEDIALOG) ,dialog_handle , Common_Message_Dialog_Procedure,MIDIINFUNCTION);
        }
    }    
}
}`

我有两个主要问题:

  • 在 midi 输出消息之后,即使我接下来测试 midiOutUnprepareHeader 的仍在播放状态,我也需要根据 sysex 的长度添加 5 到 25 毫秒的睡眠时间?
  • 如果没有 midi 输入,我会无休止地停留在 midiInUnprepareHeader while 循环中?

提前致谢, 祝你有美好的一天, Rgds,

对于 while 循环中的 midi,我添加了一个最大循环变量,但我在 midiinclose 上遇到了同样的错误。

winapi midi
© www.soinside.com 2019 - 2024. All rights reserved.