いつものようにまずはリバーブから。
割込みでADしている関係でサンプリング周波数は22,050Hz。DMAでごにょごにょできればもう少し周波数をあげられるのではないかと。DACが一つなので出力はモノラル。
Arduino UNO R4はCPUも変わったしDACも搭載されてるってことで、エフェクター的なものにトライ。とりあえずADしてDAするだけのスルー状態で盛大にノイズ出てますけど、明日の自分のためにメモ。物忘れがひどい…
逆相とMIXすることで、ヒュイィーンという刺激的なノイズは減少してホワイトノイズっぽくなったけど、まだまだノイズ多し
フィルタと電源あたりは後でキチンと考える
#include "AGTimerR4.h" #define FREQ_SAMPLING 22050.0f #define ADC_RESOLUTION 14 #define DAC_RESOLUTION 12 #define DAC_OFFSET 2048 volatile bool samplingStat = false; void timerCallback() { samplingStat = true; } void setup() { analogReadResolution(ADC_RESOLUTION); analogWriteResolution(DAC_RESOLUTION); AGTimer.init(FREQ_SAMPLING, timerCallback); AGTimer.start(); } void loop() { while(!samplingStat); int rd = analogRead(A1) - analogRead(A2); int wd = signalProcessing(rd); analogWrite(DAC, (wd >> (ADC_RESOLUTION - DAC_RESOLUTION + 1)) + DAC_OFFSET); samplingStat = false; } int signalProcessing(int rd) { return rd; }
バッファリングしてDMAでドカドカと転送できるように後で検討(後でが多い)
Arduino UNO R4 で タイマー割り込みを処理するだけのライブラリを作りました。
あれこれ調べた結果は別エントリーにまとめます(多分)
init(period, div, timerCallback)
この関数のdivで有効な値は以下の4つです。
ただTIMER_SOURCE_DIV_64のときだけトリッキーな動きをするので、他の2つのinit()を使うのが安心です(今のところ)
Processingでファイル選択ダイアログを使用する方法をメモっておきます。 入力はselectInput()、出力はselectOutput()でダイアログを表示。ファイル選択後はコールバック関数が呼び出されます。
selectInput(prompt, callback)
selectOutput(prompt, callback)
※ 詳しい設定はselectInputのリファレンスとselectOutputのリファレンスを参照
ありません
callback(File selection)
ダイアログをキャンセルしたり閉じたりした場合にはselectionはnull、選択された場合にはselection.getAbsolutePath()でフルパスが取得できます
ウィンドウをクリックするとファイル出力ダイアログが表示されます。
void setup() { size(400,400); } void draw() { } void mousePressed() { selectOutput("Select a file to process:", "fileSelected"); } void fileSelected(File selection) { if (selection == null) { println("Window was closed or the user hit cancel."); } else { println("User selected " + selection.getAbsolutePath()); } }
恐る恐る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
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:\\ )
コピーしたサンプルプログラムをそのままビルドすると、シーケンサー的に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()でデータを取り出して、あとはメッセージの種類に応じて処理するだけ。
そこそこ苦労してC++用の開発環境を構築し終えたあたりで、Arduino IDEがpicoをサポートしたという情報をキャッチしたわけで…。試してみました。使用したArduinoIDEのバージョンは1.8.13です。
2021年4月24日現在、2種類のpico用の追加ボードがあります。
2がArduino公式サポート版のようですが、先行して発表された1の方が完成度が高い感じがします。
まずは1のRaspberry Pi Pico/RP2040の方から。
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
を追加片一方だけインストールすれば事足りますけど、もう一つのArduino Mbed OS RP2040 Boardsも。
2つを比較すると、公式の方が若干コンパイルが早いような気がします。先日構築したC++の開発環境に比べると圧倒的に遅いですけど…。
サンプルの充実度、ボードの設定パラメータの豊富さ、自動的に本体をマウントして実行まで進むあたりを考えるとRaspberry Pi Pico/RP2040の方を使うかなー。
Mbedがよくわかってないんですが、公式の方はMbedのライブラリ等の資産が使えたりとか多大なメリットがあるんでしょうか?
PCM5102Aとつないでsineが問題なく出力できたわけですが、 もう一つDACコレクションの中からUDA1334A を引っ張り出してきて試してみました。
使用したDACボードはデフォルトでI2Sフォーマット(SF0とSF1がLOW)なので、PCM5102Aの時と同様3本接続するだけです。
GP26 ---> BCLK GP27 ---> WSEL GP28 ---> DIN
こちらも問題なし! と思ったんですけど、PCM5102Aの時と比べると振幅が半分…。要調査ですね。