https://www.notyet-maker.com/2026/01/xiao-esp32s3-2.html
の続き。
1. ESP32S3+MAX98357Aでは「素材音」まで
2. MX MIDI Guitarの“鳴らし方”だけを真似る
3. ESP32S3側でクリーン音を整え、Slash寄りにする。
という3段階の2段階目。
ChatGPTによると、
---
2. では、MX MIDI Guitarの音そのものは作らない。
真似るのは「弾いた瞬間の反応」「減衰の仕方」「揺れの入り方」だけ。
3.で、初めて音としてギターっぽくする。
その方向性の一例が「Slash寄り」。
---
とのこと。
今度はスムーズに、Codexがコードを生成してくれた。
そこそこクリアな音になった。
///
import time, math
import board, audiobusio, synthio
SAMPLE_RATE = 18000
AMP = 0.05
ATTACK = 0.01
DECAY = 0.20
SUSTAIN = 0.25
RELEASE = 0.25
NOTE_ON_SEC = 0.35
NOTE_GAP_SEC = 0.25
VIB_ON = True
VIB_DELAY = 0.08
VIB_RATE = 5.0
VIB_CENTS = 5.0
VIB_STEP = 0.01
i2s = audiobusio.I2SOut(board.D6, board.D3, board.D7)
synth = synthio.Synthesizer(sample_rate=SAMPLE_RATE)
i2s.play(synth)
env = synthio.Envelope(attack_time=ATTACK, decay_time=DECAY, sustain_level=SUSTAIN, release_time=RELEASE)
notes = [261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]
def cents_to_ratio(cents):
return 2 ** (cents / 1200.0)
def play_note(freq):
note = synthio.Note(frequency=freq, envelope=env, amplitude=AMP)
synth.press(note)
start = time.monotonic()
while time.monotonic() - start < NOTE_ON_SEC:
if VIB_ON and (time.monotonic() - start) > VIB_DELAY:
t = time.monotonic()
ratio = cents_to_ratio(math.sin(2 * math.pi * VIB_RATE * t) * VIB_CENTS)
note.frequency = freq * ratio
time.sleep(VIB_STEP)
synth.release(note)
time.sleep(NOTE_GAP_SEC)
while True:
for f in notes:
play_note(f)
///
続いて、
3. ESP32S3側でクリーン音を整え、Slash寄りにする。
に進む。
AdafruitsのMX MIDI Guitarの音色を、ESP32S3+synthio で再構成するには、
下記が必要とのこと。
---
(1) ピッキング直後 5〜15ms の非周期成分を必ず入れる
- ノイズを足すのではなく
- 位相が少し乱れた「壊れた周期波形」を使う
- 振幅は上げない
(2) アタックの時間構造を作る
- 無音に近い状態(2〜6ms)
- → 非周期成分(5〜15ms)
- → 通常の周期波形
この順序を必ず守る
(3) ピッキング位置差を入れる
- 毎ノートごとに
- 3次/5次倍音の係数
- 非線形量
を「ごく小さく」ランダムに変える
- 均質な音を禁止する
(4) その後にだけ
- 非線形の減衰
- 遅延ビブラート
---
が、これは、REPLでは実行できないらしい。
---
(1)(2) は「数 ms 単位で同じ処理を回し続ける」必要がある
→ 時間を追いかけるループ(while)が必須。
(3) は「1ノート分の処理をひとまとまりで保持する」必要がある
→ 波形生成・係数決定・発音制御を同一ブロックで扱う必要がある。
(4) は「前段の状態を引き継いで後段に遷移する」必要がある
→ 状態(フェーズ)を保持しながら条件分岐を繰り返す必要がある。
REPLはブロック構造(for / while / def)を安定して保持できない
→ 全文コピペしても、内部では行単位評価になり、
フェーズ・時間・状態の連続性が壊れる。
その結果、
・無音 → 非周期 → 周期
・非線形減衰 → 遅延ビブラート
という 「時間でつながった処理」 が成立せず、
unexpected indent や動作破綻が起きます。
---
ということらしい。
何度も実際に REPL で失敗ログを出していたのに、なかなか、この結論に
達することができず、多くの時間を浪費した...
今後は、code.py を使う。
Wio Terminalでは、Arduinoのビルドが面倒だったけど、
ESP32S3は、CircuitPythonを使う分、効率が良いだろう。
0 件のコメント:
コメントを投稿