【发布时间】:2010-08-25 08:10:14
【问题描述】:
我希望在 delphi 中同时处理多个 .wav 文件。
当我打开并放置第一件事时,一切都很好。 但是,第二个在尝试打开时会导致错误。
看来我一次只能使用一个媒体播放器....有什么办法可以解决这个问题吗?
【问题讨论】:
标签: delphi audio media-player pascal wav
我希望在 delphi 中同时处理多个 .wav 文件。
当我打开并放置第一件事时,一切都很好。 但是,第二个在尝试打开时会导致错误。
看来我一次只能使用一个媒体播放器....有什么办法可以解决这个问题吗?
【问题讨论】:
标签: delphi audio media-player pascal wav
你会如何播放单个声音?当我想要精细控制时,我使用waveOut 函数,如this answer。我在那里的回答还允许您使用线程播放声音(也就是说,除其他外,异步)。我认为你可以同时播放两种声音,只需同时启动两个这样的线程,如果你只用全局threadvars替换全局vars。
播放单个声音的最简单方法是使用PlaySound。这可以异步使用,但是既然你问了这个问题,我假设这不允许你连续两次使用这个函数来开始同时播放两个文件。但是:如果你创建了一个只播放声音的线程(同步,这样线程在播放结束之前就不会死掉),那么你可以可能使用两个这样的线程同时播放两个音频文件。 (我现在无法使用 Delphi 编译器,所以恐怕我无法检验我的假设。)
我的假设是,如果只从两个不同的线程调用函数,您可以对PlaySound 进行两次调用,但显然这还不够好。看起来你真的需要两个不同的过程,这很糟糕(很明显)。我试过了
procedure TForm1.FormCreate(Sender: TObject);
begin
with TSoundPlayerThread.Create(true) do
begin
SetFileName('C:\Users\Andreas Rejbrand\Downloads\Anna.wav');
FreeOnTerminate := true;
Resume;
end;
with TSoundPlayerThread.Create(true) do
begin
SetFileName('C:\Users\Andreas Rejbrand\Downloads\Mike.wav');
FreeOnTerminate := true;
Resume;
end;
end;
与
unit SoundPlayerThread;
interface
uses
Classes, MMSystem, Windows;
type
TSoundPlayerThread = class(TThread)
private
{ Private declarations }
FAudioFileName: string;
protected
procedure Execute; override;
public
procedure SetFileName(const FileName: string);
end;
implementation
procedure TSoundPlayerThread.Execute;
begin
PlaySound(PChar(FAudioFileName), 0, SND_SYNC);
end;
procedure TSoundPlayerThread.SetFileName(const FileName: string);
begin
FAudioFileName := FileName;
end;
end.
只播放了后一个波形文件。
我实际上已经编写了一个小型 WAV 文件库。使用它,我可以加载两个 WAV 文件,合并它们,然后将结果发送到音频驱动程序。但是,这里发布的代码太多了。如果有一天我有时间,我可能会编写一个更轻量级的PlaySimultaneously 过程并发布它。
否则:DirectX?
【讨论】:
您可以使用DirectShow 转换过滤器,它是一个 Microsoft Windows 应用程序编程接口 (API),使 Windows 应用程序能够与 Windows“媒体”输入设备进行交互和控制,
或者您可以使用WaveMix DLL,它是一个允许同时播放多个WAV 文件的实用程序。它被设计为尽可能简单易用,但仍然有能力完成游戏所需的操作。 DLL 支持 8 通道同时播放波形、沿同一通道排队波形和波形完成通知的能力。
【讨论】:
我是这样做的:
//yup, i used more than 1 MediaPlayer controls.
MediaPlayer1.FileName:='song1.wav';
MediaPlayer2.FileName:='song2.wav';
MediaPlayer1.Open;
MediaPlayer2.Open;
MediaPlayer1.Play;
MediaPlayer2.Play;
//the next lines of code is checked every so often in my Timer event handler.
if MediaPlayer1.Position=MediaPlayer1.Length then begin
MediaPlayer1.Close;
end;
if MediaPlayer2.Position=MediaPlayer2.Length then begin
MediaPlayer2.Close;
end;
【讨论】:
您可以为此使用SoX (Sound eXchange)。它可以播放和录制音频文件,应用各种效果,转换各种格式......
勾选-m参数同时播放文件。
示例:
sox -m 1.wav 2.wav -d
【讨论】:
如果您想要一个真正的异步 wav 文件以模拟方式播放,并且不打断其他文件, 真正的解决方案是 mitov labs-audiolab。 http://mitov.com/products/audiolab sndPlaySound ?不工作 mciSendString?没有按预期工作。 因此,没有简单的 winapi 解决方案或 snd_async 参数等有效。 只有 mitov audiolab 工作得这么好。 检查它并删除线程解决方案作为答案。它不能同时工作。 一波打断另一波。 mitov audiolab 是对我有用的真正解决方案。所以在这里与大家分享。希望这对某人有所帮助。
【讨论】:
我认为我们可以使用
sndPlaySound('filename1.wav',SND_SYN OR SND_NODEFAULT);
sndPlaySound('filename2.wav',SND_SYN OR SND_NODEFAULT);
sndPlaySound('filename3.wav',SND_SYN OR SND_NODEFAULT);
sndPlaySound('filename4.wav',SND_SYN OR SND_NODEFAULT);
【讨论】: