<分区>
我是计算机科学专业的学生。我有一个最后学期的项目来开发一个图形和声音的短游戏。
<分区>
我是计算机科学专业的学生。我有一个最后学期的项目来开发一个图形和声音的短游戏。
最佳答案
首先,编写如下代码:
#include <Mmsystem.h>
#include <mciapi.h>
//these two headers are already included in the <Windows.h> header
#pragma comment(lib, "Winmm.lib")
打开*.mp3:
mciSendString("open \"*.mp3\" type mpegvideo alias mp3", NULL, 0, NULL);
播放*.mp3:
mciSendString("play mp3", NULL, 0, NULL);
播放并等待 *.mp3 播放完毕:
mciSendString("play mp3 wait", NULL, 0, NULL);
要重播(从头开始再次播放)*.mp3:
mciSendString("play mp3 from 0", NULL, 0, NULL);
重播并等待 *.mp3 播放完毕:
mciSendString("play mp3 from 0 wait", NULL, 0, NULL);
播放 *.mp3 并在每次结束时像循环一样重播:
mciSendString("play mp3 repeat", NULL, 0, NULL);
如果你想在*.mp3播放完毕后做一些事情,那么你需要通过WNDCLASSEX
结构RegisterClassEx
,CreateWindowEx
并在 while
循环中使用 GetMessage、TranslateMessage 和 DispatchMessage 函数处理消息并调用:
mciSendString("play mp3 notify", NULL, 0, hwnd); //hwnd is an handle to the window returned from CreateWindowEx. If this doesn't work, then replace the hwnd with MAKELONG(hwnd, 0).
在窗口过程中,添加case MM_MCINOTIFY:
里面的代码会在mp3播放完毕后执行。
但是如果您编写控制台应用程序并且您不处理windows,那么您可以CreateThread
通过在 dwCreationFlags
参数中指定 CREATE_SUSPENDED
标志处于挂起状态,并将返回值保存在 static
变量中并随意调用它。例如,我称之为 mp3。这个static
变量的类型当然是HANDLE
。
这是此线程的 lpStartAddress
的 ThreadProc
:
DWORD WINAPI MP3Proc(_In_ LPVOID lpParameter) //lpParameter can be a pointer to a structure that store data that you cannot access outside of this function. You can prepare this structure before `CreateThread` and give it's address in the `lpParameter`
{
Data *data = (Data*)lpParameter; //If you call this structure Data, but you can call it whatever you want.
while (true)
{
mciSendString("play mp3 from 0 wait", NULL, 0, NULL);
//Do here what you want to do when the mp3 playback is over
SuspendThread(GetCurrentThread()); //or the handle of this thread that you keep in a static variable instead
}
}
您现在要做的就是每次要重播您的 mp3 时 ResumeThread(mp3);
,每次播放结束时都会发生一些事情。
您可以#define play_my_mp3 ResumeThread(mp3);
使您的代码更具可读性。
当然,如果您想播放 mp3 文件,您可以删除 while (true)
、SuspendThread
和 from 0 代码仅一次,结束后随心所欲。
如果您只删除SuspendThread
调用,那么声音将一遍又一遍地播放,并在结束时执行某些操作。这相当于:
mciSendString("play mp3 repeat notify", NULL, 0, hwnd); //or MAKELONG(hwnd, 0) instead
在 Windows 中。
要在中间暂停 *.mp3:
mciSendString("pause mp3", NULL, 0, NULL);
并恢复它:
mciSendString("resume mp3", NULL, 0, NULL);
中途停止:
mciSendString("stop mp3", NULL, 0, NULL);
请注意,您不能恢复已停止的声音,只能暂停,但您可以通过执行 play 命令重播它。 播放完 *.mp3 后,请不要忘记:
mciSendString("close mp3", NULL, 0, NULL);
所有这些操作也适用于(处理)wave 文件,但是对于 wave 文件,您可以使用“waveaudio”而不是“mpegvideo”。 您也可以直接播放它们而无需打开它们:
PlaySound("*.wav", GetModuleHandle(NULL), SND_FILENAME);
如果您不想指定模块句柄:
sndPlaySound("*.wav", SND_FILENAME);
如果不想等到播放结束:
PlaySound("*.wav", GetModuleHandle(NULL), SND_FILENAME | SND_ASYNC);
//or
sndPlaySound("*.wav", SND_FILENAME | SND_ASYNC);
反复播放波形文件:
PlaySound("*.wav", GetModuleHandle(NULL), SND_FILENAME | SND_ASYNC | SND_LOOP);
//or
sndPlaySound("*.wav", SND_FILENAME | SND_ASYNC | SND_LOOP);
请注意,您必须同时指定 SND_ASYNC
和 SND_LOOP
标志,因为您永远不会等到重复无数次的声音结束!
您还可以使用 fread
函数fopen
wave 文件并将其所有字节复制到缓冲区(巨大/巨大(非常大)的字节数组)和然后:
PlaySound(buffer, GetModuleHandle(NULL), SND_MEMORY);
//or
PlaySound(buffer, GetModuleHandle(NULL), SND_MEMORY | SND_ASYNC);
//or
PlaySound(buffer, GetModuleHandle(NULL), SND_MEMORY | SND_ASYNC | SND_LOOP);
//or
sndPlaySound(buffer, SND_MEMORY);
//or
sndPlaySound(buffer, SND_MEMORY | SND_ASYNC);
//or
sndPlaySound(buffer, SND_MEMORY | SND_ASYNC | SND_LOOP);
OpenFile
或 CreateFile
或 CreateFile2
以及 ReadFile
或 ReadFileEx
函数可以用来代替 fopen
和 fread
函数。
希望这完全完美地回答了您的问题。
关于c++ - 如何在 C++ 程序中播放或打开 *.mp3 或 *.wav 声音文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22253074/