Pergunta

Estou escrevendo um programa Windows usando o C ++ e a API do Windows e estou tentando fazer fila de mensagens MIDI em um fluxo MIDI, mas estou recebendo um erro estranho quando tento fazê -lo. Se eu usar midiOutShortMsg Para enviar uma mensagem MIDI não para o fluxo, ele funciona corretamente. No entanto, midiStreamOut sempre retorna o código de erro 68, que é #defined para MCIERR_WAVE_OUTPUTUNSPECIFIED. midiOutGetErrorText fornece a seguinte descrição do erro:

A configuração atual do MIDI do MIDI refere -se a um dispositivo MIDI que não está instalado no sistema. Use MIDI Mapper para editar a configuração.

Estou usando o Windows 7 (64 bits) e tentei abrir o fluxo MIDI com IDs de dispositivo de Midi_mapper e todos os quatro dispositivos de saída MIDI no meu sistema e ainda recebo exatamente a mesma mensagem de erro.

Aqui está o código para abrir o fluxo MIDI:

UINT device_id = MIDI_MAPPER; //Also tried 0, 1, 2 and 3
midiStreamOpen( &midi, &device_id, 1, ( DWORD_PTR )hwnd, 0, CALLBACK_WINDOW );

Aqui está o código para enviar a mensagem MIDI:

MIDIHDR header;
MIDIEVENT *event;

event = ( MIDIEVENT * )malloc( sizeof( *event ) );
event->dwDeltaTime = delta_time;
event->dwStreamID = 0;
event->dwEvent = ( MEVT_F_SHORT | MEVT_SHORTMSG ) << 24 | ( msg & 0x00FFFFFF );

header.lpData = ( LPSTR )event;
header.dwBufferLength = sizeof( *event );
header.dwBytesRecorded = sizeof( *event );
header.dwUser = 0;
header.dwFlags = 0;
header.dwOffset = 0;

midiOutPrepareHeader( ( HMIDIOUT )midi, &header, sizeof( header ) );
midiStreamOut( midi, &header, sizeof( header ) );

Como posso resolver esse problema?

Foi útil?

Solução

O problema era que eu estava usando toda a estrutura do evento como buffer do fluxo MIDI. Acontece que o quarto membro da estrutura, dwParms, deve realmente ser omitido de mensagens curtas. Para corrigir o código na pergunta publicada, duas das linhas de código podem ser alteradas para o seguinte:

header.dwBufferLength = sizeof( *event ) - sizeof( event->dwParms );
header.dwBytesRecorded = sizeof( *event ) - sizeof( event->dwParms );

Ao adicionar vários eventos ao fluxo, é realmente muito mais fácil usar uma matriz de DWORDs em vez de se incomodar com o MIDIEVENT estruturas.

Para qualquer outra pessoa que faça programação MIDI usando a API do Windows, tenha cuidado que parte da documentação do MSDN seja enganosa, inadequada ou completamente errada.

A documentação para o MIDIEVENT estrutura diz o seguinte:

dwparms

Se o dwevent especificar mevt_f_short, não use este membro no buffer de fluxo.

Isso é ambíguo porque não está claro que "uso" se destina a significar "incluir" em vez de "especificar".

Aqui estão duas outras falhas na documentação que os programadores precisam estar cientes de:

Dwevent

Código do evento e parâmetros de evento ou comprimento. [...] O byte alto deste membro contém sinalizadores e um código de evento. O sinalizador mevt_f_long ou mevt_f_short deve ser especificado. O sinalizador mevt_f_callback é opcional.

Quando os arquivos do cabeçalho são verificados, o MEVT_F_ Definições de pré -processador realmente especificam completo DWORDS, em vez de apenas as bandeiras individuais; portanto, no meu código, a linha especificando esse membro deveria ter sido a seguinte:

event->dwEvent = MEVT_F_SHORT | MEVT_SHORTMSG << 24 | ( msg & 0x00FFFFFF );

Além disso, também aconteceu que a memória que contém a estrutura MIDIHDR deve ser mantida até que o buffer termine de reproduzir, para que seja alocado na pilha, em vez da pilha para a maioria das implementações.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top