mldspにステータスパネルを追加して、演奏コントロールもできるように改造してみた。ファイルを選択して再生する部分は今までもあったけど、ここに一時停止と停止が付く。ただ停止に対応するUIのリセットがまだ出来ていない。難しくはないのだけど面倒でやっていない。ひとつには、キーボードまわりだけまだprocessingのコードを引きずっていて、ちゃんと制御するように出来ていないという話がある。これはまあ、やる気の問題だ。
テンポとトータル演奏時間も表示するようにしてみた。テンポは実際にmetaイベントで送られてくる値は意味不明過ぎるので、シーケンサ等でBPM指定して、SMFファイル生成時にmetaイベントのテンポ指定の値に変換していた(であろう)ものを、BPMに逆変換してやらないといけない。
画面上に乗っかる主な部品としては、あとスペアナとキーオンメータ(ここに音色とパンが一緒に表示される)、それと(デスクトップ向けには)ファイルセレクタ、くらいではなかろうか。ファイルセレクタはWeb版ではあまり意味が無いのだけど。isolated storageに保存しておけば良いだろうか。
ステータスパネルでは、演奏時間の経過表示も実装しなければならないのだけど、この辺から、少し状態管理もややこしくなる。ユーザからの入力を画面に反映させる部分と、楽曲からのイベントを画面に反映させる部分と、時間経過によって自動的に更新されなければならない部分があって、後2者は実のところまだ出来ていない。演奏時間は、GUI上でアニメーションするのが一番簡単なのだけど、一時停止中は更新されないことになるし、テキストで演奏時間を表示するやつは、一時停止を考えると演奏開始時間を使った単純な引き算ではまずいので、これはプレイヤ実装の方で管理した方がいいだろうと思っている(これが一時停止なども把握している)。
話をさらにややこしくするであろうものが、ジャンプと早送り/巻き戻し機能だ。MIDIデータを作っている時は必須に近い機能なので、実装するつもりはある。あと今UI上には存在していないのだけど、スロー再生とスキップも実装できるだろう。
もう少し整理して書くなら、早送りとスロー再生はテンポ計算の補正値の問題で、スキップと巻き戻しはジャンプの応用だ。前2者は実のところプレイヤ上にテンポ補正を実現するコードがあるので、今すぐにでも出来る。後者は小節単位でやるのが望ましいだろうが、いずれにしてもスキップの応用なのでスキップの実装が出来てからだ。
スキップは、プレイヤ上は、スキップ先の絶対時間(マイクロ秒なりステップカウントなり)を入力として受けて、フォーマット0のかたちでマージされたシーケンスの先頭からそこまでのイベントの時間を計算しつつスキップする、というやり方でいけるだろうが、その間のイベントを全部スキップするわけにはいかない。音色やピッチベンドの変更を保持しておく必要がある。しかも全ての変更をバカ正直に転送するわけにはいかないので(ピッチベンドやエクスプレッションは、リアルタイムでも短いステップで大量に送信されることが多く、それがスキップで全部押し寄せたら、音源側が処理しきれない)、仮想マシンで最後に格納されたレジスタ値を送信する、というやり方になるだろう。
スキップを実際に処理する前に、一時停止してオールサウンドオフしておく必要もある。ただし、一時停止状態でスキップを実行したら、その後勝手に再開しない方が望ましいし、演奏中にスキップを実行していたら、そのまま再開するべきだろう...という状態の遷移を考えると、スキップの準備として一時停止することで状態を壊さない必要もある。この辺の実装はプレイヤ上で行うのが妥当だろう。
GUI上は、スキップ命令を受信したら(これは、おそらく演奏状態バーの上をmouseupしたタイミングで行われる)、GUI上のキーオン状態を全てクリアしてから、プレイヤ上でスキップを実行する。その後、演奏時間関係のプロパティ(テンポ、演奏カウント、経過時間など)を再表示する。
...と、まあこういう実装にすれば、概ね解決するような気はしている。まあ、ジャンプ以外はニッチなので、後回しにする可能性が高いけど。
Leave a comment