【问题标题】:WinAPI: How to make sound effect keep up with each mouse clickingWinAPI:如何让音效跟上每次鼠标点击
【发布时间】:2021-09-28 06:33:31
【问题描述】:

确保每次单击鼠标后都会播放声音。
我的想法是创建一个持续运行的线程。

#include <pthread.h>
music ding1("./ding1.wav");
music ding2("./ding2.wav");
void* pmusic(void* a)
{
  while(1)
  {
    DWORD dw=WaitForSingleObject(hmusic, INFINITE) ;
    if(ding1.busy)
    {
      ding2.play();
    }else{
      ding1.play();
    }
    ResetEvent(hmusic);
  }
}

创建一个公共信号。

HANDLE hmusic=CreateEvent(nullptr,false,false,nullptr);

在音乐类中使用 playsound 函数播放声音

class music
{
public:
music(char* path)
{
  //load the wav file to memory
  fs.open(path...);
  ...
  fs.readsome(buf...);
  ...
}
play()
{  
   busy=1;
 
 PlaySoundA(buf,null,SND_MEMORY,SND_ASYNC,SND_NOSTOP,SND_NOWAIT);
  busy=0;
}

char * buf;
int busy;
...
}

WndProc

LRESULT CALLBACK WndProc(hwnd,msg,wparam,lparam)
{
  switch(msg)
  case WM_LBUTTONDOWN:
  {
    SetEvent(hmusic);
    break;
  }
  case WM_LBUTTONUP:
  {
    ResetEvent(hmusic);
    break;
  }
  case WM_CREATE:
  {
    pthread_create(&tid,null,pmusic,null);
    break;
  }
}

编译后在 Windows 10 上运行,通过 mingw32 没有问题。
也许还有另一种不同的方式来实现上述目标。
感谢您分享您的智慧和经验。

【问题讨论】:

  • 如果您从不等待事件,那么通过CreateEvent() 创建事件对象有什么意义?您可能打算在线程中使用 while (WaitForSingleObject(hmusic, INFINITE) == WAIT_OBJECT_0) 而不是 while(1)
  • 另外,play() 使用SND_ASYNC 标志调用PlaySoundA()(不正确),所以PlaySoundA() 将始终立即退出,因此busy 将实际上始终是0如果声音正在播放。
  • 无论如何,如果您需要对音频播放进行细粒度控制,PlaySound() 并不是最好的选择。
  • @Remy Lebeau,是的,我错过了,因为代码是手动输入的。
  • 你能解释一下你的程序流程吗?看起来它在第一个 WM_LBUTTONDOWN 上开始播放 ding1.wav,然后在下一个 WM_LBUTTONDOWN 上,如果 ding1.wav 仍在播放,它将播放 ding2.wav,或者如果已经完成,则重复 ding1.wav

标签: winapi mingw win32gui playsound


【解决方案1】:

我建议阅读PlaySound 的文档。

据此,SND_NOWAIT 不受支持。如果另一个声音已经在播放,SND_NOSTOP 将阻止您播放声音,这违背了您的计划。此外,这些标志与按位 OR 运算符 | 组合,而不是逗号:

PlaySoundA(buf, NULL, SND_MEMORY | SND_ASYNC);

正如 cmets 中所指出的,您不需要线程来玩 SND_ASYNC

不要在问题中输入代码;从您的编辑器中复制/粘贴working 代码;你没有编译的那个。

以下是您可以使用的:

LRESULT CALLBACK WndProc(hwnd,msg,wparam,lparam)
{
  switch(msg) {
  case WM_LBUTTONDOWN:
    music();
    break;
  }
....

music() 在哪里:

void music()
{
  if(ding1.busy)
    ding2.play();
  else
    ding1.play();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多