wavの音量をコントロールしたい

解決


サトシ  2010-02-25 12:22:33  No: 37758  IP: 192.*.*.*

Personal  6  で勉強中です。

ゲームなどで効果音を出すのにwavファイルをPlaySoundで鳴らしています。この場合最初の一発のタイミングが遅くなってしまうため、対策としてゲームスタートと同時に一発鳴らしておいて実際の効果音のタイミングを合わせています。(2発目からは時間差はなくなります)
最初の一発を目立たなくするためにこの音量を絞るというようなことは可能でしょうか。または鳴らすタイミングの遅れを防ぐような方法があるのでしょうか。よろしくお願いします。

編集 削除
環境?  2010-02-25 12:36:49  No: 37759  IP: 192.*.*.*

OSは?
絞りたいのはWAVE? SPEAKER?

編集 削除
サトシ  2010-02-25 17:22:26  No: 37760  IP: 192.*.*.*

開発しているOSはXPですが使用するPCは雑多です。
発する音がなるべく聞こえないようにしたいと思います。
よろしくお願いします。

編集 削除
jazzin  2010-02-25 17:49:23  No: 37761  IP: 192.*.*.*

1度目のタイミングが遅くなるという根本の原因を探った方が良いかと思うのですが、
PlaySoundで鳴らすデータソースは何になりますか?
言い換えればPlaySoundをどのような引数を指定して呼び出していますか?
例えばファイルから(SND_FILENAME)であれば、1度目はファイルアクセスが発生するので遅く、
2度目からはキャッシュが効いて速くなることが考えられます。
その場合はあらかじめメモリにロードしておくことで解決できるかもしれません。

編集 削除
サトシ  2010-02-26 11:19:52  No: 37762  IP: 192.*.*.*

jazzin様。ありがとうございます。
最初のサウンドの遅延はご指摘のようにファイルのアクセスに要する時間の分だけ遅れ、2度目からはキャッシュによって遅延がなくなるものと思います。音を出さずにキャッシュに入れる方法として音量を絞って鳴らすことを考えたものですが鳴らさずにメモリにロードする方法があるとは知りませんでした。現在は次のようにやっています。(見よう見まねです)

procedure SHOOT;
var rs:tresourcestream;
begin
    rs:=tresourcestream.create(hinstance,'gun','wave');
    playsound(rs.memory, 0, SND_ASYNC or SND_memory);
    rs.free;
end;

編集 削除
monaa  2010-02-26 14:09:43  No: 37763  IP: 192.*.*.*

で、解決ですか?
それとも依然として遅延するんですか?

編集 削除
サトシ  2010-02-26 14:33:04  No: 37764  IP: 192.*.*.*

失礼しました。
現在はこれ(SHOOT)を呼び出すと一発目は遅れ、2発目から即時鳴ります。

編集 削除
サトシ  2010-02-26 14:51:07  No: 37765  IP: 192.*.*.*

皆様ありがとうございました。
メモリーにロードとはどうやれば良いか、などと考えていましたがもしやと思い(何もわからずに)下のようなSHOT0;を作って試してみました。

最初の一発はSHOOT0を起動してメモリに入れ、本番でSHOOTを呼び出したら遅延はなくなりましたので解決とさせていただきました。もしもこのやり方がおかしい/間違っているようでしたらご教示お願いします。ありがとうございました。

procedure SHOOT0;
var rs:tresourcestream;
begin
    rs:=tresourcestream.create(hinstance,'gun','wave');
    rs.free;
end;


procedure SHOOT;
var rs:tresourcestream;
begin
    rs:=tresourcestream.create(hinstance,'gun','wave');
    playsound(rs.memory, 0, SND_ASYNC or SND_memory);
    rs.free;
end;

編集 削除
Quest  2010-02-26 15:56:35  No: 37766  IP: 192.*.*.*

こういう時には、アプリの起動時に
rs := TResourceStream.Create(hinstance, 'gun', 'wave');
これだけやっておき
終了する前に
rs.Free;
を行うようにします。
そして必要なときに
PlaySound(rs.memory, 0, SND_ASYNC or SND_memory);
だけを実行するようにすればいいんじゃないでしょうか。

編集 削除
サトシ  2010-02-28 13:15:18  No: 37767  IP: 192.*.*.*

Quest様、ありがとうございます。
よくわからずに作っていましたので参考になりました。
心配してすぐに開放することを考えていましたがご指摘のように起動時にCreateしてClose時に開放すれば良いわけですね?  早速本体に実装してみます。  ありがとうございました。

編集 削除