Могу ли я отправить необработанные байты на MIDI-устройство?

#c# #winapi #midi

#c# #winapi #миди #midi

Вопрос:

Я получаю поток MIDI-данных в реальном времени из именованного канала, по одному байту за раз.

Я хотел бы переслать эти данные по мере их получения на MIDI-устройство. Я знаком с кодированием WinAPI / взаимодействием для MIDI в C #.

К сожалению, функция WinAPI midiOutShortMsg требует, чтобы я сначала собрал свои байты в допустимые MIDI-сообщения. Я бы хотел избежать этого и просто отправлять необработанные байты по мере их получения из канала.

Есть ли функция WinAPI MIDI, которую я упустил из виду? Или что-то еще в более широком WinAPI, что дало бы мне низкоуровневый доступ к MIDI-устройству, чтобы я мог отправлять необработанные байты?

Примечание: Я исследовал набор функций midiStream, и они представляют собой ту же проблему, что и выше.

Дополнительный фоновый контекст…

Для тех, кому может быть интересно, что я делаю с MIDI-данными по именованному каналу…

Я все еще сочиняю и продюсирую музыку на ПК с Windows 3.1 под управлением Cakewalk Pro и Encore. Точно так же, как я делал примерно в 1994 году. Когда я говорю ПК, я на самом деле имею в виду виртуальную машину VirtualBox.

На виртуальном ПК установлен драйвер Roland Serial MIDI, который обеспечивает 2×16 каналов MIDI-вывода и 1×16 каналов MIDI-ввода через последовательный порт. VirtualBox настолько любезен, что позволяет нам общаться / прослушивать виртуальные последовательные порты через именованные каналы. Большое спасибо VirtualBox за реализацию такой полезной функции.

Итак, в двух словах: я получаю MIDI-данные с виртуального ПК через именованный канал, обслуживаемый VirtualBox. Я хотел бы переслать эти данные на реальное MIDI-устройство на главном компьютере.

Пример потока MIDI

F5 02 90 3C 7F 40 7F 43 7F 80 3C 00 40 00 43 00

Те, кто знаком с MIDI-сообщениями, могут заметить, что F5 02 сообщение нестандартное, это способ Roland «переключать» группы деталей, в приведенном выше примере Roland SC-88 будет знать, что последующие данные предназначены для группы деталей B. Если бы это было так, F5 01 это означало бы группу частей A.

Кроме того, приведенные выше данные демонстрируют состояние выполнения, где байты состояния могут быть опущены для экономии пропускной способности. Весело.

Как вы можете видеть, было бы неплохо просто отправить необработанные байты на MIDI-устройство. Но с WinAPI, похоже, мне приходится обрабатывать байты в полные MIDI-сообщения перед их отправкой. WinAPI загоняет вас в это поле. И это означает необходимость закодировать небольшой конечный автомат для обработки состояния выполнения и системного индекса и, возможно, других деталей, о которых я еще не подумал. Я люблю Windows, но иногда это делает то, что должно быть супер простым, супер сложным.

Поэтому я подумал, что спрошу здесь, чтобы посмотреть, есть ли простой способ, прежде чем тратить время на то, чтобы сделать это трудным способом.

Комментарии:

1. Вы пробовали какой-либо из доступных пакетов midi nuget? github.com/atsushieno/managed-midi есть такой пример output.Send(new byte [] {0xC0, GeneralMidi.Instruments.AcousticGrandPiano}, 0, 2, 0);

2. Вам приходится делать то, чего вы не хотите делать. Это не особенно сложно , но вы, конечно, сначала подумали бы о том, чтобы исправить этот канал.

3. Я автор DryWetMIDI и у меня есть некоторые функции для преобразования отдельных MIDI-событий из / в байты. Но ваш случай немного отличается. Не могли бы вы, пожалуйста, показать пример массива bytes и описать вашу систему более подробно?

4. @Jason спасибо за ссылку, да, я проверил это на уровне исходного кода, и сталкиваюсь с аналогичным ограничением, вы не можете просто отправлять произвольные байты, вы должны отправлять правильно сформированные сообщения.

5. @Maxim Я обновил свой вопрос, добавив больше деталей. Кстати, я посмотрел на DryWetMIDI, отличная работа!