マイコン工作実験日記

Microcontroller を用いての工作、実験記録

ついでにWAV再生も

2009-12-28 22:26:22 | MP3プレーヤ
まだ作業中ではありますが、ファイルの拡張子(MP3/M4A)に応じてMP3とAACファイルの再生ができるようになりました。この際、ついでなんで、WAVファイルの再生機能も入れておこうかと思います。

WAVもMPEG4と同じようにファイルのカプセル化の方法であり、音声ファイルのフォーマットは選択利用できるようになっていますが、ここではWMPを使ってCDをWAV形式で取り込んだ場合の 44.1KHz, 16bitのPCMファイルフォーマットを扱うこととします。無圧縮ですから再生の際にはデコードの処理は必要無し。単にファイルから読み出した楽曲データを、そのままCODECあるいはUSBスピーカに送出してやればいいだけの単純処理なんで、これはすぐに作れます。いつものように、メタ・データがどのように格納されているかを調べておかねばなりません。

WMPで作成したWAVファイルをLinux上で hexdumpして調査。どうやらLISTタグの中にメタデータが格納されているようです。



見易くするために簡易的な解析/ダンプ・プログラムを作ってみました。



タイトル、アルバム名、歌手/演奏者程度の情報しか入っていないようです。曲の長さ情報もありませんが、これはWAVファイルのヘッダ情報がもつファイル・サイズから算出すればいいだけのことですので、MP3/AACの時と同等の情報は表示できそうです。



アートワークのありか

2009-12-23 23:48:34 | MP3プレーヤ
AACのデコーダの単体動作確認がとれたので、これをプレーヤに統合する作業中です。MPEG4ファイルから曲データを拾いだす部分は調査しましたが、アルバム画像についてはMPEG4ファイルには含まれていませんでした。iTunesではアートワークと呼んでいるんですね。調べてみると曲データとは別に管理されているようです。

どうやら、My Music/iTunes/Album Artworkの下にITC2ファイルとして置かれているのですが、この場所を特定するためにはXMLファイルも見なきゃいけないようなので、PC側でツールを用意しなければならないでしょう。そんなわけで、アルバム画像のサポートについては、はやばやと断念することにしました。

一応、ITC2ファイルについてもちょっと検索して調べてみました。最初の方にヘッダがあるけど実際の中身はPNGだという説明もありましたが、わたしが試しにダウンロードしたものでは、確かに最初の方に何やらヘッダがありましたが実際の中身はJPEGでした。iTunesのバージョンや、ダウンロードするアルバム画像によって、PNG/JPEGの違いがあるのかもしれません。

AACの再生

2009-12-18 01:20:20 | MP3プレーヤ
ようやくとAACを再生できるところまで漕ぎ着けました。どうやらMPEG4のデコードルーチンで正しくAAC曲データの先頭を正しく見つけられていたようです。今のところAACのデコーダとMPEG4の簡易デコーダをどうにか載せたところですので、まだコマンド操作でしか再生できませんが、音はちゃんと鳴りました。以下、再生実験の様子です。

最初に矢印に続いて192と表示されている行がありますが、これはMPEG4内の情報で曲データの長さが192秒であることを示しています。切り捨て表示していますので、より正確には 8502272/44100=192.795 秒です。実際には、これを190.62秒で再生を終えています。つまり、ちょっと早めのテンポで再生していることを示しています。この数字の違いは、CODECで使用しているクロックが12MHzであり、正確な44.1KHzのサンプリングクロックを生成できないのが原因だろうと考えたのですが、計算してみると短くなりすぎです。試しに別の曲を再生してみると、そちらはほぼ同じ時間で再生終了。どうして、この例では2秒も違うのか? いまのところ、原因不明。



続いて、aplay dummyとすることで、PCMデータをCODECに送らないように指示。こうすることで、今度はデコードに要する時間を調べてみようというわけです。106秒でデコードできていますから、MP3の場合とさほど変わりませんね。もっと、CPU喰うのかと想像していましたが、それほどでもないようです。

