chakokuのブログ(rev4)

テック・コミック・DTM・・・ごくまれにチャリ

コードのデータを作ってI2Sで鳴らしてみる

やりたい事:440HzのSin波を作って鳴らしてみたけど、スピーカの特性によるのか矩形波のようなBEEP音になっていた。試しにコードの波形を作って鳴らしてみる
どうせならマイナーな、ラドミの和音の波形を作ってみる。
できたこと:和音の波形を作ってI2S制御のスピーカから再生した。
課題:和音が再生されたがノイズがひどい。また、単音の場合もi2s.write()でデータを送信する都度音が途切れる。callback方式で実装しても音が途切れる。どうやったら途切れることなく連続再生できるのか不明(Git上のサンプルコードを調べると何かわかるかも)*1
まとめ:やっぱり音のプログラムは難しい。MicroPython等のインタプリタで制御するにはハード側でcacheを持たせる等いろいろ工夫しないと、音が途切れる症状が出ると思われる。

  周波数        1周期にかかるclock数(44.1KHz)
--------------------------------------
# ラ A3 220.000      200 clock
# ド C4 261.626      169 clock
# ミ E4 329.628      134 clock

ラドミの和音による波形データを作るプログラムは以下

from math import pi
from math import sin
from machine import I2S
from machine import Pin

# code (A3_C4_E4)
# A3 220.000      200 clock
# C4 261.626      169 clock
# E4 329.628      134 clock

A3_CYCLE = 200
C4_CYCLE = 169
E4_CYCLE = 134


MAX_VOLUME = 0x7fff
volume = int(MAX_VOLUME * 0.5)


def dump2Bls(buf, len=128, onHex=False):
  for i in range(len):
     data = buf[i*2+1] << 8
     data += buf[i*2]
     if onHex:
         print(f'{data:02x} ',end='')
     if data >= 0x8000:
         print(data - 0x10000)
     else:
         print(data)

def toI16(data):
   if data == 0:
      lb = 0
      ub = 0
   elif (data > 0) and (data <= 0x7fff):
      lb = data & 0xff
      ub = (data >> 8) & 0xff
   elif (data < 0) and  (data >= (0x8000 * -1)):
      data = 0x10000 + data
      lb = data & 0xff
      ub = (data >> 8) & 0xff
   else:      
      lb = None
      ub = None
   return (ub, lb)		      


i2s = I2S(0, sck=Pin(18), ws=Pin(19), sd=Pin(20), mode=I2S.TX, bits=16, format=I2S.MONO, rate=44100, ibuf=20_000)

buffer_size = 44100 * 2              # *2 means 2byte(16bit)  and 1sec
buf = bytearray(buffer_size)         # 

for i in range(int(len(buf)/2)):
    a3 = sin( 2 * pi * i / A3_CYCLE)
    c4 = sin( 2 * pi * i / C4_CYCLE)
    e4 = sin( 2 * pi * i / E4_CYCLE)
    tone = int(volume * (a3 + c4 + e4 ) / 2)
    i16 = toI16(tone)
    buf[i * 2] = i16[1]
    buf[i * 2 + 1] = i16[0]

while True:
    i2s.write(buf)

ノイズがひどくて聞くに堪えない。なぜノイズが乗るのか分からない。和音の作り方がまずいのかも。Excelで波形を描画させたが特に非連続な部分は見つけられず

*1:WAVフォーマットに仕上げてPCで再生させることにより、データの問題か再生装置の問題かを切り分けられそうだ