如何在c ++程序中播放或打开*.mp3或*.wav声音文件?



我是计算机科学专业的学生。我有一个最后一个学期的项目,要开发一个图形和声音的短游戏。

首先,编写以下代码:

#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结构RegisterClassExCreateWindowEx并使用GetMessageTranslateMessageDispatchMessage函数在while循环中处理它的消息并调用:

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,则可以通过在dwCreationFlags参数中指定CREATE_SUSPENDED标志来CreateThread挂起状态,并将返回值保留在static变量中,并根据需要调用它。例如,我称之为mp3。当然,这个static变量的类型是HANDLE的。

以下是此线程lpStartAddressThreadProc

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);使代码更具可读性。

当然,您可以删除while (true)SuspendThread从0代码,如果您只想播放一次mp3文件并在结束时做任何您想做的事情。

如果您删除SuspendThread呼叫,那么声音将一遍又一遍地播放,并在结束时执行某些操作。这相当于:

mciSendString("play mp3 repeat notify", NULL, 0, hwnd); //or MAKELONG(hwnd, 0) instead

在窗口中。

要暂停中间的 *.mp3:

mciSendString("pause mp3", NULL, 0, NULL);

并恢复它:

mciSendString("resume mp3", NULL, 0, NULL);

要在中间停止它:

mciSendString("stop mp3", NULL, 0, NULL);

请注意,您无法恢复已停止而只能暂停的声音,但您可以通过执行播放命令来重播它。 当你玩完这个*.mp3时,不要忘记:

mciSendString("close mp3", NULL, 0, NULL);

所有这些操作也适用于(处理)波形文件,但对于波形文件,您可以使用"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_ASYNCSND_LOOP标志,因为您永远不会等到重复无数次的声音结束!

您也可以fopenwave 文件并使用fread函数将其所有字节复制到缓冲区(巨大/巨大(非常大)字节数组),然后:

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);

可以使用OpenFileCreateFileCreateFile2,也可以使用ReadFileReadFileEx函数代替fopenfread函数。

希望这完全回答了您的问题。

http://sfml-dev.org/documentation/2.0/classsf_1_1Music.php

SFML没有像另一个人建议的那样支持mp3。 我一直在使用 Audacity 并将我所有的音乐制作成 ogg,并将我所有的音效都保留为 wav。

加载和播放 wav 很简单(粗略的例子):

http://www.sfml-dev.org/tutorials/2.0/audio-sounds.php

#include <SFML/Audio.hpp>
...
sf::SoundBuffer buffer;
if (!buffer.loadFromFile("sound.wav")){
return -1;
}
sf::Sound sound;
sound.setBuffer(buffer);
sound.play();

流式传输 ogg 音乐文件也很简单:

#include <SFML/Audio.hpp>
...
sf::Music music;
if (!music.openFromFile("music.ogg"))
return -1; // error
music.play();

如果你想播放*.mp3或*.wav文件,我认为最简单的方法是使用SFML。

尝试在 VC++ 中使用简单的 c++ 代码。

#include <windows.h>
#include <iostream>
#pragma comment(lib, "winmm.lib")
int main(int argc, char* argv[])
{
std::cout<<"Sound playing... enjoy....!!!";
PlaySound("C:\temp\sound_test.wav", NULL, SND_FILENAME); //SND_FILENAME or SND_LOOP
return 0;
}

我会使用 FMOD 为您的游戏执行此操作。它能够播放任何文件,主要用于声音,并且在C++中实现起来非常简单。同时使用 FMOD 和 Dir3ect X 可能很强大,而且并不那么困难。如果您熟悉 Singleton 类,我会在您的 win main cpp 中创建声音管理器的 Singleton 类,然后在加载或播放新音乐或音效时可以访问它。 下面是一个音频管理器示例

#pragma once
#ifndef H_AUDIOMANAGER
#define H_AUDIOMANAGER
#include <string>
#include <Windows.h>
#include "fmod.h"
#include "fmod.hpp"
#include "fmod_codec.h"
#include "fmod_dsp.h"
#include "fmod_errors.h"
#include "fmod_memoryinfo.h"
#include "fmod_output.h"
class AudioManager
{
public:
// Destructor
~AudioManager(void);
void Initialize(void);  // Initialize sound components
void Shutdown(void);    // Shutdown sound components
// Singleton instance manip methods
static AudioManager* GetInstance(void);
static void DestroyInstance(void);
// Accessors
FMOD::System* GetSystem(void)
{return soundSystem;}
// Sound playing
void Play(FMOD::Sound* sound);  // Play a sound/music with default channel
void PlaySFX(FMOD::Sound* sound);   // Play a sound effect with custom channel
void PlayBGM(FMOD::Sound* sound);   // Play background music with custom channel
// Volume adjustment methods
void SetBGMVolume(float volume);
void SetSFXVolume(float volume);
private:
static AudioManager* instance;  // Singleton instance
AudioManager(void);  // Constructor
FMOD::System* soundSystem;  // Sound system object
FMOD_RESULT result;
FMOD::Channel* bgmChannel;  // Channel for background music
static const int numSfxChannels = 4;
FMOD::Channel* sfxChannels[numSfxChannels]; // Channel for sound effects
};
#endif

使用库 (a) 读取声音文件和 (b) 播放它们。(我建议在业余时间的某个时候自己尝试两者,但是...

也许(*尼克斯):

  • http://www.underbit.com/products/mad/
  • https://www.xiph.org/ao/
  • http://libsdl.org/

Windows:DirectX。

相关内容

  • 没有找到相关文章

最新更新