MPEG4ファイル形式について調べる - その2

2009-12-09 01:05:51 | MP3プレーヤ
iTunesでCDから取り込んだ m4aファイルの情報をダンプする簡易プログラムをLinux上で作成してみました。プレーヤ上で使わないであろう部分に関してはbox構造を解析することなくスキップすることにして、試行錯誤しながら興味ある部分だけを追いかけてみました。

曲のメタ・データに関してはilst box内にあるようですが、ISO/IEC 14496-12ではこのbox typeは定義されていないので、この部分はダンプを調べながら自己解釈して表示したものになっています。標準の別の部分で定義されているのかもしれませんし、そもそもudta がUser Dataですので、Apple独自だったりするんでしょうか?曲名や演奏者、アルバム名は取得方法がわかって一安心です。どうやら日本語の場合には、UTF8でエンコードされているようです。
% ./mpeg4dump 14CAT.m4a
00000000(00000020) ftyp
  M4A
  M4A
  mp42
  isom
00000020(000094e9) moov
  00000028(0000006c) mvhd
    version = 0
    Timescale: 44100, Duration: 8502272 --> 192 sec
  00000094(000089a9) trak
    0000009c(0000005c) tkhd
    000000f8(00008945) mdia
      00000100(00000020) mdhd
      00000120(00000022) hdlr
      00000142(000088fb) minf
        0000014a(00000010) smhd
        0000015a(00000024) dinf
        0000017e(000088bf) stbl
          00000186(00000067) stsd
            00000196(00000057) mp4a
            Channel: 2, Samples: 16, Sampling rate: 44100
          000001ed(00000018) stts
          00000205(00000028) stsc
          0000022d(000081d0) stsz
          000083fd(00000640) stco
  00008a3d(00000acc) udta
    00008a45(00000ac4) meta
      00008a51(00000022) hdlr
      00008a73(00000451) ilst
        00008a7b(00000021) .nam
          00008a83(00000019) data
            00008a8b: CAT'S EYE
        00008a9c(0000001e) .ART
          00008aa4(00000016) data
            00008aac: 杏里
        00008aba(00000024) .alb
          00008ac2(0000001c) data
            00008aca: ザ・杏里
        00008ade(0000001b) .gen
          00008ae6(00000013) data
            00008aee: Pop
        00008af9(00000020) trkn
          00008b01(00000018) data
            00008b09: 14
        00008b19(0000001e) disk
          00008b21(00000016) data
            00008b29: 1
        00008b37(0000001c) .day
          00008b3f(00000014) data
            00008b47: 1986
        00008b53(00000019) cpil
          00008b5b(00000011) data
        00008b6c(00000019) pgap
          00008b74(00000011) data
        00008b85(0000001a) tmpo
          00008b8d(00000012) data
        00008b9f(00000037) .too
          00008ba7(0000002f) data
            00008baf: iTunes 9.0.1.8, QuickTime 7.6.4
        00008bd6(000000bc) ----
          00008bde(0000001c) mean
            com.apple.iTunes
          00008bfa(00000014) name
            iTunSMPB
          00008c0e(00000084) data
            00008c16:  00000000 00000840 0000026C 000000000081B154 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000
        00008c92(00000077) ----
          00008c9a(0000001c) mean
            com.apple.iTunes
          00008cb6(0000001b) name
            Encoding Params
          00008cd1(00000038) data
            00008cd9: 1986359923
        00008d09(000000a2) ----
          00008d11(0000001c) mean
            com.apple.iTunes
          00008d2d(00000014) name
            iTunNORM
          00008d41(0000006a) data
            00008d49:  00000468 00000494 000039C5 00003EBE 00011F87 00011F87
