FATFSを用いたLFNファイル名によるソート
えっと、今日の日記はタイトルの説明から必要ですよね。
用語の説明からさせて頂きます。
FATFS:PIC界に後閑さんが有るならば、AVR界にその人有りと言われた
フリーソフトとして配布されています。
Chanさんありがとう!
LFN :LongFileNameの略。FATファイルシステムで13文字を超えるファイル名をこう呼びます。
この二つはFATファイルシステム上、大きな違いがあるのですが
ちょっとややこしいので、詳しくはChanさんのHPを参照頂ければと存じます。
ソート :バラバラなものを並べ替える事です。
参考の為に、FATシステムの概要を図1.に示しました。(図の右下をクリックで拡大されます)
図1.FATシステムの構造概要
つまり、今日の主旨はFATFSの機能を使って、
バラバラにおかれているmp3ファイルの順番を綺麗に並べ替えよう!という事です。
○ソートの方法を考えてみる。
まず、図2.をご覧ください。
図2.ソート前のLFNの表示
これはRHYMESTERというヒップホップグループの、リスペクトというアルバムをmp3化したものです。
是非、4番のB-BOYイズムは聞いて頂きたいのですが、そういう話は今は置いておいて・・・
わざとバラバラの順序でSDカードに記録したおかげで
そのままディレクトリエントリからLFNを呼び出すと順番が無茶苦茶になります。
これを並び変える訳ですが、こういう時はこのアルバムだけじゃなく
どんな内容のフォルダにも使えるような汎用性のあるソート方法にしたいものです。
LFNは規格上最大255個の2byte文字で構成されます。
つまり1曲に付き(NULL文字を含めて)最大512Byteをファイル名だけで使ってしまいます。
例えばこれが100曲入っているフォルダだとしたら、51.2kByteですね。
曲のソート中は曲の順番の情報を覚えておく必要があるのですが、
まともにLFNのファイル名でテーブルを作ろうと思ったら外部SRAMが必要になってきます。
省メモリでソートできるように次のような解決方法を考えて見ます。
1.LFNの先頭に3桁くらいの数字を書き込んで読み出せば1曲6Byte+エントリNoの
ワーク配列でソートできる。
(エントリNo:ディレクトリエントリのID)
△処理はとても高速。ただしファイル名を書き換える必要がある。
2.SFNでソートする。
さらに図3.のように自動生成されたSFNが思ったよりカオスだった。
図3.「図2.」のSFNバージョン。順番は変わっていない。最後の数字だけ変化するものだと思っていたら・・・
3.常にLFN同士を比較して、結果をSFNテーブルの組み換えの形で反映する。
△SFNテーブル(13Byte×ファイル数)と2つのLFN配列(1024Byte)が
有ればLFNのフルネームソートができる。
ただ、比較の度にディレクトリエントリからフルネームを呼び出すので、超遅い。
しかも該当のLFNを呼び出す為に、毎回、ディレクトリエントリの先頭から調べています。
何百回,何千回SDカードにアクセスする事になるのやら。
検討の結果3番の方法にしました。STM32のパワーが有ればなんとかなる!力技でGOGO!
○ソート処理の過程
それでは具体的な処理を説明します。
ただし、今回の場合は項目の交換は最後まで比較が終わった時点で行います。
図4,5に処理の過程を図示します。(図の右下をクリックで拡大されます)
図4.処理過程前半
図5.処理過程後半
ソート処理だけなら、SFNリストではなく、項目番号の配列だけでも可能なのですが、
FATFSのファイル指定にはSFNが必要なのでここでリストを作成しています。
図6.やったー出来たー!
20曲程度なら一瞬で並び替えが出来ました。さすがSTM32やでぇ・・
○ソートのコード
FATFSのf_stat関数を使うと、確保したDIL構造体のlfnameは何故か空で返されるので
f_readdir関数を使ってLFNを繰り返し呼び出すという
しこたま効率の悪いmy_f_statという自作関数でSFNからLFNを呼び出しています。
もしよろしければご覧ください。