MMSYSERR_NOMEM при вызове midiInOpen () только когда открыты другие midi-приложения

Я пытаюсь открыть порт MIDI на окнах с помощью midiInOpen. Вызов обычно работает отлично (я использую обертку RtMidi, а код довольно чистый), но он возвращает MMSYSERR_NOMEM, если Ableton Live открыт. У машины осталось достаточно памяти (4 ГБ), и закрытие других приложений, похоже, не имеет никакого эффекта.

Я сталкиваюсь с каким-то внутренним ограничением ресурсов в winmm?

Я запускаю Windows 7 на новой машине Intel NUC, звонки поступают из RtMidi.cpp, и я оборачиваю их в модуль CPython, но больше ничего не делаю. Я опытный разработчик C ++ и могу в этом разобраться, если кто-то укажет путь.

Спасибо!

void MidiInWinMM :: openPort( unsigned int portNumber, const std::string /*portName*/ )
{
if ( connected_ ) {
errorString_ = "MidiInWinMM::openPort: a valid connection already exists!";
error( RtMidiError::WARNING, errorString_ );
return;
}

unsigned int nDevices = midiInGetNumDevs();
if (nDevices == 0) {
errorString_ = "MidiInWinMM::openPort: no MIDI input sources found!";
error( RtMidiError::NO_DEVICES_FOUND, errorString_ );
return;
}

if ( portNumber >= nDevices ) {
std::ostringstream ost;
ost << "MidiInWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid.";
errorString_ = ost.str();
error( RtMidiError::INVALID_PARAMETER, errorString_ );
return;
}

WinMidiData *data = static_cast<WinMidiData *> (apiData_);
MMRESULT result = midiInOpen( &data->inHandle,
portNumber,
(DWORD_PTR)&midiInputCallback,
(DWORD_PTR)&inputData_,
CALLBACK_FUNCTION );
if ( result != MMSYSERR_NOERROR ) {
if(result == MMSYSERR_ALLOCATED) printf("MMSYSERR_ALLOCATED: %i\n", MMSYSERR_ALLOCATED);
if(result == MMSYSERR_BADDEVICEID) printf("MMSYSERR_BADDEVICEID: %i\n", MMSYSERR_BADDEVICEID);
if(result == MMSYSERR_INVALFLAG) printf("MMSYSERR_INVALFLAG: %i\n", MMSYSERR_INVALFLAG);
if(result == MMSYSERR_INVALPARAM) printf("MMSYSERR_INVALPARAM: %i\n", MMSYSERR_INVALPARAM);
if(result == MMSYSERR_NOMEM) printf("MMSYSERR_NOMEM: %i\n", MMSYSERR_NOMEM);
errorString_ = "MidiInWinMM::openPort: error creating Windows MM MIDI input port.";
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
}

// Allocate and init the sysex buffers.
for ( int i=0; i<RT_SYSEX_BUFFER_COUNT; ++i ) {
data->sysexBuffer[i] = (MIDIHDR*) new char[ sizeof(MIDIHDR) ];
data->sysexBuffer[i]->lpData = new char[ RT_SYSEX_BUFFER_SIZE ];
data->sysexBuffer[i]->dwBufferLength = RT_SYSEX_BUFFER_SIZE;
data->sysexBuffer[i]->dwUser = i; // We use the dwUser parameter as buffer indicator
data->sysexBuffer[i]->dwFlags = 0;

result = midiInPrepareHeader( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) );
if ( result != MMSYSERR_NOERROR ) {
midiInClose( data->inHandle );
errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (PrepareHeader).";
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
}

// Register the buffer.
result = midiInAddBuffer( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) );
if ( result != MMSYSERR_NOERROR ) {
midiInClose( data->inHandle );
errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (AddBuffer).";
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
}
}

result = midiInStart( data->inHandle );
if ( result != MMSYSERR_NOERROR ) {
midiInClose( data->inHandle );
errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port.";
error( RtMidiError::DRIVER_ERROR, errorString_ );
return;
}

connected_ = true;
}

0

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]