00005D9F 00005D31 00027492 0001C0FA
        00008dab(0000007a) ----
          00008db3(0000001c) mean
            com.apple.iTunes
          00008dcf(0000001b) name
            iTunes_CDDB_IDs
          00008db3(0000001c) mean
            com.apple.iTunes
          00008dcf(0000001b) name
            iTunes_CDDB_IDs
          00008dea(0000003b) data
            00008df2: 15+07F3A9686FAC013975351AE84B4D91FF+2161923
        00008e25(0000009f) ----
          00008e2d(0000001c) mean
            com.apple.iTunes
          00008e49(00000035) name
            UFIDhttp://www.cddb.com/id3/taginfo1.html
          00008e7e(00000046) data
            00008e86: 3CD3N19R31408325U178A4F3CFEDFC86FFD0F5B21E332C865A08P1
      00008ec4(00000645) free
00009509(000001dd) free
000096e6(005f962b) mdat
 21 00 03 40 68 1c 21 00 03 40 68 1c 21 00 03 40
 68 1c 21 00 03 40 68 1c 21 00 03 40 68 1c 21 00
 03 40 68 1c 21 00 03 40 68 1c 21 00 03 40 68 1c
 21 00 03 40 68 1c 21 00 03 40 68 1c 21 00 03 40
%

最後のmdatのboxが実際のトラックの楽曲データを格納しているboxです。この部分がAACになっているハズなので、16進数で頭の方をダンプしてみました。この部分が正しいAACデータであることが確認できればいいので、いろいろ探し廻ったところ、この記事この図に辿り着きました。赤字の部分がAACデータとのことなので、最初の2バイトが21 00となっており、それっぽい感じではあります。この部分からAACデコーダに喰わせれば、曲の再生ができるんじゃないかと思います。

MPEG4ファイル形式について調べる

2009-12-04 00:41:12 | MP3プレーヤ
AACのデコーダを見つけたのはいいのですが、デコーダだけではプレーヤに必要な機能要件を満たすことができません。それは、曲名等のメタ・データを抽出する機能はデコーダには含まれていないからです。MP3の場合にMP3デコーダとは別にID3タグの解析をする必要があったのと、ちょうど同じ理屈です。Helixプロジェクトにはプレーヤも含まれているので、メタ・データに関する処理もプレーヤを調べれば見つかるのでしょうが、せっかくなので自分で調べて作ってみようと思います。

AACという名前を聞いたことはあっても、iTuneとかに関してもまったくの無知であるわたしにとっては、全てが新たに学ぶことばかりです。

  • まず、iTuneでCDから曲データを取り込むと、m4aという拡張子が付くことを知る。オジサン丸出し。どうやら、MPEG4だがVideoを含まないAudioだけのファイルであることを示す拡張子であるらしい。AACという形式で圧縮されたオーディオデータが、MPEG4形式のファイルに格納されているということになる。
  • AACのデータをMP4に格納する際のフレーム形式が、いくつか存在するらしい。Helixのデコーダは、ADTS, ADIF, rawの3種類に対応している。Andresさんのコードを読むと、m4aの拡張子の場合にはrawとして扱っているようだ。
  • つまりは、MPEG4のファイル形式に基づいて、ファイルの中に含まれるメタ・データを抽出するとともに、実際の曲データの開始位置を見つける必要があるようだ。ところが、AndresさんのコードにはMPEG4ファイルを解析している部分が見当たらない。
  • MPEG4ファイル形式の概要については、このサイトの説明が実際のイメージがつかめて解りやすかった。基礎資料として紹介されているISO/IEC 14496-12が基本となるISOのメディア形式を定めており、MP4ファイルはこの形式に基づいているようだ。と、いうわけでこの標準もダウンロード。


つまりは、Andresさんのコードそのままじゃ、iTuneのm4aファイルを再生することはできないようで、自分で音声データ部分の頭出しをやってやる作業は必要なようです。また、Andresさんのコードではサンプリング・レートやサンプル・ビット長を44.1K/16bitで決め打ちしているようですが、こういう情報も本来であればm4aファイルを解析して得らるはずのようです。資料もざっと眺めてみましたが、曲名などのメタデータの格納形式については上記のISO/IEC資料には含まれていませんでした。実際にiTuneで作成したm4aを調べてみた方が良さそうです。

