マイコン工作実験日記

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

3つのデコーダ

2009-12-31 21:59:15 | MP3プレーヤ
MP3, AAC, WAVの3種類のファイルが再生できるようになったので、その処理方法について書いておくことにします。それぞれのファイル形式に対しては、それぞれのデコーダを用意しています。ファイルを再生する際に、そのファイルの拡張子から対応するデコーダを判断し、それを処理するタスクを起動するようにしています。例えば、MP3ファイルを再生中のタスク状態はこんな感じ。



AACファイル再生中は、こうなります。



もちろんwavdecoder_taskはWAVファイルの再生を担当するタスクです。それぞれのタスクは、デコード結果として44.1KHz, 16bit, 2チャンネルのPCMデータを出力しますので、それをCODECあるいはUSBスピーカに出力してやることで音が出ます。この出力を担当するのがpcmsender_taskです。

MP3やAACのデコーダは、それぞれその動作に20KB以上のRAM領域を必要とします。しかしながら、合計で40KB以上のメモリを必要とするというわけでもありません。なぜなら、3種類のデコーダは同時に動作することはないので、それぞれのタスクが使用するバッファやメモリを共通のメモリプールから動的に獲得/解放することができるからです。

同じ理屈で、3つのデコーダ・タスクのスタック領域を共通化させることも可能ですが、残念ながらTOPPERS/JSPのコンフィギュレータには、そのようなタスク間でのスタック共用を表現する能力は用意されていないようです。LPC2388にはRAMがたくさんあるものの、こうしてタスク数が増えてくるとスタックで消費されるメモリ量の割合が大きくなってくるので、これら同時に動くことのないタスクに対して独立した充分なスタック領域を割り当ててしまうのもモッタイナイです。そこで、ちょっとした dirty trickを施してみました。

上記のデコーダ実行時のps コマンド出力のStack表示はスタック残量/スタック割り当て量を示しています。aacdecoder_taskとmp3decoder_taskのふたつのタスクのスタック残量はゼロになっており、スタック残量が不足していることを示しています。本来であればこのような事態はマズイことなのですが、wavdecoder_task, aacdecoder_task, mp3decoder_taskの3つのタスクは同時に実行されることはないうえに、これらのタスクのスタック領域は隣接して割り当てられています。そのため、mp3decoder_taskのスタックは、割り当て量で足りなくなるとaacdecoder_taskのスタック領域を侵食し、さらにそれでも足りなくてwavdecoder_taskのスタック領域まで浸食しています。aacdecoder_taskも同様に自分のタスクに割り当てられたスタック領域では足りずにwavdecoder_taskのスタック領域を侵食しています。このような侵食が生じても、3つのタスクが同時に実行されるわけではないので、実害は無いというわけです。



現在のメモリ使用状況はこんな↑です。AACとWAV入れたらtextサイズが100KBほど増えました。

今年の作業は、ここまでとします。それでは、皆さん、良いお年を。

ついでに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の時と同等の情報は表示できそうです。



そろそろ、M3を始めようか

2009-12-25 23:38:49 | Weblog
秋月や苺Linuxが扱うようになって以来、Primer2を買ったというブログ書き込みをしばしばみかけます。わたしも興味がないわけではないのですが、LDOが壊れるという話を聞くこともあり、ずっと様子見状態でした。ATMELからのCortex-M3に期待していたというのも様子見を続けていた大きな理由のひとつです。でも、SAM3Uはピン数が多くて自作するには覚悟がいるし、手ごろなボードも出てきていません。SAM3Sこそがわたしが待っていたデバイスなんですが、やはり手ごろなボードが入手できるようになるまでは、まだしばらく時間がかかるでしょう。

いつまでも待っていてもしょうがないので、そろそろちゃんとCortex-M3を使い始めようと思っていました。チップの値段からしても、ARM7よりも優位ですし。近頃じゃ、embedとかLPCXpressoが開発環境を含めて手ごろな値段で話題ですね。わたしの趣味としては、やはりPrimer2のようなケースに入ったものよりも、自分で工作するヘッダー・ボードの方が好みにあっています。そこで、DWMのSTM32基板を使って勉強し直すことも考えていたのですが、FuturlecのET-STM32を見つけてしまいました。24.9USDという激安価格です。これで512Kフラッシュと48K RAMを持ったSTM32F103REを搭載です。DigikeyやMouserじゃ、このチップだけで15USDくらいします。回路図とかは公開されていないものの、50ピン出ていれば不自由することはないだろうと踏んでポチってしまいました。ちなみに、Futurlecでは最近になってSTM32チップのばら売りも始めたのですが、STM32F103REが6.9USDと、やはり激安です。




