2025年12月26日金曜日

Pico W + MAX98357A(chatgpt) https://www.otosozai.com/se1_1.htmlよりステレオ音源とったが、、、

一度はうごいたがその後無音に。。。。製品が2個とも悪いのかも、あきらめた

 **「ステレオ WAV でも再生できる」**ようにします。

やり方は ステレオ → モノラルにソフトで変換(L+R を平均)して I2S に流す方式です。
👉 MAX98357A が モノラル接続でも確実に鳴る一番安全な方法です。


方針(重要)

  • WAV が

    • モノラル → そのまま再生

    • ステレオL/R を平均してモノラル化して再生

  • 対応フォーマット

    • PCM

    • 16bit

    • mono / stereo 両対応


ステレオ対応版:WAV 再生コード(Pico W + MAX98357A)

from machine import Pin, I2S import struct # ============================== # I2S ピン設定 # ============================== BCLK_PIN = 10 # GP10 WS_PIN = 11 # GP11 DIN_PIN = 12 # GP12 WAV_FILE = "test.wav" # ============================== # WAV ヘッダ解析 # ============================== def read_wav_header(f): if f.read(4) != b'RIFF': raise ValueError("RIFF形式ではありません") f.read(4) if f.read(4) != b'WAVE': raise ValueError("WAVE形式ではありません") # fmt チャンク探索 while True: cid = f.read(4) size = struct.unpack("<I", f.read(4))[0] if cid == b'fmt ': fmt = f.read(size) break else: f.seek(size, 1) audio_format, channels, sample_rate = struct.unpack("<HHI", fmt[:8]) bits = struct.unpack("<H", fmt[14:16])[0] print("==== WAV 情報 ====") print("チャンネル数 :", channels) print("ビット深度 :", bits) print("サンプル周波数:", sample_rate, "Hz") if audio_format != 1: raise ValueError("PCM形式のみ対応") if bits != 16: raise ValueError("16bitのみ対応") if channels not in (1, 2): raise ValueError("mono / stereo のみ対応") # data チャンク探索 while True: cid = f.read(4) size = struct.unpack("<I", f.read(4))[0] if cid == b'data': return sample_rate, channels, size else: f.seek(size, 1) # ============================== # ステレオ → モノラル変換 # ============================== def stereo_to_mono(data): out = bytearray(len(data) // 2) for i in range(0, len(data), 4): l = struct.unpack_from("<h", data, i)[0] r = struct.unpack_from("<h", data, i + 2)[0] m = (l + r) // 2 struct.pack_into("<h", out, i // 2, m) return out # ============================== # WAV 再生 # ============================== with open(WAV_FILE, "rb") as f: rate, channels, data_size = read_wav_header(f) audio = I2S( 0, sck=Pin(BCLK_PIN), ws=Pin(WS_PIN), sd=Pin(DIN_PIN), mode=I2S.TX, bits=16, format=I2S.MONO, rate=rate, ibuf=40000 ) print("▶ 再生開始") BUF_SIZE = 1024 * (2 if channels == 2 else 1) remaining = data_size while remaining > 0: raw = f.read(min(BUF_SIZE, remaining)) if not raw: break if channels == 2: raw = stereo_to_mono(raw) audio.write(raw) remaining -= len(raw) audio.deinit() print("■ 再生終了")
-------------------------------------------------------------

0 件のコメント:

コメントを投稿