まえがき
多くの場合、多くの人がPHPをサイト開発用のツール以外の方法で認識していないという事実に出会いますが、このトピックでそれらを思いとどまらせたいと思います。
今日、電話を受けて、YAMAHAシンセサイザー(特に403モデルのアナログ)のサポートを依頼しました。これには1つの興味深い機能があります-作曲した5曲をメモリに保存できますが、バックアップファイルを除いて何らかの形でコンピューターに取り込むすべてのフォーラムおよびこのシンセサイザーの技術文書に記載されているように、コピーはできません。
.bup形式は、すべての設定と5つの録音された曲を保存するためにシンセサイザーによって使用されます。
これらのメロディを録音する際のアドバイスはすべて、タイムアウト時にシンセサイザーから音楽を録音することですが、これはオプションではありません。
それでは始めましょう
私の手には08PK61.BUPというファイルがありました 。 彼を最初に見ても、肯定的な感情はありませんでした。
06PK61 BackFile
ファイルのasciiヘッダーを読みました。 Googleも肯定的な結果を出しませんでした。
しかし、シンセサイザーは音楽にmidi形式を使用していることを思い出しました。なぜ開発者は標準のmidiストリームをバックアップファイルに保存しないのですか?
「でも、どうやって彼を見つけるのか!」 そして、すべてが簡単であることが判明しました。
判明したように、標準のMIDIファイルのヘッダーは次のようになります。
4D 54 68 64 00 00 00 06 00 00 00 01 00 60
わかりやすくするために、タイトルを5つの部分に分けました。
- Mthd-ヘッダー、これからmidiファイルが始まります
- 00 00 00 06-このブロックの後ろのデータ長(バイト単位)
- 00 00-ファイルタイプ(3タイプ)
- 00 01-MTrkブロックの数
- 00 60-ペース
さて、私はウィキペディアでそれを読んだ後、このファイルの検索にMThdを駆り立てることに決めました。 ここで私は失望しました-ファイル内のバイトのこのシーケンスはそうではありませんでした。 私の手が落ちた。
何もすることはないので、私は記事を最後まで読むことに決め(そして、これは常に行われるべきであることに気づきました)、そこでMTrkレコードを見ました(簡単にそれらについて):
シーケンスで始まる
4D 54 72 6B
データはさらに進み、ブロックはシーケンスで終了します
FF 2F 00
シーケンス4D 54 72 6Bで検索を開始すると、見よ、このようなレコードが3つも見つかりました。
それから問題は小さいままだった:
シーケンスFF 2F 00で終わるMTrkブロックをコピーし、最初に標準のMThdヘッダーを追加して、これらすべてをファイルに書き込む必要があります。
すぐに言ってやった。
結果を中間ファイルに保存してプレーヤーで開くと、録音された音楽が聞こえました
そして今、プログラミングについて
そのようなファイルから1曲を削除する必要がある場合は、大丈夫、それを終了することができますが、この方法で複数のファイルを処理する必要がある場合は、どうでしょうか。 そして、自動化が助けになります。
このテーマに対して実行する必要のあるすべてのアクションを発見しました。次に、それらをまとめて実行します。 コード内:
- ファイルを開く
- ファイルを読む
- 結果をHEXに転送します
- MTrkヘッダーとの一致を検索します(存在する場合)。
- FF 2F 00との一致を見つける
- 結果のインデックスを使用して、部分文字列を変数にコピーします
- 出力ファイルを作成する
- MThdヘッダーと、HEX2BIN関数によって処理されたMTrkブロックを含む変数を書き込みます
- 保存してファイルを閉じる
- ポイント4に戻る
PHPコードの準備:
- <?php
- function hex2bin($ h) //不明な理由でphpにない関数
- {
- if (!is_string($ h)) return null ;
- $ r = '' ;
- for ($ a = 0; $ a <strlen($ h); $ a + = 2){$ r。= chr(hexdec($ h {$ a}。$ h {($ a + 1)})); }
- リターン $ r;
- }
- $ lp = 0;
- $ i = 0;
- $ fh = fopen( 'test.bup' 、 "r" )またはdie( "ファイルを開けません!" ); //ファイルを開きます
- $ file = fread($ fh、 filesize ( 'test.bup' )); //読む
- $ bin = bin2hex($ファイル); // 16進数に変換します
- while (strpos($ bin、 '4d54726b' 、$ lp)!== false ) //デューティサイクル
- {
- $ fp = strpos($ bin、 '4d54726b' 、$ lp);
- $ lp = strpos($ bin、 'ff2f' 、$ fp);
- $ getss = substr($ bin、$ fp、$ lp- $ fp + 6);
- $ fm = fopen( "mid $ i.mid" 、 "w" );
- fwrite($ fm、hex2bin( '4d54686400000006000000010060' 。$ getss)); //ヘッダーファイルMThdおよびMTrkに書き込みます
- fclose($ fm);
- $ i ++;
- }
- fclose($ fh);
- ?>
これはとても簡単です;)
UPD。 (ニックネームeDogsを除く)私に知らないユーザーのアドバイスに基づいて、バイナリ形式に変換する機能について追加します。 代わりに、標準のPHP関数を使用できます。
文字列パック (string $ format [、mixed $ args [、mixed $ ... ]]))