WAVE/PCM再生: Arduino: AVRで8bit PWM音楽再生 2016
* はじまり
* ChaNさんのFatFs
* プチ音の消去
* Arduino NanoでSDカード,5V:3.3Vレベル変換接続
抵抗でレベル変換 バツ:
ダイオードでレベル変換 ○△:
残念ながら:
* 動作可能ボード
* Arduino Wave PWM Player Lite版 仕様
概要:
WAVファイル仕様:
機能:
* SDカードの速度問題
44.1KHz(以下)/8bitに変換する:
* SDカード速度測定機能
使い方:
* SDカード シールド対応
* 実体配線図
出力の高域カットフィルタ:
Arduino(ATmega328p with 16MHz crystal) UNO/Nano/etc. :
* Download v1.3 (2016/04)
書き込み方:
* 動作確認
* avr-gccのバージョン
* Petit(ぷち) FatFs
* その他のWave player
TMRpcm
SimpleSDAudio
* はじまり
AE-ATmega/AVR: 8bit PWMの音 / PCM/WAVE再生
から3年。
47秒周期くらいのクラスタ境界で「プチ音」がするために見捨てられていたのを復活させてみた。
* ChaNさんのFatFs
http://elm-chan.org/fsw/ff/00index_j.html
前回は
R0.09b (C)ChaN, 2013 を使っていて,今回は
R0.11a (C)ChaN, 2015 という最新版を使ってみた。
disk_read()関係がかなり高速化されている様でビックリしました。
ATmega328p 16MHz でSDカードのリードテストしたら 720KB/sec 出てた。(OoO)/
古い版だと"512バイト読み出し直前の準備期間"が固定長で結構時間がかかっていて,
低速でSRAMが少ないマイコンの場合,速度のボトルネックになっていたが,その部分が消失していた。
これは良い。
* プチ音の消去
でもプチ音に変化なし。orz
で,
ChaNさんのFatFs:AVR用のサンプル(ATmega64)をなんとかATmega328pに移植して音を聞いてみると,
(ChaNさんのサンプルもWAVE再生可能)
なんとプチ音なしだった。orz (オイ
ChaNさんのプログラムをいろいろ調べたところ :D
バッファーアンダーフローが起きた時に"前回のデータを出す"という部分があって
それのおかげでプチ音が消失しているのが分かった。
ちなみに,
移植ミスも否定できないけど,ChaNさんのは
約3msec周期で300usecの期間バッファーアンダーフローが起きていて,
この周期で約15回づづ前回と同じデータを出していたのだった。(OoO)
バッファーアンダーフローの対処がないとノイズだらけになるハズなんだけど。。。
恐るべし,人間の耳 xD
今回はサンプルコードの解析が目的ではないので :D
そのうち調査してみるか。。。
で,
自分の方は47秒に一回程度なんだけど,上記バッファーアンダーフローに対応することで,
ようやくプチ音が消去できました。
(^^)/ (^^)/
「ごまかした」とも言う。(^^;
この部分はマイコンクロックを20MHzに上げればクリア可能と思われます。
* Arduino NanoでSDカード,5V:3.3Vレベル変換接続
前回は秋月のArduino Duemilanove互換ボード(AE-ATmega)を3.3V改造したものを使ったけど,
http://mpu.seesaa.net/article/399685555.html
今回は一般的な「Arduino Nano互換ボード」:D につないでみた。
従って,
SDカードをつなぐためには5V(Arduino側)と3.3V(SDカード側)のレベル変換が必要です。
参考:
しなぷすさんのハード制作記のページ
3-6.5VのArduinoと接続する方法
http://www3.big.or.jp/~schaft/hardware/hard/MGLCD_AQM1248A/page004.html
抵抗でレベル変換 バツ:
ググると1.8KΩ:3.3KΩくらいでレベル変換しているのがあったのでやってみたけど,
再生中に頻繁にリードエラーが起きて全然ダメでした。
ブレッドボードだからアレなのはアレなんだけど xD
orz
SPIクロック8MHzなのでもっと速度を落とせばひょっとしたらそれなりの用途には使用可能
かもしれないけど,波形を観測すると,とても使う気にはなれない。orz
さらにググると抵抗値を下げている人がいて結構きれいな波形だったが,
電流がものすごいことになっているので今回は未実験。
ダイオードでレベル変換 ○△:
さらにググると, (オイ
ダイオードでやっている人がいてこっちの方がよさそうだったので試してみたら,
抵抗変換よりだいぶマシだった。
というか今回の用途には問題なく使えた。(^^)/
波形を見ると立ち上がりが悲惨な感じだけど,立ち下がりは問題なさそうな感じだった。
電流も少なくて済むのでこれを採用しました。
簡単だし,ダイオードは部品箱にあるのだった。
残念ながら:
上のダイオード方式も手持ちのSDカードを全部試してみると
一部のものはリードエラーが出て使えなかったので万能ではない模様。
ちゃんとしたレベル変換を付けるのがベストなのは間違いなさそう。:D
と,いうことでこの手の簡易型のレベル変換は高速クロックでは信頼度が
低いことが分かりました。
* 動作可能ボード
マイコンがATmega328p,動作クロックが16MHzの互換ボード,
Arduino: UNO, Duemilanove, Nano, Mini, Pro 及び "素のATmega328pマイコン+16MHz水晶発振子"
等々でHEXファイルを書くだけで動作します。
(注) 素のATmega328pの場合,Fuseに適切に書き込む必要あり
* Arduino Wave PWM Player Lite版 仕様
概要:
Lite版なので曲の選択機能はありません。(^^;
電源ONか,SDカードが差し替えられると以下の順でフォルダを探して,
/music
/wav
/ (ルートフォルダ)
最初に見つかったフォルダ内のWAVファイルを順に再生して無限ループします。
次の曲には飛ばせるけど,前の曲には戻れません。(^^; (注1)
SDカード挿抜とかは見ていないので,電源ONのままmicroSDカードの抜き差しは非推奨ですが,
自分は自己責任でやってたりします。:D
WAVファイル仕様:
foobar2000又はSoXでWAVファイルに変換されたものをターゲットにしています。
これ以外で変換されたファイルは未確認です。
PCM: 8bit / 16bit
Stereo/Mono
fs(サンプリング周波数): 48KHz以下。
こちらで確認したのはfs=8KHz,32KHz,44.1KHz,48KHzのWAV(8bit/16bit)ファイルですが、
最低でもfs=22.05KHz以上で使用することを強く推奨します。
通常は最も音質が良いfs=44.1KHzを推奨します。
機能:
[パソコン上のUARTターミナル(TeraTerm等)から操作]
次の曲に飛ばす : [N], [ ](スペースキー)
再生ポーズ/解除: [S], [P], [ESC](エスケープキー)
一度押すとポーズし,画面に「P」マークが表示されます。
もう一度押すとマークが消えて再生再開します。
曲の先頭に戻す: [F]キー
再生中にこのキーを押すと,その曲の先頭に戻って再生を開始します。
早送り(FF)/巻き戻し(Rewind): FF: ]キー Rewind: [キー
再生音を出しながらFF/Rewindします。
最後までFFすると次の曲に行ってしまいます。(^^;
音量ボリューム: Up:[+ or .(ピリオド)], Down:[- or ,(カンマ)]キー で音量Up/Downします。
32ステップです。
可変速再生: Speed Up:[U], Speed Down:[D], Speed Normal:[0]
高速側はあまりSpeed Upしません。
[外部の押しボタンSWで操作]
(1) 次の曲に飛ばす: SWを一回クリック。(離した(0.5秒以内)タイミングで次の曲に飛びます)
(2) 再生ポーズ/解除: SWを1秒以上押し続けると再生ポーズします。
手を離してSWをもう一回クリックするとポーズ解除されます。
* SDカードの速度問題
16ビット/44.1KHz/Stereoのファイルを再生するには, そこそこ高速なSDカードが必要になります。
手元に高速なSDカードがない場合以下の対応方法があります。
44.1KHz(以下)/8bitに変換する:
マイコンのPWM出力は8ビットの分解能しか使わないので,foobar2000で
44.1KHz(以下)/8bitにWAVファイルをコンバートしたものにすれば
低速なSDカードでもOKになる可能性大です。
今回の場合,8bitに落としても音質は変わりません。(^^;
* SDカード速度測定機能
SDカードのリード速度を計測する機能を付けました。
これでSDカード速度の絶対評価が可能になります。
使い方:
音楽の再生中(or ポーズ中)に「t」キーを押すとリードテストがはじまります。
以下のようにリード速度が表示されます。
[PCM] S321601.WAV 32000Hz 16bit Stereo 26115412 Byte
-----+-----+-----+---
*****************
[Read]: Testing 512 byte buffer: read performance...
Done!
Result: 314 KB/s
[PCM] S441601.WAV 44100Hz 16bit Stereo 66767804 Byte
-----+-----+-----+-----+-----#-----+--
*****
手持ちのSDカードのなかで,44.1KHz/16bitの読み出しで問題なく使えたSDカード。
リード速度 | SDカード |
332KB/sec | Transcend 2G FAT SD @? |
303KB/sec | SanDisk 16G FAT32 UHS-I @6 |
302KB/sec | Victor 4G FAT32 SDHC @4 |
294KB/sec | Good-J 16G FAT32 SDHC @10 |
266KB/sec | BUFFALO 16G FAT32 SDHC @4 |
(22.3usecの割り込みがガシガシ入った状態で速度計測しています)
44.1KHz(以下)/8bitデータならもっと遅くても大丈夫だと思います。
* SDカード シールド対応
以下のSparkFunとSeedStudioのSDカードシールドに対応。
チップセレクトが違うだけなので二つのチップセレクト端子を同時にパタパタさせてます。
持ってるわけでないので本当に動くかどうかは未実験。
SparkFun microSD Shield
https://www.sparkfun.com/products/12761
SD Card shield V4.0
http://akizukidenshi.com/catalog/g/gM-09696/
http://www.seeedstudio.com/wiki/SD_Card_shield_V4.0
* 実体配線図
電源:
Arduino Nanoの場合,3.3Vは外部から供給する必要があります。
3.3VはSDカード用なので100mA以上を供給可能なものが必要と思われます。
ダイオード:
ダイオードは部品箱にありがちな適当なのでOKです。(オイ
一本1円で十分かと。
http://akizukidenshi.com/catalog/g/gI-07783/
ショットキ・バリア・ダイオード(SBD)でも大丈夫です。高いけど。
出力の高域カットフィルタ:
この実体配線図はPC(パソコン)のAudio入力端子との接続を想定しているので省略してありますが,
一般のアナログアンプに接続するなら,以下のページの出力ローパスフィルタを入れた方が
良いです。(或いはもっとマシなフィルタ:-)
http://mpu.seesaa.net/article/432426722.html
注意ポイント:
当然のことながら,SDカードは壊れてもおしくないものを使って下さい。
うちは2枚ほどダメになりました。(お〜〜〜い
(爆
orz
Arduino(ATmega328p with 16MHz crystal) UNO/Nano/etc. :
使用端子のメモ。pin番号は28pin DIPのもの。
[ PWM ]
OC1A: PB1, 15pin, D9 : Audio Left
OC1B: PB2, 16pin, D10 : Audio Right
[ SPI ] <Arduino> <SD Card>
MOSI: PB3, 17pin, D11 DI, 2pin
MISO: PB4, 18pin, D12 DO, 7pin
SCK : PB5, 19pin, D13 CLK, 5pin
CS : PD4, 6pin, D4 CS, 1pin
or
CS : PB0, 14pin, D8 CD, 1pin
[ Button SW port ]
SW :PD2(INT0), 4pin, D2, Active low
* Download
arduino_wave_player_lite_atmega328p_v1.3-201604.zip
v1.3:
(1) FF/Rewindがリファクタでバグってしまっていたのを修正。orz
(2) バージョン表示を追加。
(3) 再生中の曲の最初に戻る[F]キーを追加。
v1.2: 最初の版
arduino_wave_player_lite_atmega328p-v1.2-201603.zip
書き込み方:
解凍して出てきた
arduino_wave_player_lite_atmega328p_38400bps.hex
というファイルをこのツール
http://mpu.seesaa.net/article/399685603.html
にドラッグ・ドロップして 書き込みます。
* 動作確認
/musicフォルダにWAVファイル(fs=32KHz以上推奨(注2))を入れたSDカードを差し込んで
電源を入れると,基板上のLED(TX)がチカチカします。
十秒以内くらいでこのチカチカが停止すれば,既に音楽再生が開始されています。
TeraTermを38400bpsの設定で開けば操作可能です。
圧電素子や100円スピーカをつなげば音声確認できるかと思います。(こちらでは未確認)
* avr-gccのバージョン
arduino-1.6.8に付属の
gcc version 4.8.1 (GCC)
を使用。
これより前の版は使わない方がよい。
後の版なら大丈夫と思われるが,あまりチェックしていない。
というか,大勢のユーザが使用しているarduino版がひとまず安心。
* Petit(ぷち) FatFs
コンパイル・オプションでPetit・FatFs(以下 PFatFs)を使ってコンパイルできます。
動作はコンパチブル。
問題:
音が「ブヨブヨ」でちょっと使えません。 :D
バッファーアンダーフローの対策がなければ,「ブチブチ。。。」という感じに
なります。
原因:
最初期から変わっていない気がする。
FatFsよりもSDカードの読み込み速度が遅いと思って上記の「SDカード速度計測機能」で
比較するとほとんど同じ値を出していた。
フラグメント問題かもしれないが詳細未調査。
* その他のWave player
TMRpcm
Arduinoのスケッチタイプの以下のWAV・PWMプレイヤーがある様です。
標準でfs:32KHz mono。 拡張でもう少しアップするみたいだけど詳細不明。
TMRpcm
https://github.com/TMRh20/TMRpcm/wiki
Youtube動画
https://www.youtube.com/watch?v=LbqPgJe3Qd4
TMRpcm/Arduinoのフォーラム
https://forum.arduino.cc/index.php?topic=179027.0
SimpleSDAudio
これもスケッチタイプ
http://www.hackerspace-ffm.de/wiki/index.php?title=SimpleSDAudio
* 参考
Arduinoシリーズ15種類の違い | まとめ比較表
http://ideahack.me/article/134
(注1) いろいろやればできそうなんだけど,この手の機能はキリがないので
Lite版仕様ということにしました。今のところ。
(注2) サンプリング周波数(fs)が低すぎる場合,ちゃんとしたフィルタを入れないと
PWMノイズと折り返しノイズ、(キーーン!)で耳が痛いです。xD