CircuitPython 10行プログラミング Step5 (6) Raspberry Pi PicoのI2S出力
audiobusioモジュールは、オーディオのディジタル入出力を扱います。S/PDIFは含まれておらず、出力はI2S、入力はPDMです。
audiocoreモジュールは、メモリ内のデータ、wavデータを指定されたサンプリング周波数でaudioioもしくはaudiobusioモジュールの出力から音を出します。
I2Sは、CDやディジタル配信で使われるデータを再生します。最初は、NXPのUDA1334Aを搭載したボードを使います。スイッチサイエンスでAdafruitの製品を取り扱っています。
●UDA1334Aボードのおもな特徴
- 動作電圧 3.3〜5V
- フォーマット I2S(デフォルト)または16ビット、20ビット、または24ビットの左揃え
- サンプリング周波数 16~100kHz
- マスタ・クロックは入力なしでも可
●接続
UDA1334Aボードの端子 | Picoの端子(GPIO) | 名称 |
---|---|---|
Vin | 3.3V | 3V3(OUT) |
Vo | - | - |
GND | GND | GND |
Wsel | GP27 | LRCK(LRSLK、WS) |
Din | GP28 | Data |
BCK | GP26 | BCK |
SCLK | - | (MCLK) |
FS0 | 3.3V | 3V3(OUT) |
MUTE | - | - |
FS1 | GND | GND |
PLL | - | - |
DEEM | - | - |
I2Sのデータ・フォーマットには3種類があります。FS0、FS1の両方をGNDに落としたら「I2Sフォーマット」、上記の設定では「LSB-justified 16 bits input」になります。
●sin波の出力プログラム
sample_rateを8kHzから上げていくと音のデータはそのままなので、高音寄りになっていきます。sample_rateを96kHzにすると聞こえなくなったので、math.pi * 2をmath.pi * 20にすると、音の発生が確認できました。
import audiobusio
import audiocore
from board import *
import array
import time
import math
# Generate one period of sine wave.
length = 8000 // 440
sine_wave = array.array("H", [0] * length)
for i in range(length):
sine_wave[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15) + 2 ** 15)
sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000)
i2s = audiobusio.I2SOut(GP26, GP27, GP28)
i2s.play(sine_wave, loop=True)
time.sleep(1)
i2s.stop()
次は、TIのPCM5102Aを搭載したボードを使います。ebayで入手しました。
●PCM5102Aボードのおもな特徴
- 動作電圧 3.3〜5Vと思われる
- フォーマット I2S(デフォルト)または16~32ビットの左揃え
- サンプリング周波数 8~384kHz
- マスタ・クロックは入力なしでも可
●接続
PCM5102Aボードの端子 | Picoの端子(GPIO) | 名称 |
---|---|---|
SCLK | - | (MCLK) |
BCK | GP26 | BCK |
Din | GP28 | Data |
LCK | GP27 | LRCK(LRSLK、WS) |
GND | GND | GND |
Vin | 3.3V | 3V3(OUT) |
- | - | |
FMT | 3.3V | 3V3(OUT) |
I2Sのデータ・フォーマットには3種類があります。FMT端子をGNDに落としたら「I2Sフォーマット」、FMT端子を3.3Vへつなぐと上記の設定の「LSB-justified input」になります。
●sin波の出力プログラム
sample_rateを上げていき、96kHzまで、音の発生を確認しました。
import audiobusio
import audiocore
from board import *
import array
import time
import math
# Generate one period of sine wave.
length = 8000 // 440
sine_wave = array.array("H", [0] * length)
for i in range(length):
sine_wave[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15) + 2 ** 15)
sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000)
i2s = audiobusio.I2SOut(GP26, GP27, GP28)
i2s.play(sine_wave, loop=True)
time.sleep(1)
i2s.stop()