たま日記

たまに書く

FM音源チップを動かしてみた(3)

ブレッドボード上のYM2151を外し、代わりにYM2414をTX81Zの中の人として動作させる実験を行った。

PC  ->  esp32  ->  YM2414  ->  TX81Zの音色
  1. PCからesp32にレジスタアドレスと書き込む値を送る(シリアル経由)
  2. esp32は受け取ったとおりにYM2414に書き込む
  3. TX81Z実機と同じ音が出ればOK!

受け取る関数はこんな感じ。1byteずつ受け取って、2byte毎に書き込みを行う。esp-idfはArduinoより難しかった…

// app_main()中で
// xTaskCreatePinnedToCore(register_loop, "register", 8192, NULL, 1, &vgmtaskHandle, 1); 
// として動かす
void register_loop() {
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    ESP_ERROR_CHECK(uart_param_config(UART_NUM_0, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
    ESP_ERROR_CHECK(uart_driver_install(UART_NUM_0, 256*2, 0, 0, NULL, 0));

    writeData(0x01, 0x02); // A0のLEDを消すため

    uint8_t buf[256];
    int len = 0;
    uint8_t addr=0, data=0;
    int count = 0;
    while (true) {
        while (uart_read_bytes(UART_NUM_0, buf, 1, 1) > 0) { // 1byte読む
            if (++len % 2 == 1) {
                addr = buf[0];
            } else {
                data = buf[0];
                writeData(addr, data);
            }
        }
        if (++count > 1000) {
            count = 0;
            vTaskDelay(1);
        }
    }
}

TX81Z実機を同じスピーカーにつなげて聴き比べしてみた。ピアノとかギターとかは概ね同じように聞こえるのだが、D11 Hole in 1がノイズまみれになる…?

いろいろパラメータをいじくって分かったのだが、LFO Wave=3(Sample & Hold)の場合は以前調査したLFO Speed変換表とは異なる変換が必要なことが分かった。スピードが速すぎるので、うねりではなくノイズっぽく聞こえるみたい。測定した結果を以前の記事に追記した。

nornand.hatenablog.com

今回の測定では、実機ではなくMAMEのTX81Zエミュレーションを使った。開腹してテストクリップを付けなくても、エミュレーションのレジスタ書き込み時にアドレスとデータをprintf()させることで挙動が観察出来て便利。なんとMIDIキーボードに接続して演奏することもできる!感動的!

ただし、実機で測定したときにはAMDとPMDの値を(LFO Delayのために?)延々と更新しつづけてたような気がするのだが、これはエミュでは観察できなかった。