【问题标题】:MMSYSERR_NOMEM when calling midiInOpen() only when other midi apps are openMMSYSERR_NOMEM 仅在其他 midi 应用程序打开时调用 midiInOpen()
【发布时间】:2014-12-10 18:00:13
【问题描述】:

我正在尝试使用 midiInOpen 在 Windows 上打开一个 midi 端口。该调用通常效果很好(我正在使用 RtMidi 包装器,并且代码非常干净),但如果 Ableton Live 已打开,它会返回 MMSYSERR_NOMEM。机器还有很多内存(4GB),关闭其他应用程序似乎没有任何效果。

我是否在 winmm 中遇到某种内部资源限制?

我在新的英特尔 NUC 机器上运行 Windows 7,调用来自 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;
}

【问题讨论】:

  • 这来自设备驱动程序。也许你有一个不稳定的,也许 Ableton 修补它。当然,您对此无能为力。
  • 这是什么设备驱动程序? WDM,还是自定义驱动程序?
  • Gotchya,它是一个 RME 接口。众所周知,RME 拥有业内最好和最快的驱动程序,因为他们特别重视软件质量。这是否回答了您的问题,或者我是否需要弄清楚它是否属于某个驱动程序类(如果那是 WDM 是什么......),不管作者是谁?
  • 或者这种问题只能由 RME 驱动的作者来回答?
  • 这里有同样的问题。您是否设法解决了这个问题?

标签: c++ windows midi winmm


【解决方案1】:

我在命令行工具中调用midiInOpen 函数时遇到了同样的错误(这就是我在这里的原因)并发现这是因为我有另一个(也是命令行)连接到我的 midi 设备同时连接。

当我关闭第一个时,我能够再次在主应用程序中打开它。

在您的情况下,它是保持连接的 Ableton。我不是专家,但我相信,您可以将设备仅连接到一个应用程序。

【讨论】:

    猜你喜欢
    • 2023-01-28
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多