新MP3player製作(自作編) H15.8.14Update
Chanさん(若松通商のキット)のMP3playerを作って以来、自分でも設計段階から作ることができたらいいなとは思っていま
したがメディア(メモリカード)の制御やら、ファイルシステム(FAT)等々分からないことばかりであきらめていました。
そんな中、EasyMP3(http://strawberry-linux.com/mp3)とSD(MMC)カードを使ってMP3プレーヤを作られている
ゆきさんのホームページを見つけました。
今回、ゆきさんの内容をほとんど真似しながらですが、SDカードの制御・FATの理解を目指しMP3プレーヤ製作に挑戦しました。
プロトタイプ
とりあえず、プロタイプで大きさや見栄えはあとまわしにして何とか音を出すことを目標とした。
仕 様
CPU:Atmega8 LCDを接続するのでI/Oピンを確保するため内部OSC(8MHz)を使用
デコーダ:EasyMP3(VS1001K:DAC・DSP)
対応フォーマット:MPEG 1& 2 Layer-3, Layer-3の2.5拡張、VBR対応全てのサンプルレート、ビットレートに対応
最大256kbpsで動作確認
記録媒体:SD/MMCカード MMCのSPIモード使用、BUFFALO製RSDC(128MB)にて動作確認
ファイルシステムはFAT16のみ対応、ロングネーム(VFAT)対応、ルートデレクトリのMP3ファイルを演奏
データはパソコン等でメディアに転送しそれを使用する。
カードソケットは、壊れた(壊した?)スマートメディア用ソケットの接触部がちょうどSDカードの接続部の
ピッチと合うのでそれを使用。
(写真のようにクリップで固定したが接触不良になやまされました、正規のソケットでないとだめですね)
表示装置:SC1602BS(16x2) ID3TagV1情報を用いタイトル・アーティストおよびボリューム、演奏時間を表示
エラー表示:SDカード異常、FAT異常、MP3ファイル異常、製作過程ではデバック用のデータを表示させた
電源電圧が3V程度のため、表示器駆動電圧チャージポンプ回路で作成(chanさんの回路)
操作SW:電源入&再生、停止&電源切、1曲先送、1曲戻し、ボリューム上げ、下げ の6ボタン
電源:3.3V 5Vを3端子レギュレータ(EasyMP3に付属品)で変換、当初単三(アルカリ)x2を直に使っていたが問題発生(後述)
消費電流40mA弱(128kbpsにて) (EasyMP3は、 3.3Vなので74LVC245A・3端子レギュレータを不使用)
電源電圧監視回路は省略(将来追加)
ソース:アセンブラ (ゆきさんのCをそのまま流用するのも芸がないし、アセンブラの方が細かいところに手が届くし、C環境も
整ってないので) 荒削りで、無駄も結構あるかもしれません。
現在実用機作成中ですが、細かいバグがまだありそうです。(再起動時まれにかたまる)
回路図:ほとんど、VS1001Kのデータシートをベースにゆきさんおよびchanさんの回路を参考に作成。
製作過程(約1ヶ月苦戦)
基本回路
CPU:MEGA8、クロック8MHz(内臓OSC使用)
LCD:やりなれているので特に問題なし。4ビットモード、3V動作回路の付加(本体R6の変更91→75k)
電源:アルカリ単三電池2本3V前後は確保。(CPU・SD・VS100Kとも2.7−3.6V動作OKのはず?)
SDカード
SDカードとの通信が第一段階、うまくいくか不安。
MMCカードのSPIモード使用、日立のデータシートおよびゆきさんのテクニックをそのまま回路作成&コーデング
回路&ソフトとも完璧に作った(つもり)だが、なかなかカードが応答してくれない。約1週間かけ何度もチェックして出た原因は
ソケットの接触不良でした。(見た目ではよさそうですが、微妙なところでつながっていない)
FAT情報
FATについては、深いところ(セクタ・クラスタ・BPB等々)まで理解していなかったので関連するホームページ等を参考に概略を理解
したうえでコーデング。FAT12は、バイトをまたぐ処理等が面倒で大容量メディアでは使わないので、ターゲットはFAT16とした。
セクタサイズが512バイト以外、FAT12・32はFATエラーで演奏中止 (FAT32、サブデレクトリ対応はさらに勉強が必要)
今回使用したBUFFALO製128MのSDカードのフォーマットは、セクタ長512バイト、1クラスタあたりのセクタ数4、FAT領域のセクタ数240
FATの数:240x512/2 ∵FATサイズ2バイト(16bit) 実質DATA記憶容量 512x4x240x512/2=120x1024x1024バイト=120MB
FAT32 file system(一番参考になった、現在ない模様) 、FATについて(自分なりに整理しました)
MP3ファイルのサーチ
ルートデレクトリエントリにあるファイル属性を順に検索し、拡張子がMP3のものを探し出す。他のファイルは無視
1曲あたりのサイズは16MB未満とした。(あまり意味はないが、16Mあれば問題ないので処理をちょっと簡素化)
ID3TagV1
MP3ファイル構造もまったく分からないので、ホームページで勉強。とりあえずタグ仕様について理解。
ID3TagV1は、仕様は比較的簡単であり本体ファイルの末端128バイトにある。
(offset:内容)
0−2:’TAG’ 固定文字、タグはオプションであるので要確認、3−32:曲タイトル、33−62:アーティスト名
63−92:アルバム名、93−96:公開年、97−126:コメント、127:ジャンル
曲の演奏前に、クラスタをたどっていき最後の128バイトを読み出す。ここで厄介なのは、セクタあるいはクラスタをまたぐ
場合処理が面倒になる。(今回単純ミスもありこれに結構時間を費やした。)
LCDにはタイトル16文字(1行目)、アーティスト名10文字(2行先頭より)を表示、タグがない場合は'No ID3 Tag V1'
を表示。
MP3のHP(最初から説明するInside MP3:わかりやすく内容が高度、サンプルソースもある)
VS1001Kの制御
EasyMP3に使用されている、VS1001Kの使い方はメーカのデータシートを参照した、それほど難しくないと思われたが
ここでもはまる。勘違い等を直し、やっと音が鳴るようになったがどうもイニシャルが時々おかしくなり、演奏速度が2倍程度
の速度になってしまう。悪いのが100%でなく50%程度なのでよけい分からない。メーカのデータシート・FAQ等を見て
何度もイニシャルルーチンをチェックするも原因不明。(約1週間苦闘)
そんななかFAQを何度も読返すとそのなかに、「演奏速度がおかしいのは基準クロックの設定がおかしく、それを正しく
設定したにもかかわらずそうなるのは、MP3ファイルが不正のため自動リセットがかかている・・・・」とかかれていた。
MP3ファイルは正規(タグ等の冗長部分はあるが)なので、何か他の要因で自動リセットしているあるいはリセット処理が
不安定になっているのではと考えた。
不安定要因として、電源を疑った。電池電圧は、3V弱となっていたことは知っていたがスペック上問題ないと信じていた。
しかし、ほかに方策がないので3.3V安定電源(EasyMP3に付属の3端子レギュレータ)に変えてみた。
するとあっさり不具合は解消できた。電源電圧対しての裕度はそれぞれあるはずなので、原因部位はなんともいえないが
一番くさいのがVS1001Kで、他にAVR内臓OSCの変動等が考えられるがとりあえず直ったのでよしとしよう。
曲の演奏は、ひたすらDREQ(データリクエスト)が’H’である間、MP3データを送り続ければいいだけです。
(冗長部分[タグ、可変ビットレートのXingヘッダー]があっても問題なしです。)
次のクラスタ検索は、次のクラスタ読出し直前にその都度実施していますが、問題ありません。(ゆきさんとちょっと違う)
割込処理(SW処理等)
SW操作や演奏時間・ボリュームの表示更新をどのタイミングでやるか考えました。
タイマ割込みを使うまえにまず、思いついたのはVS1001Kがビィジーの間(DREQ='L')に処理できないかです。
DREQの信号周期(128kbpsにて)をみると、’H’が5ms+α程度、’L’が10ms+α程度でした。これなら、十分いけると
思いこれにしました。(10msあれば、8万クロックあります)
手順
DREQを1バイト送信ごとにチェックし、’L’なら割込み処理に入ります。
割り込み時間調整のウエイト
SW_in確認し、連続して押されたか確認して、ボリュームなら上げ・下げ処理し、それをLCD上に一定時間表示する
STOP・FF・REWキーなら、割り込みを抜けさらにメインルーチンに戻りそれぞれの処理
以上実行し割り込みを抜ける
とりあえず、この方法で曲の途切れもなく、操作に違和感もなく動いてます。
演奏時間の表示
演奏時間の表示方法ついては、あまり情報がなくトータル時間の表示さえも結構面倒そう。(windows上のプレイヤーでも可変ビットレート
の場合結構間違っている)
演奏しながら計算するのは、処理が複雑でCPU負担が大きくなりすぎるしいい方法ないか思案した。そこで、もしかと思いVS1001K
のデータシートよく見ると、デコード時間(秒単位)をレジスタ上にもっており読出せそうである。そこで、SOピンを接続しそれを読出す
ことにした。ここで注意が必要なのは、このデコード時間はVS1001Kがリセットしてからの時間なので、曲の途中からだと合わなくなる
ので、途中で電源オフする場合にはその時間をEROMに記録しておき、次の立上げ時にはその時間を足してやらないといけない。
感想、課題
全般に処理そのものはそう難しいものはありませんが、サブルーチンを組合わせる場合はレジスタ(変数)を、ローカルとして使うのか
グローバルにするのかよく整理しないと、思わぬところで内容が破壊され落とし穴にはまりました。スタック・SRAMとの使いわけも含め
た設計を最初からしないと、いけないとつくづく感じました。その点、Cはローカル変数が使えるので楽なのかな。
とりあえず、初期の目的は達成でき満足してます。SDカード・VS1001Kは、ブラックボックスの部分がありますが自作プレーヤでお気に
入りの音楽が楽しめるのは、感動ものです。
次なる課題はポータブルプレイヤとするため、電源を電池+D/Dとすること(要電源監視回路)、全体のコンパクト化です。
また、SDソケットもて手に入れないと。