恐る恐るRaspberry Pi PicoのSDKにあるTinyUSBをつかってみたら、恐ろしく簡単にMIDI受信できました。
プロジェクトの作成
pico-sdkのtinyusbにMIDI送信のサンプルプログラムmidi_testがあるので、これをベースにMIDI受信用プロジェクトを作成します。 ファイルの構成は以下の通りです。
usb_midi ├─ CMakeLists.txt ├─ pico_sdk_import.cmake ├─ tusb_config.h ├─ usb_descriptors.c └─ main.c
- 適当な場所にフォルダ作成。今回はusb_midiとしました。
- pico-sdk/lib/tinyusb/examples/device/midi_test/srcにある3つのファイルをusb_midiフォルダにコピーします。
- pico-examples/pico_sdk_import.cmakeをusb_midiフォルダにコピー。
- 以下の内容でCMakeLists.txtを作成。
cmake_minimum_required(VERSION 3.12) # Pull in SDK (must be before project) include(pico_sdk_import.cmake) project(usb_midi C CXX ASM) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) set(PICO_EXAMPLES_PATH ${PROJECT_SOURCE_DIR}) # Initialize the SDK pico_sdk_init() set(CMAKE_C_FLAGS_DEBUG "-O0 -g") add_executable(usb_midi main.c usb_descriptors.c ) target_include_directories(usb_midi PRIVATE ${CMAKE_CURRENT_LIST_DIR}) target_link_libraries(usb_midi PRIVATE pico_stdlib tinyusb_device tinyusb_board) pico_add_extra_outputs(usb_midi) # Copy uf2 when the build is complete add_custom_command( TARGET usb_midi POST_BUILD COMMAND copy ${CMAKE_CURRENT_BINARY_DIR}\\usb_midi.uf2 f:\\ )
MIDI受信用コード
コピーしたサンプルプログラムをそのままビルドすると、シーケンサー的にNoteOn/Offが送信されます。これを変更してNoteOn/Offを受信した時にLEDがついたり消えたりするようにしてみました。
#include "bsp/board.h" #include "tusb.h" void midi_task(void) { uint8_t n_data; uint8_t msg[4]; while (tud_midi_available()) { if (n_data = tud_midi_read(msg, 3)) { switch (0xf0 & msg[0]) { case 0x80: // NoteOff board_led_off(); break; case 0x90: // NoteOn if (msg[2] == 0) board_led_off(); // velocity == 0 --> NoteOff else board_led_on(); break; default: break; } } } } int main(void) { board_init(); tusb_init(); while (1) { tud_task(); // tinyusb device task midi_task(); } return 0; }
tud_midi_available()でデータがあればtud_midi_read()でデータを取り出して、あとはメッセージの種類に応じて処理するだけ。