...というのが、2週間ほど前のこと。普通の郵便での出荷なんでトラッキングはできませんが、送料も5USDと安いので待つことしばし。ようやくと、昨日届きました。Futurlecの本社はタイにある様子。ボードの製造元もタイの会社のようです。でも、荷物は香港から出荷されてきました。その方が送料とか安くできるのでしょうかね。



中身はこんな感じ↑。ボード上にMAX232が載っていてRS232レベルのコネクタが出ているので、DB9へのケーブルが付属しています。CDには次のようなファイルが含まれていました。
  1. ユーザ・マニュアルと回路図
  2. STが提供しているマニュアル、APノート、ライブラリと同じファイル
  3. IAR, Keil, RaisonanceのIDE試用版

マニュアルにはタイ語版も含まれていましたが、もちろん英語版もあります。英語はちょっと怪しいレベルなんですが、充分に意味は通じますので、なんの問題もありません。



50ピンですが、必要な信号はほとんど出ているようなので安心。ピンが1列ですので、ブレッドボードに挿して使うのもいいかもしれません。

開発環境も整えねばならないので、実際に使い始めるのは来年になると思います。

アートワークのありか

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の違いがあるのかもしれません。

SAM3Sの嬉しいところ

2009-12-20 19:21:42 | Weblog
これまでSAM3Uが発表されても様子見状態でしたが、ピン数が手ごろなSAM3Sには興味をもったので、マニュアルを読み始めています。以下、64ピンのSAM3S4BをSAM7S256と比べた場合に個人的に便利だと感じた点を列挙してみます。

  • RTCがある! SAM7Sでは発信周波数があまり安定していない、RTTだけだったので、RTC機能は別途用意する必要がありました。
  • バックアップ機能あり。RTCがあれば、当然バックアップも必要。
  • MCIが使える。SDカードのアクセスに便利。
  • 12MHzのクリスタルで良い。これまでは標準的なクリスタルは18.432MHzという周波数だったので、入手性悪かった。12MHzなら秋月で買える。
  • USBエンドポイント数が8つに倍増。これで、複合デバイスも作れます。プルアップ制御も内蔵された。
  • TWIが改善された。DMAが使えるようになったし、送信の際に明示的にSTOPが送れるようになった。これまでは次のデータの書き込みが間に合わないと、クロック・ストレッチをしてくれず、自動的にSTOPが送出されてしまっていた。
  • 12bit DACが使える! ADCも12bit対応。コンパレータ機能もあり。
  • PIOキャプチャ・モードを使えばCMOSカメラもつなげられる。
  • USARTにSPI機能が加わった。


LPCシリーズとかSTM32とか使っている人からみれば、当たり前のことも多いでしょうが、これまで不自由に感じていた点が改善されることは、なんとも嬉しいものです。クロックは、最高64MHz. 速度と消費電力とのバランスを考えてのことでしょうか? 速く動かしたい人は、96MHzまでのSAM3Uを選択できます。このシリーズにもEthernetとUSB OTGはありませんから、いずれこれらをサポートしたシリーズが発表されるのでしょうね。

64ピンでは外部メモリは使えないので、CMOSカメラをつなげてもLCDへ表示するか、いったんSDカードへ書き出さないといけないでしょうが、ちょっと実験するには面白そうです。

クロックについては最高64MHzとなっていますが、高速にするとフラッシュアクセスのウェイトを増やさなきゃいけない制約があります。評価ボード用のソースが公開されたのでさっそく覗いてみましたが、1ウエイトで済む48MHzで動かしているようです。

期待度は高まりましたが、実際に使い始められるのはいつになるでしょうか。ヘッダボードを待っていたら、来年春以降くらいかなぁ。

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喰うのかと想像していましたが、それほどでもないようです。

SAM3S発表される

2009-12-16 21:48:40 | Weblog
待ってました!ようやくとATMELから新しいCortex-M3のデバイスが発表されました。SAM3Sです。すでにあるSAM3UはUSBハイスピード対応がウリでしたが、ピン数が100/144とちょっと多いので、ちょっと気おくれしていたのですが、こんどのSAM3Sは48/64/100とそろっているようです。ちょっと使ってみるには、48/64ピンくらいが変換基板も安くて済むし、使いやすいんですよね。

これまでSAM7Sで不満を感じていた点がぜーんぶ解消されるような気がするので、早く使ってみたい気がしてきました。でも、当分はESのチップなんだろうな。バグが心配なので、少し枯れるのを待った方がいいだろうか。。

USB <-> シリアル変換

