Microsoft DirectX 9.0

Capturing MIDI

To capture MIDI messages from a device such as a keyboard, create a port for the capture device and use its IDirectMusicPort8::SetReadNotificationHandle method to cause an event to be signaled whenever messages are available to be read. In response to the event, call the IDirectMusicPort8::Read method repeatedly to place pending events into a buffer, until S_FALSE is returned. Each time Read is called, as many events are put into the buffer as are available, or as fit into the buffer. If at least one event was put into the buffer, S_OK is returned.

To retrieve events from the buffer, call the IDirectMusicBuffer8::GetNextEvent method. Each call retrieves a single event, until no more are available, at which point S_FALSE is returned.

The following code fragment illustrates this process. Assume that hEvent was created with CreateEvent and given to the capture port pPort by a call to SetReadNotificationHandle. Assume also that pBuffer was initialized by IDirectMusic8::CreateMusicBuffer.

DWORD    dwGroup;
DWORD    cb;
BYTE    *pb;
DWORD dw = WaitForMultipleObjects(1, hEvent, FALSE, INFINITE);
for (;;)
  hr = pPort->Read(pBuffer);
  if (hr == S_FALSE)
    break;  // No more messages to read into the buffer.
  for (;;)
    hr = pBuffer->GetNextEvent(&rt, &dwGroup, &cb, &pb);
    if (hr == S_OK)
      // pb points to the data structure for the message, and
      // you can do anything that you want with it.
      // pb[0] is the status byte.
      // pb[1] and pb[2] are the data bytes.
    else if (hr == S_FALSE)
      break;  // No more messages in the buffer.
  }  // Done with the buffer.
}  // Done reading pending events.

If you don't want to intercept messages, but simply want to send them from one port to another, you can use the IDirectMusicThru8 interface. See IDirectMusicThru8::ThruChannel for details.