在 Windows 10 上使用 Delphi 和 DirectX 没有声音

问题描述 投票:0回答:2

我在 Windows 10 上使用 DirectX (DirectSound) 时遇到问题。我正在更改一些使用 DirectX(我认为是 DirectX 9)并在 Windows XP 上运行的旧代码。

在 Windows XP 上一切仍然运行良好,但我在 Windows 10 上听不到声音。

该应用程序使用以下文件:DXUTIL.PAS(由 Boris V. 制作的原始 ObjectPascal 转换)、lzexpand.pas(作者:Vadim Bodrov)和 DirectSound.pas(Alexey Barkovoy 的 DirectX 9.0 Delphi / FreePascal 改编)。

procedure TForm1.Button1Click(Sender: TObject);
var
sndgwait : PSound;
begin
InitSB(Handle);
LoadWave(sndgwait,   'D:\game\EXP01.wav', 1);
StartSound(sndgwait, false);
end;

function LoadWave(var Sound: PSound; fn : string; conc : integer) : boolean;
var
cbData, cbdata1 : DWORD;
pd1 : pointer;
hfile : longint;
vreopenbuff : TOFStruct;
begin
hfile := LZOpenFile(PAnsiChar(fn), vreopenbuff, OF_READ);
if hfile < 0 then begin result := false; exit; end;
cbdata := LZSeek(hfile, 0, 2);  // file size
LZSeek(hfile, 0, 0);            //back to the start of the wav
getmem(pd1, cbdata);
LZRead(hfile,  pd1, cbdata);
LZClose(hfile);
if conc < 1 then conc := 1;
result := ParseWaveData(Sound, conc, cbdata, pd1);
end;

function ParseWaveData(var Sound : PSound; conc : integer; cbdata : dword; pd1 : pointer) :  boolean;
var
pWaveHeader: PWAVEFORMATEX;
pDSB: IDirectSoundBuffer;
dsBD: TDSBUFFERDESC;
rr : longint;
begin
if lpDS = nil then begin
result := false;
exit;
end;
Sound := PSNDOBJ(LocalAlloc(LPTR, SizeOf(TSNDOBJ) + (conc-1) * SizeOf(IDirectSoundBuffer)));
Sound^.iAlloc := conc;
Sound^.cbWaveSize := 0;
Sound^.pbWaveData := nil;
pwaveHeader := nil;
Sound^.pbData := pd1;
Sound^.cbSize := cbdata;
if DSParseWaveResource(pd1, pWaveHeader, Sound^.pbWaveData, Sound^.cbWaveSize) then begin
ZeroMemory(@dsBD, SizeOf(dsBD));
dsBD.dwSize := SizeOf(dsBD);
dsBD.dwFlags := DSBCAPS_STATIC or DSBCAPS_GETCURRENTPOSITION2 or DSBCAPS_CTRLFREQUENCY orDSBCAPS_CTRLPAN or DSBCAPS_CTRLVOLUME;//DSBCAPS_CTRLDEFAULT or
dsBD.lpwfxFormat := pWaveHeader;
dsBD.dwBufferBytes := Sound^.cbWaveSize;

if lpDS.CreateSoundBuffer(dsBD, pDSB, nil) = DS_OK then begin
if not DSFillSoundBuffer(pDSB, Sound^.pbWaveData, dsBD.dwBufferBytes) then begin
pDSB._Release;
pDSB := nil;
end;
Sound^.Buffers[0] := pDSB;
for rr := 1 to conc - 1 do begin
lpDS.DuplicateSoundBuffer(Sound^.Buffers[0], Sound^.Buffers[rr]);
end;
end else begin
pDSB := nil;
SndObjDestroy(Sound);
Sound := nil;
end;

end;
Result := Sound <> nil;
end;

function StartSound(Sound: PSound; Loop: boolean = false; waitforend: boolean = false): boolean;
begin
if Loop then
StartSound := SndObjPlay(Sound, DSBPLAY_LOOPING)
else
 StartSound := SndObjPlay(Sound, 0);
if waitforend and not loop then
while SoundPlaying(Sound) do Application.ProcessMessages;
  
end;

function SndObjPlay(pSO: PSNDOBJ; dwPlayFlags: DWORD): Boolean;
var
pDSB: IDirectSoundBuffer;
begin
Result := FALSE;
if pSO = nil then
begin
exit;
end;
if ((dwPlayFlags and DSBPLAY_LOOPING) = 0) or (pSO^.iAlloc = 1) then
begin
pDSB := SndObjGetFreeBuffer(pSO);
if (pDSB <> nil) then
Result := SUCCEEDED(pDSB.Play(0, 0, dwPlayFlags));
end else
Result:= FALSE;
end;

我认为 ParseWaveData 调用中的所有值都是正确的(没有零值)。

我没有收到任何错误。只是没有声音。

这里可能出现什么问题?

或者还有其他方法可以在 Windows 10 上的这个旧应用程序中使用 DirectX 来发出声音吗?任何例子都会很棒。

delphi audio directx
2个回答
0
投票

虽然我不能保证这就是解决方案,但我也不能只是发表评论,因为我没有 50 次代表,但值得一试。我在 Windows 10 声音方面遇到了很多问题,而且通常看起来是随机的!切换应用程序会禁用后台应用程序的声音,游戏编程不会发出声音,甚至用 CD 刻录软件播放音乐来查看是否有正确的曲目也被破坏,Netflix 的声音会被破坏,直到我重新启动,无线耳机无法工作或音量也太大低的。令人气愤。由于 2018 年 4 月 W10 的更改,您可能无法从当前优先事项中夺取控制权,并且不会遇到我遇到的问题。

无论如何,这值得一试:

右键单击任务栏右下角的声音图标。点击 播放或音频设备。右键单击出现的扬声器图标 在设置屏幕中。从弹出菜单中单击“属性”。点击 “扬声器属性”屏幕上的“高级”选项卡。取消选中复选框 允许应用程序进行独占控制并给予独占 模式应用程序优先。


0
投票

我已经解决了这个问题。最终与 DirectX 无关。

hfile := LZOpenFile(PAnsiChar(fn), vreopenbuff, OF_READ);

输入到程序的参数“fn”(字符串)错误。有什么事情搞砸了。文件名不正确,所以应该播放的文件是空的。与 DirectX 无关。我已将上面的命令替换为:

hfile := LZOpenFile(PAnsiChar(AnsiString(fn)), vreopenbuff, OF_READ);

现在可以工作了。

© www.soinside.com 2019 - 2024. All rights reserved.