foobar2000用の自作コンポーネントのバージョンアップをした。およそ20日ぶり。バグ取りだけ。
先月追加した部分、iPodとの連携部分だけれども、実機試験をサボったため、バグっていたのだ。爆弾を踏まなかっただけのようだ。が、先日、異常終了したケースが出たのだけが不明だけれども、それも治っていると期待する。
一件は、単純ミスで、新しいDBアクセス関数を追加したときにそこで発行するSQL文が文法エラーになっていたので、SQLが絶対に成功しないというバグ。SELECT文なのだけど、デバッガで追いかけていて、パラメータのBINDでエラーになるからおかしいな?と思ったら、初歩的なミスで、FROM句が抜けていた。テーブル名を指定しないSELECT文など実行しようがない。
で、SQLが成功すると、文字列としてファイル名がテーブルから取得できるようにしておいたのだけれども、ここでもWindowsプログラミングから離れていたのでミスが。strcpyを使おうとしていたのだけれども、コンパイルで警告だかエラーになるので、strcpy_sにしていた。これは第2引数に長さを指定する。3つの引数に、コピー先、長さ、コピー元と指定するのだけども、この長さは、コピー先バッファ長であって、コピー元文字列長ではない。ヘルプをきちんと読んでおけばよかったのに、読まないで適当に書くからコピーしたい長さと勝手に誤解してプログラミングして落ちる。充分なバッファ長を用意いておいても第2引数がコピーしたい文字列長であれば、バッファ長不足で落ちる。で修正。
最後にやっとfoobar2000のSDKレベルの話。元々ローカルファイルパスを取得するのは画面をリフレッシュするため。ファイルパスから、media_handle_ptrを取得すると、refreshメソッドが呼び出せて、それを呼び出すことによって画面表示用のデータが最新のものに置き換わる。自作コンポーネントのSQLiteデータベースを更新したあとで呼び出せば更新後のデータでリフレッシュされる。呼び出さなければ、再生開始とか、フィルターをかけた時とか、OSが再描画をかけた時など、意図しないタイミングでしか最新の情報に置き換わらない。プレイリストを選択しても、同じトラックなのに違う情報が表示される状態になったりする。
そのためには、ファイルパスから、playable_locationというクラスのオブジェクトを作成し、そこからmedia_handle_ptrを取得する。SDKのソースを読んだ限りではこの方法しか見つからなかった。で、ファイルパスは、file://C:musicfoo.mp3などという形式で指定するらしい。iTunesからCOMで頭のfile://を削除してデータベースに格納していたのに、foobar2000で必要になるとは皮肉である。作成し直すことも検討しようかと思う。
再生中は置き換えが得できないので、最新バージョンは明日から使う予定である。といっても自分のための、自分だけが使っているコンポーネントなので別の致命的なバグが見つかったら元に戻すのだけれども。
コメント