準備
お付き合いいただく前に準備してほしいこと。
まずはLazalusのインストール です
IDEは日本語に設定します
[Tools]-[Options]「IDE Options」窓でEmviroment-General 右上のLanguage をJapanese[Ja]でOKボタンでLazalus再起動
必要な追加すべきパッケージはACSです
インストールされてるパッケージに[laz_acs 3.03] [laz_acs_lib 3.03]がある状態が必要です
IDE[パッケージ(c)]に[Online Package Manager]が無ければ
IDE[パッケージ(c)]-[パッケージをインストールもしくはアンインストール]よりOnline Package Managerインストール
IDE[パッケージ(c)]-[Online Package Manager]
便利 jcfidelazarus をパッケージに追加しておけば"Ctr+D"で全行の整形をDelForExのようにしてくれます。IDEオプションにJCF整形設定があり細かな設定も可能です
ダウンロードしたacsパッケージは C:\lazarusではなくC:\Users\自分の場所\AppData\Local\lazarus\onlinepackagemanager\packages にあります。ここに説明も demosフォルダにサンプルもあり ".lpi" をクリックすればLazarusが開きますからお試し下さい。
DirectX系のソースも入ってるようですが、DirectSound.pas等が入ってないようでコンパイルはできませんでした。
さて問題は計算で音を出したい場合です。TAcsCustomInput継承のもので使えそうなのは
AcsMemoryIn
AcsStreamIn
あるいは TAcsCustomInput を継承して自分で作るかになります。
継承して自分で作るのはある程度動作したので後で公開するとして、この2つについて
AcsMemoryInはOnBufferDoneでデーター作ってやるのでしょうが、やってみるとどうすれば良いのか分からず断念。
AcsStreamInを使ってLazarusのACSで計算音を作る8step
●1.プロジェクト(P)->新規プロジェクト アプリケーションを選び[OK]
●2.Audio I/O タブから TAcsStreamIn(右から3つめ)をクリック後 Form1をクリック
●3,Audio I/O タブから TAcsAudioOut1(左から2つめ)をクリック後 Form1をクリック
●4.Form1の何もない所をダブルクリック 以下のコピペ
{copyするのは begin~end;の中の3行です}
procedure TForm1.FormCreate(Sender: TObject);
begin
AcsStreamIn1.InBitsPerSample := 16;
AcsStreamIn1.Stream := TMySnd.Create(AcsStreamIn1);
AcsAudioOut1.Input := AcsStreamIn1;
end;
●5.上記FormCreateの上にカーソルを出して以下をコピペ
type
TMySnd = class(TStream)
protected
FPosition: Int64;
AcsStreamIn: TAcsStreamIn;
function GetPosition: Int64; override;
public
constructor Create(const Parent: TObject);
function Read(var Buffer; Count: Longint): Longint; override;
end;
constructor TMySnd.Create(const Parent: TObject);
begin
AcsStreamIn := Parent as TAcsStreamIn;
end;
function TMySnd.Read(var Buffer; Count: Longint): Longint;
var
i, sz: Longint;
D16: array[0..9999] of Int16 absolute Buffer;//Bufferを無理やり配列D16に見せるおまじない
begin
with AcsStreamIn do begin
sz := ((Count * 8) div InBitsPerSample) div InChannels; //出力すべき最大のサンプル数
if InBitsPerSample <> 16 then raise Exception.Create('8bit未対応');
if InChannels <> 1 then raise Exception.Create('ステレオ未対応');
end;
for i := 0 to sz - 1 do begin//お試しで440Hzサイン波を出しています
D16[i] := round($7f00 * sin(PI() * 440.0 / AcsStreamIn.InSampleRate * FPosition));
Inc(FPosition, 2);
end;
with AcsStreamIn do
Result := (sz * InBitsPerSample * InChannels) div 8; //奇数の場合の為
end;
function TMySnd.GetPosition: Int64;
begin
Result := FPosition;
end;
●6.Standard タブから TButton をクリック後 Form1をクリック
●7.そのButton1をダブルクリックして以下のコピペ
{copyするのは begin~end;の中の10行です}
procedure TForm1.Button1Click(Sender: TObject);
begin
with Button1 do
if Tag = 0 then begin //Tagは自由に使える変数のようなもの
Tag := 1;
Caption := 'STOP';//動作中STOP表示 押せば止まるという意味
AcsAudioOut1.Run();//このメソッドでReadが何度かされて音が出始めます
end else begin
Tag := 0;
Caption := 'サイン波開始';
AcsAudioOut1.Stop();
end;
end;
●8. F9で実行 問題なければ[Bottun1]を押せば音が出て再度押せば音が止まります
やってる内容はTStreamの継承クラスReadで16bitの配列に出力してるだけです。GetPositionメソッドも必要になるので結構面倒に見えますね。イベント処理で書けたら良いのに。
記述途中です 追加内容によっては一部が有料になるかもしれません。
関連ブログ
を購入された方が添付ソースをビルドしたい要求があるかもしれないと、Lazarusの設定について先に公開しました