2009-12-12 23:37:28 | Weblog
久々にAT91SAM7を使う。頼まれ事があり、USBとRS232Cシリアルの変換をAT91SAM7Sを使って製作。SAM7-H256にレベル変換のADM3202ANを付けただけのようなものです。DB9コネクタは、オスとメスの両方を準備。秋月のDサブ9P基板(小)がちょうどいいサイズでした。これで、オス/メスが合わないために、ケーブル継ぎ足したりする面倒から少しは解放されるでしょう。今のところ、ストレート結線しか必要ないですが、ジャンパつけ足してクロス/ストレートの変更も可能にできますし。



ソフトの方は、ATMELの提供しているサンプルを使うつもりでいたのですが、ボーレートが115200bpsで初期化されたまま変更できないようです。そこで、いつも自分がデバックコンソール用に使っていたコードを変更することに。処理としては、USBから受信したものをUSARTに送り、USARTから受信したものをUSBに送るという、簡単なブリッジをすればいいだけのものです。それでもSAM7らしさは出したいので、USARTの送受信にはPDCによるDMAを使っています。

DMAでの転送量はUSBのバルク転送に合わせて最大64バイトに。送信の時は、送信したいデータ量に合わせてDMAすればいいのですが、受信の時には64バイト受信するまで待ち続けるわけにはいきません。そこで、一定時間あらたな入力が無い場合にはタイムアウトにより、DMA待ちから抜けるようにします。普通ならタイマが必要となる処理ですが、AT91SAM7のUSARTには受信タイムアウト機能が用意されており、USART単独でこのタイムアウト機能が実現できて大変便利です。

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デコーダに喰わせれば、曲の再生ができるんじゃないかと思います。

OV7670

2009-12-05 18:22:56 | CMOSカメラ
AitendoにOV7670を使ったカメラモジュールが出ています。なんだかガッチリとした印象を受けるレンズが付いています。2.54mmピッチで足が出ているのがちょっと魅力的。

このモジュール本体もイイのですが、紹介されている応用参考回路に興味を持ちました。ATMEGA32を使っています。まったく説明が無いので、この回路図から、どうやってカメラからのデータを拾うのかを推測するという楽しみが生まれます。

  • MEGA32には2KしかRAMがありませんから、カメラからのフレーム画像データを全部蓄えることはできません。たとえ1ラスタ分であってもピクセル毎にRGBデータの保存に2バイトは必要なので、VGAであれば640*2 = 1280バイトになってしまいます。QCIFなら176*2 = 352バイトなので、数ラスタなら蓄えられます。
  • LCDは16ビットバス接続のものを使っていますが、ATMEGAからは8ビット分のデータしか出ていません。そうすると、このLCDは8ビットでもつなげられるモードがあり、実際にはD8~D15しか使っていないのではないでしょうか。
  • SPIは何に使っているのでしょうか?画像保存用のSDカードでしょうか?FAT動かすためには、そのためのバッファメモリが必要となりますから、いよいよラスタデータなんか蓄えていられません。
  • PCLKとHREFの2つの信号は、カメラからのピクセルクロック信号と水平同期信号です。これらの信号が7400でゲーティングされてLCDへのWRとなっています。つまりは、カメラからのクロック信号で、そのままLCDへ書き込んでいることになりますね。

次のような手順で、カメラから出力されるデータをATMEGA32を介さずに、そのままLCDに流しこめるのではないでしょうか?
  1. LCDはRGB565のフォーマットをサポートしているでしょうから、カメラもRGB565で出力するように初期化しておきます。
  2. カメラの画像サイズにあわせて、LCDの描画ウィンドウを設定し、連続ピクセル描画コマンドを発行します。
  3. カメラへのRS信号を反転し、以後書き込まれるのはコマンドではなく、データであることを指示します。
  4. カメラからの画像出力を許可し、VSYNC信号の立下りを待ちます。
  5. VSYNCを検出したら、EN_EXCLKにHを出力し、CMOS_CSにLを出力します。すると、カメラからのRGBデータは74245を介してHREFの期間だけPCLKに同期してLCDに流れ始めます。
  6. MEGA32は、VSYNCの立ち上がりを検出したら、CMOS_CSとEN_EXCLKを反転してカメラからのデータを止めます。
  7. 最後に、連続描画動作を止めるためのコマンドをLCDに送ります。

と、まぁ、ざっとこんな仕掛けで1フレーム分のデータをLCDに送って、表示することができると思われます。LCDに表示された画像は、LCDへREADコマンドを送って読み取ることができますから、それをSDカードに書き込んでやることもできるでしょう。LCDの画面サイズよりも大きい解像度をサポートすることができないという制約はありますが、安価なATMEGAで自作デジカメが作れそうです。LCD表示をメモリ代りに使うなんて、うまいこと考えたもんですねぇ。どなたか、挑戦してみませんか?