そんなわけで、自分でm4aのファイルを解析する簡単なプログラムを作ってみる必要があるという結論に達しました。

ビットレートを変更しての動作確認

2009-11-20 23:20:54 | MP3プレーヤ
クロックを72MHzに変更したので、改めてMP3のデコードにどの程度の時間がかかっているのかを調べてみることにしました。以前、おおざっぱに調べたことがありますが、その時はまだSDカードも使えない状態でしたので短時間のMP3データでしか調べられませんでした。そこで今回は、SDカードからの読み出しと伸長処理をおこなうだけで音声出力をおこなわないルーチンを作成して、どの程度の時間がかかるのかを調べてみました。ついでに、ビットレートも192Kに加えて、256Kと320Kの場合の3種類を調べることにしました。

実験の様子はこんな↓感じです。試験再生コマンド(mplay)を投入して、経過した時間を表示させています。実際には、並行してLCDに時計を表示するタスクが動いているのですが、その程度のオーバヘッドは無視することにします。結果は次のとおりです。



それぞれのファイルは、同一の曲をビットレートを変えて取り込んだものです。意外と、ビットレートによる時間差は少ないです。曲の長さは175.466秒ですので、

ビットレートファイル長展開時間
192Kbit4,208,95283.370/175.466 = 47.51%
256Kbit5,612,59687.368/175.466 = 49.79%
320Kbit7,017,02888.580/175.466 = 50.48%


となり、SDの読み取り時間を含めてだいたい半分くらいの時間がかかっているようです。以前は60%くらいは費やしていましたから、ほぼ予想通りに性能が向上したということろでしょうか。

データがとれたのはいいのですが、じつは320Kbitのファイルを再生しようとすると、かなりの頻度で途中で試験再生が止まってしまうことが判明。普通に音を出せば問題なく動作するので、どうやらSDの読み取りが連続して発生した場合に問題が発生しているようです。週末にバグとりするつもりです。

フォントの追加

2009-11-07 22:55:02 | MP3プレーヤ
これまでMP3の再生時の際の曲名や演奏者名の情報の表示には日本語表示に対応するためにIPA GUIフォントを使っていたのですが、英字/漢字に関わらずIPA GUIを使っていました。そのため、英文表示の際になんとなくノッペリとした印象を受け気に入らなかったので、英字部分には別のフォントを用いることとしてみました。

使用したフォントはGentium Book Basicです。IPAフォントと同じように次のような手順を経て、使用しています。
  1. TTFファイルをダウンロード。
  2. FreeTypeを使った自作ユーティリティで、必要なサイズのビットマップデータ(独自フォーマット)を生成。
  3. Linux上で作成したフォントデータをSDカードにコピー。
  4. LPC2388上で、SDカードのフォントデータをLCDモジュールに搭載されているNANDフラッシュにコピー
  5. LCDの表示ルーチンは、NANDフラッシュからフォントデータを読み込み表示。

NANDフラッシュに関しては、単純なR/Wルーチンしか用意しておらず、ファイルシステムは載せていません。そのため、各フォントは単純に連続したページに配置して、その先頭ページを自分でメモして管理しているという手抜きで済ませています。そのため、NANDへのコピー作業の実態は次↓のようなものです。



copyコマンドで、フォント名とコピー先の先頭ページ番号を指定しています。結果として表示されるページ番号が次の領域のページ番号ですので、次のフォントのコピーはそのページから開始しています。そして、ソフト側ではフォントをオープンする際に、このページ番号を指定しているという仕掛けです。

BeforeAfter

ついでに演奏者名の表示位置も若干修正。GUI作成ツールがあるわけじゃないんで、プログラム中でテキトーに座標指定することで位置修正しなけれりゃなりません。うーん、まぁ、こんなところで良しとしておきましょう。

ジャケット画像の表示

2009-10-31 16:42:27 | MP3プレーヤ
前回、ジャケット画像がJPEGでしまわれていることがわかったので、今回はPC上でこれをBMPに変換しておくことにより、再生中にジャケット画像を表示するようにしてみました。



