動画再生 完成

2010/05/28

周辺ツールも整備して、ひとまず完成しました。
動作ムービーはこちら。撮影すると色が綺麗に出ませんね。
サンプルは Sugardansen。音も鳴っていますが、動画には入れていません。

POMコンバータは、画像のみの非圧縮AVIと、非圧縮WAVを元に
プレイヤー用の動画フォーマットに変換して出力します。
これをSDカードにコピーし、spin 上のファイル名を書き換えて実行してください。

POMコンバータ (Windows 実行ファイル+ソース)

プレイヤー側は6KB程度のバッファで動作します。(コードも6KB程度)
省メモリを追求すると実装もデータ構造も素直でなくなってしまうので、ほどほどです。

プレイヤー本体 (DemoBoard用、要SDカード&OLED接続)


動画再生 その2

2010/05/26

音声再生には 先日作ったドライバ を使うことにしました。
動画2フレーム分のバッファをループ再生させた状態に維持し、
バッファを半分ずつSDカードから更新することによってストリーミングを実現します。

ファイルの断片化などでSDカードへのアクセスが遅くなったときに waitcnt に
失敗する場合があるため、カウンタ(PHSx)を利用するようにしています。
さらに音と絵を同期するために、たまにバッファの再生位置をリセットしています。
実質音飛び(プチノイズ)になるのですが、音がズレるよりは良いということで・・。

まだコンバータがワンオフですが、48KHz 16bit ステレオ音声 + 30fps の動画は
再生できました。ウェイトを抜くと 70~80fps 程度の性能はあるようです。

もう少し整備したら公開します。


動画再生を作成中

2010/05/24

先日接続した SDカードOLEDモジュール を使用して、
SDカードからムービーを再生するプログラムを作りたいと思います。
データの用意が主な作業になりますが、WAVE 再生は実験を兼ねて
キューイングの仕組みを新しく作ります。

ムービーのフォーマット変換には akj Betas、リサイズに VirtualDubMod
利用することにしました。これらのツールで横幅 96 ピクセルの非圧縮AVI まで変換し、
OLED 用の 16bit カラー + PCM への変換ツールは自作します。
AVI のフォーマット情報は こちら を参考に。

まずワンオフで画像のみを変換する物を作り、正しく再生できることを確認しました。
次は音声再生とインターリーブです。


シリアルOLEDドライバ 完成

2010/05/22

昨日のテクニックを使い、ドライバを完成させました。

リフレッシュレートは 100fps 位出るようです。
画面はTVオブジェクトのようなフレームバッファ方式にしました。

データシートの指示よりも高速にデータを投げていますので、
チップの個体差で動かなかった場合は、動作クロックを落としてみてください。

今回のコードはこちら。

ダウンロード (汎用、要ピン設定)

aitendo の OLED モジュールを接続し、oled_demo.spin を実行してください。

(5/23追記)
OLED モジュールのデフォルトのディスプレイガンマは 1.0 のようです。
PC から素材を変換する場合は、逆ガンマ変換を行う必要があります。
出力RGB = pow( 入力RGB * 1.0 / 255.0, ディスプレイガンマ ) * 255.0
という変換を行うことで、PC と同じ見え方になります。
標準的なディスプレイガンマは 2.2(Windows) および 1.8(Mac) です。


シリアルOLED その3

2010/05/22

カウンタを使用した高速シリアル通信の仕組みがわかりましたので、少し説明します。

CTRA を NCO・FRQA=0 として、PHSA の MSB をピンに直接出力し、
CTRB は NCO・FRQB=$40000000 で 4 サイクル毎のクロックを生成します。

手続きは以下のようになります。

  1. 転送する値を PHSA に読み込む
  2. FRQB設定
  3. ビット順を整えるように rol/ror を連続発行(転送ビット分)
  4. FRQBリセット

OUT レジスタの特定ビットを上げ下げするには演算が必要なのですが、
この手法により1命令で任意のビットを特定ピンへ出力できるようになります。


シリアルOLED その2

2010/05/21

Spin の速度があんまりだ、という感じなので、フレームバッファを用意して
シリアル転送を一括で行うアセンブリルーチンを作成することにしました。

1bit シリアル転送を CPU で行う場合、ピンの上げ下げを含めたループの最短は
28 クロックなので、読み書きの限界速度は約 2.8Mbps です。
(OLED モジュールの受け側が高速なので、Propeller 側でのウェイトは不要)

これを 96x64x16bit で割ると 29.06、これが1コアのCPU処理で出せる
最大フレームレートになります。実際はメインメモリからデータを読む部分や
ループ外の処理もあるため、20fps 前後でしょうか。

spi_asm オブジェクトを OLED ドライバ専用に改造して、
だいたい理論値付近が出るようになりました。

ここでふと気付いたのですが、SDカードドライバの fsrw の転送レートは
10Mbps を超えていました。CPU処理だけでは達成できない速度のため
ソースを読んでみたところ、内蔵カウンタ(ctra, ctrb)を使い 4クロックで 1bit を
読み書きする仕組みを作れるようです。転送速度は瞬間最大で 20Mbps に達し、
余裕の60fps動作が可能になります!これは取り入れるしかありませんね。

次回は、上記のテクニックを研究してもっと高速なOLEDドライバを作ります。


シリアルOLEDモジュール接続

2010/05/17

aitendo で販売されているシリアルOLEDモジュールを接続してみました。
3.3Vで動作し、VRAMはモジュール側に入っています。
あとはセットで900円という価格が魅力でしょうか。

商品ページはこちら。データシートや接続例のリンクもあります。
http://www.aitendo.co.jp/product/2099

プルアップは不要らしいので、各ピンに直結します。今回は以下のようにしました。
P4 -> MOSI
P5 -> CLK
P6 -> DC
P7 -> RES

同ページのサンプルコードをPropeller用に変更して、動作テスト。


無事動きました!所要時間は1時間程度でした。

今回のソースコードはこちら。
ダウンロード (Propeller汎用、要ピン設定)

OLEDモジュール側のコマンドに、フィルやラインの機能がある気がするので、
少し調べてみたいと思います。