■TOggPlayer クラス
■説明
TOggDataでは単一のレンダリングしかできませんでした。
そこで、TOggPlayerはこれらをまとめあげ、波形を合成し、複数同時再生、音量コントロールなどの機能を提供します。
よ〜するに、再生するにはこれをつかえ〜ってことですな〜
■使用する前に
必ず _VorbisfileInitialize 命令でDLLを組み込む必要があります。
起動時に一回だけ実行すればいいので、FormCreateの最初にでも宣言するといいでしょう。
また、解放時には _VorbisfileFinalize 命令でDLLを解放してください。
■フェードについて
このライブラリでは一部の音量とEQ(イコライザ)にフェード機構を持っています。
が、ちょっと他と違う機構ですので説明しておきます。
フェードといってもそのような名前の付く関数は存在しません。
音量操作を例にとってみましょう。
SetVolume(音量、時間)
音量を設定するものですが、時間という概念が存在しています。
この時間がフェードに深くかかわります。
SetVolume(音量、0)とした場合、
時間を0秒とすると、「0秒後に指定された音量になるようにセットする」という意味になり、即音量が反映されます。
ということは
SetVolume(音量、3)とした場合、
「3秒後に指定された音量になるようにセットする」という意味になり、音が徐々に変化し、3秒後に設定された音量になります。これがフェードになります。
イコライザに対しても同じで
SetEQ(周波番号、音量、時間)
時間によってフェードを実現させることが出来ます。
ただし、この時間をものすごごく長くしたりすると、精度の問題で時間に誤差が生じたり、作動しなかったりする場合があります。30秒以内にとどめるといいでしょう。
音量をフェードアウト(SetVolume(0.0,1.0))させると、音量が0になった時点で自動的に一時停止状態になります。その状態からフェードインさせるには
SetVolume(1.0,1.0);
Play(FALSE)
と再生命令も発行しないと再生されない点に注意してください。
■音量について
TOggPlayerでは、以下の3つのボリュームコントロールが存在します。
・MasterVolume
・ChannelVolume
・Volume
まずOggをエンコードしたWave波形は、フェード機能を持ったVolumeが適用されます。
その後、各チャンネルごとの音量を意味するChannelVolumeと、
コンフィグなどで音量調節できるように設けられたもう1つの音量であるMasterVolumeが適用されてストリーミングへと渡されスピーカーから出力されます。
Oggファイル → x Volume x ChannelVolume x MasterVolume → 出力
このうち、フェード機能を実装するのはVolumeだけです。あとは、調整用とかそういう風に使ってください。
■EQ(イコライザ)について
イコライザによって、周波数帯域に変更を加えることが出来ます。
このライブラリでは256分割の周波数帯域を各々設定することが出来ます。
が、非常に面倒なので、数個設定してあとは勝手に補完してくれる命令(SetEQ4など)も用意しましたのでお好きな方をお使いください。
このライブラリにはイコライザのON/OFFのフラグが存在しません。
「これではずっとONのままなのか?」という疑問も生まれると思いますがご安心を。
ライブラリ側がEQがかかっていない状態(全ての周波数の音量が1.0であるとき)は勝手にOFFにし、EQを必要とする状態(任意の周波数の音量が1.0以外になった)場合は勝手にONになります。
以下、例。
・ONになる場合
OggPlayer.SetEQ4(0, 1,2,1,1, 3);
・OFFになる場合
OggPlayer.SetEQ4(0, 1,1,1,1, 0);
■プロパティ
・OggData : array[0..7] of TOggData;
弄らないように。
■メソッド
〜生成・解放・初期化〜
・destructor Destroy; override;
解放。
・constructor Create(Len:Integer; MaxCh:Integer);
生成します。
Lenはストリーミングバッファと同じ長さにしてください。
MaxChは同時再生チャンネル数。1〜無限・procedure Init;
人生のリセット。
〜登録〜
・procedure Load(ch:Integer; o:TOggdata);
TOggDataをPlayerに登録します。
同じTOggDataを多重登録は出来ません。・procedure UnLoad(ch:Integer);
指定チャンネルのTOggDataを解除します。
TOggDataの解除で、開放ではありません。
不要になったTOggDataは必ず開放してください。
〜レンダリング〜
・procedure Rendering;
波形をレンダリングします。
これを行わない限り、再生時間も進みません。・function RenderingToPointer(d:Pointer; Len:Integer):Integer;
指定のポインタにレンダリングさせます。
Renderingより低レベルな使用をするときに使います。
〜演奏制御〜
・procedure Play(Loop:Boolean); overload;
・procedure Play(ch:Integer;Loop:Boolean); overload;再生を行います。
あらかじめLoadでTOggDataを登録しておく必要があります。・procedure Stop(ch:Integer); overload;
・procedure Stop; overload;再生を停止します。
再生位置が先頭に戻ります。・procedure Pause(ch:Integer);
現在の場所で一時停止します。
〜音量制御〜
・procedure SetMasterVolume(v:Single);
・procedure SetMasterVolume(ch:Integer; v:Single);
・function GetMasterVolume(ch:Integer):Single;・procedure SetChannelVolume(ch:Integer;v:Single);
・function GetChannelVolume(ch:Integer):Single;
どちらも各チャンネル対してかけるボリュームコントロールです。
フェード機能はありません。
ChannelVolumeをプログラムでの音量調整用、MasterVolumeをコンフィグの音量設定に使うといいかもです。
Volume x MasterVolume x ChannelVolume = 最終出力音量となります。0.0〜1.0までの範囲で音量を設定します。
・procedure SetVolume(ch:Integer;v:Single); overload;
・procedure SetVolume(ch:Integer;v,t:Single); overload;チャンネルに登録されているOggDataの出力音量を設定します。
フェード機能を備えています。
vが音量で、0.0〜1.0〜2.0の範囲で指定します。
tは時間(秒)で、指定秒後にvで指定した音量になるようにフェードします。SetVolume(0, 0.5, 6.0)の場合は、6秒後に音量が0.5にフェードするという意味になります。
・function GetNowVolume(ch:Integer):Single;
今現在の音量を返します。
フェード中の場合は、命令を発行した瞬間の音量を返します。・function GetSetVolume(ch:Integer):Single;
SetVolumeで設定した音量を返します。
フェード中でも、関係なく、フェード後の音量を返します。
〜EQ(イコライザ)〜
・procedure SetEQ(ch,h:Integer; v:Single); overload;
周波数成分ごとの音量を設定します。
chはチャンネル番号。
hが周波数成分で、0〜255までの範囲で設定します。
vが大きさになります。0.0〜2.0までの範囲とします。・procedure SetEQ(ch,h:Integer; v,t:Single); overload;
周波数成分ごとの音量を設定します。
tは時間で、音量と同じく、フェード時間を意味します。・function GetNowEQ(ch,h:Integer):Single;
現在の周波数の音量を返します。
・function GetSetEQ(h:Integer):Single;
設定した周波数の音量を返します。
・procedure SetEQ16(ch:Integer; v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16, t : Single);
・procedure SetEQ8(ch:nteger; v1,v2,v3,v4,v5,v6,v7,v8, t:Single);
・procedure SetEQ4(ch:Integer; v1,v2,v3,v4, t:Single);256個も設定するのは非常に面倒な場合も多々あります。
そこで、数個設定してやることで、エルミート曲線を用いて滑らかに全てを設定する関数です。
16個、8個、4個とあります。
〜シーク〜
・procedure TimeSeek(ch:Integer; t:Single);
指定した時間(秒)まで曲を進めます。
・function TimeTell(ch:Integer):Single;
現在の再生時間(秒)を返します。
・function TotalTime(ch:Integer):Single;
この曲の長さを時間(秒)で返します。
〜ループ制御〜
・function GetLoopCount(ch,n:Integer):Integer;
n番目のループカウンタを返します。
n番目とかは、付属ツールでループ設定する時にありましたよね。あれです。
0〜15までの計16個あります。何回ループしたかを返します。まぁ、使わないか・・・。
・procedure SetLoopCount(ch,n,l:Integer);
上で言った、ループカウントを自分で設定します。
本来2回ループするところに、255なんかを代入すると、ループを抜けることが出来ます。
ボスを倒した瞬間に、曲を次のループに進めたい場合なんかにどうぞ。
〜リアルタイム〜
・function GetOutputWavePos(ch:Integer): Integer;
・function GetMasterOutputWavePos: Integer;リアルタイムで現在再生中の位置を返します。
Pointerではなく、仮バッファ上の位置をBYTE単位で返します。
時間計算で算出しているので、多少の誤差は出ます。Masterは全波形を合成したもの、つまり最終出力の波形指します。
・function GetOutputSum(ch:Integer):Single; overload;
・function GetMasterOutputSum:Single; overload;
リアルタイムで再生中の音量の合計値を0.0〜1.0の範囲で返します。
左右を合計した値を返します。・function GetOutputSum(ch,c:Integer):Single; overload;
・function GetMasterOutputSum(c:Integer):Single; overload;リアルタイムで再生中の音量の合計値を0.0〜1.0の範囲で返します。
cに次の数値を設定することで左・右・両方の値を取得できます。
0:Left
1:Right
2:Both・procedure GetOutputGraph(ch:Integer; d:PSingle);
・procedure GetMasterOutputGraph(d:PSingle);リアルタイムで周波数成分を取得します。
dにはSingle[256]のポインタを渡します。
0(低周波)→255(高周波)というならびで返されます。・function GetOutputTime(ch:Integer):Single;
現在の再生経過時間をリアルタイムで返します。
が、内部で計算によって補間した値なので、正しいものではありません。
〜状態〜
・function GetLoopPlay(ch:Integer) : Boolean;
ループ再生してるかどうか。
・function GetPlay(ch:Integer) : Boolean;
再生してるかどうか。
〜レンダリングポインタ〜
・function Memory : Pointer;
合成結果をレンダリングする仮バッファ領域のアドレスを返します。
・function Offset : Pointer;
レンダリング(Rendering)して合成した結果のバッファの先頭アドレスを返します。
Wav.BlockCopy(ofs,OggData1.Offset,Len)
というカンジで使います。