画面左上に、画像表示用の領域を用意しておき、その右側に歌手/グループ名とアルバム名を表示するように配置してみました。上の例ではさほど気にならないのですが、背景が暗めだと表示全体が黒っぽく出てしますことが災いして、かなり見にくくなります。



背景が青の場合なんかも、かなり暗く見えて、何の画像なのかわからなくなってしまいます。なんとかしたいけど、いろいろとパラメータを調べて、調整するだけの気力も湧かないので、このまま放置かなぁ。

ジャケット画像を表示するには?

2009-10-27 23:35:16 | MP3プレーヤ
リモコンも使えるようになって、自分でも結構気に入ってきたMP3プレーヤです。そろそろ、次なる追加機能を考えようということで選択したのが、アルバムジャケットの表示機能です。せっかくQVGAという画面の広いLCDを使っていることですしね。

わたしはいつもWMP (Windows Media Player)を使って、CDからの取り込みをおこなっていますが、ジャケット画像がある場合には↓のようにフォルダにその画像が表示されます。



まずは、この仕掛けを調べてみました。フォルダ内を覘いてもMP3ファイルしかないので、最初はMP3ファイルに画像が埋め込まれているのかとおもったのですが、ID3タグを調べてもAPICタグは含まれていませんでした。そこで、もう一度フォルダの中を dir/as で確認してみると。。



はい、隠しファイルになっているようです。全部で4つのJPGファイルがありますが、この例では同じものが含まれているので実際にはサイズは2種類です。JPEG展開にlibjpegを使うとメモリ喰いそうなので、今回はJPEGを使うことは断念することにします。代わりに、手間ではありますがAlbumArtSma.jpg を手動でBMPに変換しておくことにし、これを表示する仕様に決めました。この画像はだいたい75 X 75ドットのようですので、QVGA液晶にサイズ変更することなくそのまま表示できます。

リモコンのノイズ対策

2009-10-23 19:29:57 | MP3プレーヤ
赤外線受信モジュールは、タイマのキャプチャ端子に直接つなげていたのですが、職場の蛍光灯の下だと、なんと毎秒2000回ほどの割り込みが発生していることが判明。これだけのノイズによる割り込みが生じても、リモコン信号として誤検出されることは無いので、実害はありません。しかし、いくらなんでもこれはチトまずいんではないかというわけで対策を施すことに。

そもそも、データ・シートには「電源ラインに100Ωと20μFのRCフィルタを取り付けることを推奨します」と書いてあったんですが、これまではその指示を無視して、ただ単にUSBからの5Vをつなげただけでパスコンすら入れていませんでした。

そこで、まずは試しに0.1μのパスコン入れてみました。これだけで、毎秒800回くらいに減りました。効果あるもんですねぇ。

続いて、データ・シートの指示どおり、100Ωと20μFを入れてみると。。。さらに半分の毎秒400回くらいになりました。これで、なんとか再び「目をつむる」ことができそうです。

比較のために自宅で再度実験してみると、日中の室内(日陰)ではまったく割り込み発生しません。蛍光灯を点けてみても、大丈夫。オン/オフの際に2回くらい発生する程度です。うーん、この違いはいったい何でしょうか? 考えられそうなことは。。
  1. 蛍光灯の種別の違い? 自宅では電球型の蛍光灯と、ふつうの机上スタンドの蛍光灯と試したんですが。。
  2. 蛍光灯の本数の違い。事務所環境では、蛍光灯の本数というか、設置数が多い。

あくまでも想像ですが、設置数が影響しているような気がします。それだけ、赤外線成分が多くなるし、インバータの影響も増えるとか? 

そして、最後に日中の室外(日向)でも実験してみると。。。毎秒、400回の割り込みが発生します。赤外線リモコンの受信が、こんなにも環境条件の影響を受けるものだとは知りませんでした。日光や蛍光灯の光線が直接入らないような向きにするだけで、かなり影響は減らせるので、そのように設置するのが基本ですね。