マイコン工作実験日記

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

Cover Artに再挑戦

2025-01-17 22:00:30 | DoomPlayer

以前、STM32H7B3I-DKで試したAVRCPのCover Art機能ですが、今度はLVGLPlayerのBluetooth Player機能に追加すべく再挑戦しています。以前試した時には、Sportifyを使った場合に正しい画像が表示されない問題があったのですが、現在は改善されたのか正しい画像が表示されるようなのです。しかしながら、時折画像がダウンロードされない問題に遭遇しています。Sportityのコミュニティでも1年半以上前からのスレッドで延々と不具合報告が続いているようです。

当初はCover Art表示機能については、使用できるSRAMが減ってきたのでサポートできないだろうと思っていたのですが、各所で使用するメモリを削ったりして問題なくJPEGの画像データをダウンロードして表示できるようになりました。本記事では、メモリを節約した方法について書き残しておくことにします。

スタック領域の共有 LVGL Playerでは3つのアプリケーションを走らせることができますが、これらのアプリケーションは、複数のタスクにより構成されています。各アプリケーションは同時に実行されることはありませんから、タスクが使用するスタック領域を共有することによりメモリを節約できます。FreeRTOSではスクのスタック領域を動的に割り当てることも可能ですが、LVGLPlayerではメモリ管理の都合上静的にわりあてることにしていますので、共通の領域を使うことで節約しています。

変数領域の共有 各アプリケーションは同時に実行されることはないので、各アプリケーションが使用するメモリ領域も共有することが可能です。これを実現するためには、Linkerスクリプトで、OVERLAYコマンドを使って各アプリを構成するオブジェクトファイルをまとめてグループとすることで、同一メモリ領域に配置してやります。

TJegDecを使う STM32U575にはハードウェアJPEGデコーダは用意されていませんので、ソフトウェアでデコードを行う必要があります。デコードにTJegDecを使うことでlibjpegを使う場合に比べて使用するメモリを削減することができます。

Draw Bufferのサイズを減らす LVGLでは画面描画のためのバッファには、画面サイズの1/10程度のバッファでも充分な速度で動作可能とされています。使用しているLCDは 480x320の RGB565フォーマットですが、ダブルバッファリングで使っていますので、1ラスタ分減らせば2KB近くのメモリを削減できます。

LVGLでは元々TJpegDecがライブラリのひとつとして用意されていますが、そのAPIはAVRCPで使うには向いていないので、用意されているライブラリは使わないことにしました。TJpegDecは約3.5KBのRAMがあれば動作可能とされていますが、AVRCPのCovert Artで使うには  1) ダウンロードしたJPEGデータを保管しておくためのバッファ、2) デコード結果の画像ビットマップを保持しておくためのバッファ の2つのメモリ領域が追加で必要となります。1番目のバッファについては、JPEGデータを受信しながら並行してデーコードを進めるように工夫してやれば、不要にできます。2番目のバッファは、LCDに直接書き込むような使い方であれば不要にできますが、LVGLではImage widgetを使って描画したいので、そうもいきません。結局、2つのバッファともPSRAM上に用意すること(チカラ技!)で対応していますが、1番目のバッファを不要とする対策については後ほど挑戦したいと思います。

Doom Music Playerでは、FFTの表示演出としては回転する放射状バーと低音の強さに応じて大きさが変化する中心画像がありましたが、これらの画像描画にかなりのCPUタイムが消費されていることがわかったので、こちらではアルバム画像は静止表示したままで、FFTも4つのバー表示にとどめることで表示負荷を軽減することとしました。

Sportify Free Planでは時折入る広告表示にもスポンサー名や画像が入るのでそれなりに楽しめるのですが、広告が連続した時に画像取得が失敗することが多いような気もします。曲の入れ替わり(AVRCP的には Track Change)のイベント通知をきっかけとして画像取得を行うのですが、そのタイミングも関係しているのかもしれません。


最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。