TFT_eSPIとAudioI2SでmediaPlayerを作る(7)

今回はSDカードに保存された音楽ファイルの再生です。

media-player

音楽ファイルの管理は下記の制約に従って下さい。

  • SDカードのrootの下にlibファルダを作成しその中に音楽ファイルを保存する。
    • SDカードには既にフォント用とWeb Radio用に”font”と”url”が有ります。
    • これにフォルダ”lib”を追加します。
  • libフォルダ内での条件
    • 有るフォルダの構成要素はフォルダまたはファイルのみとする。
      • フォルダとファイルの混合は不可。ファイルまたはフォルダのみとする
  • フォルダは階層構造が可能。

この条件の元にSDカードに以下の様に音楽データを保存しました。

上記のデータ SDダウンロード。 解凍してSDカードに保存して下さい。

スケッチの説明

スケッチはここに保存しました。 media_playerダウンロード

スッチの構造は以下の様になっています。

media_player.inoのWiFi設定部には自身のSSIDとPASSWORDを入力して下さい。

SDカードをLCDに挿入し、上記のスケッチをコンパイルして実行して下さい。しばらく待つと

  1.  LCDがこの画面になります。ここで音符のアイコンにタッチしてMedia Playerを選択。
  2.  タイトル表示の欄をタッチすると
  3.  SDカードのLibフォルダに登録されたデータが表示されます。
    • 今回新しく追加した”Up”ボタンは、1つ上のフォルダに移動する時に使用します。
    • 表示されたITEMがフォルダの場合先頭に”/”を付けて表示されます。
    • sample, sample1, sampl2, サンプルの4つはフォルダなので先頭に”/”が付いています。
      • 3−1
        • ここで”/サンプル”にタッチする。
        • 選択画面でフォルダが選ばれると、そのフォルダの内容が表示されます。
      • 3−2
        • ”サンプル”フォルダの下のサンプル1、 サンプル2の2つのフォルダが表示されます。
        • この時点で”Up”ボタンにタッチすると
      • 3−3
        • 1つ上のフォルダに移動します。3−1の画面に戻ります。
        • 今度は “sample”にタッチすると”sample”フォルダのデータが表示されます。
  1.  ここで”mp3_サンプル”を選んで”OK”ボタンにタッチしてメイン画面に戻る
  2.  メイン画面では
    • 選択した”mp3_サンプル”がタイトル表示欄に表示される
    • 画面の下の部分に下記が表示される
      • 左側:経過時間
      • 中央:プログレスバー
      • 右側:トータル時間
    • ここでPlayボタンにタッチすると曲の演奏が始まります。
  3.  曲の進行に合わせて、経過時間とプログレスバーが更新されます。
    • 音楽ファイルがMP3以外の場合、
      • 経過時間は通常に表示される
      • プログレスバーは表示されない
      • トータル時間は xx:xx と表示される
  1.  Pause機能
    • 演奏中、左下の演奏経過時間にタッチすると表示が赤に変わり演奏が停止します。
    • 再び演奏経過時間にタッチすると表示が白に戻り演奏を再開します。
  1.  長いタイトル名の表示(タイトルが表示欄に収まらない場合)

不思議なところ

その1:日本語フォントが潰れる

drawString()を使って直接LCDに日本語フォントを描写するとフォントが潰れてしまう事が分かりました。下記は日本語タイトル ”希望の轍” の表示例です。左はdrawString()で直接LCDに書いた場合。右はSpriteを作成し、それにdrawString()で書き、最後にpushSprite()でLCDに表示させた場合の結果です。理由は分からないのですが、明らかに直接書いた方のフォントが潰れている事が分かります。今回は日本語表示部分は全て一度Spriteに書いてからLCDに表示しています。

その2:pushSprite()すると表示がずれる

下記はSpriteを作成し日本語フォントを表示した例です。左が正常。右はpushSprite()実行後に先頭にズレ(黒い部分)が生じた場合です。両者共に表示関係のコードは同じなのですがあるタイミングから先頭がズレる様になりました。これも原因は分かりません。

色々調べて見ると下記の2つを実行するとズレがなくなる事が分かりました。

  • 構造体に要素を加える
    • スケッチの最初で下記の構造体を定義しています。
      • typedef struct player_state{
        String m_path;
        int pl_device; // 0:web radio 1:radiko 2:Library
        int selected_no[3]; //Selected Station No.
        int st_max; //MAX Station No.
        int vol; //Volume value
        bool flg_mute; //Mute Flg true: on false: off
        bool flg_play;
        bool flg_dir;
        bool flg_wifi;
        int temp_no[10];   //dammy
        } player_state;
    • 最後の要素 int temp[10] を構造体に追加するとズレが無くなりました。
    • また配列の大きさが10くらい無いとズレてしまいます。
    • この要素はスケッチでは使用しておらず、ズレ対策のみで使用しています。
  • ボードマネジャーでesp32のバージョンを下げる
    • 当初最新のバージョン 3.2.0でプログラムの開発を行っていました。
    • ズレが生じた後バージョンを3.0.4に下げたらズレが無くなりました。

最新のバージョンを使いたかったので、今回は構造体にダミーの要素を追加しています。

次は

だいぶ完成に近づいて来ました。次回はmedia_playerにリピートやランダム再生機能を追加して行きたいと思います。