我是计算机科学专业的学生。我有一个最后一个学期的项目,开发一个带有声音的图形短小游戏。如何在C++程序中播放或打开* .mp3或* .wav声音文件?
回答
使用库来(a)读取声音文件和(b)播放它们。也许(我建议你自己在你的业余时间一些点尝试两种,但是......)
(* nix中):
Windows:DirectX。
我会使用FMOD为您的游戏做到这一点。它能够播放任何主要用于声音的文件,并且在C++中实现起来非常简单。一起使用FMOD和Dir3ect X可以很强大并且不那么困难。如果你对Singleton类很熟悉,我会在你的win 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
这不是真的与op的问题有关,但你能解释为什么你有单独的关闭方法,而不是依靠析构函数? – jaho
,因为使用尽可能多的组件作为音响系统应该可以处理声音系统的所有对象,而不是在析构函数中,因为析构函数会摧毁声音管理器,但没有声音类创建的对象,只有它自己的班级。 – Josh
那么你可以把你放入'shutdown()'方法的代码放入析构函数中。这就是析构函数的目的,释放一个对象所拥有的所有资源。我经常看到这种两步破坏式的设计,但永远无法理解它背后的推理。为什么不使用C++提供的默认设施?除此之外,您始终可以使用智能指针,而不必担心显式释放资源。我只是看不到单独的shutdown()函数的好处。 – jaho
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();
通过使用预编译的二进制文件为我工作 –
首先,写以下代码:
#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
结构,CreateWindowEx
和处理它与消息需要RegisterClassEx
在的GetMessage,的TranslateMessage和在DispatchMessage在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播放完成时,将会执行那里的代码。
但如果要编制控制台应用程序,你不窗户应对,那么你就可以在CreateThread
通过在dwCreationFlags
参数指定CREATE_SUSPENDED
标志暂停状态,并保持返回值的static
变量并随意调用它。例如,我把它叫做mp3。这个static
变量的类型当然是HANDLE
。
这里是ThreadProc
该线程的lpStartAddress
:
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
}
}
所有你现在要做的就是ResumeThread(mp3);
要重播的MP3和事情会发生在每次完成时间每一次。
您可以#define play_my_mp3 ResumeThread(mp3);
使您的代码更具可读性。
当然你也可以去掉while (true)
,SuspendThread
和从0代码,如果你想播放MP3文件只一次,做任何你想要的,当它结束了。
如果你只有只有删除SuspendThread
电话,然后声音会一遍又一遍地播放,并做任何事情,当它结束。这相当于:
在windows中。
要暂停* .MP3在中间:
mciSendString("pause mp3", NULL, 0, NULL);
,并恢复它:
mciSendString("stop mp3", NULL, 0, NULL);
请注意,您无法恢复:
mciSendString("resume 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_ASYNC
和SND_LOOP
标志,因为您永远不会等到发出无数次重复的声音结束!
您也可以fopen
波形文件,它的所有字节复制到缓冲区中(巨大/庞大(非常大)的字节数组)与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);
无论OpenFile
或CreateFile
或CreateFile2
和ReadFile
或ReadFileEx
函数可以用来代替fopen
和fread
函数。
希望这完全回答你的问题。
哇,我不能相信这个答案到目前为止还没有被注意到!对于像我这样想要在C++代码中实现简单的.mp3声音实现的人来说,这是一个很好且详细的资源! – Sossenbinder
尝试用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;
}
- 1. 如何使用C库播放音乐(MP3)或.Wav文件?
- 2. 如何在C++中播放.WAV声音
- 3. 在后台播放mp3或wav音乐文件
- 4. MediaElement不播放mp3或wav
- 5. 在iOS应用程序中播放多个声音(mp3,wav等)
- 6. 如何触发在Mac上播放WAV或MP3音频文件的Python?
- 7. .wav文件不播放任何声音
- 8. 如何在Flixel中播放wav声音?
- 9. Get Tempo(BPM),Rythm,使用Java/C#从MP3或Wav或任何数字音乐文件播放音调信息?
- 10. 播放WAV文件时单击声音
- 11. 记录音频文件为MP3或WAV
- 12. VB播放随机声音wav文件
- 13. 如何让程序在背景中播放音乐或声音C#
- 14. 在WindowForms应用程序中播放两个(或更多).wav声音
- 15. iPhone应用程序 - WAV声音文件不播放
- 16. 如何在C#中播放声音?
- 17. 录音并上传为WAV或MP3播放服务器
- 18. IPhone,音频MP3或M4A等音频文件播放没有声音
- 19. 的Visual C++或C播放声音
- 20. 如何在打开应用程序时自动播放声音?
- 21. 我如何获得.wav声音播放?
- 22. Python播放mp3/wav文件音频(Pygame调音台)
- 23. 在C#中播放的mp3不使用MediaPlayer或XACT
- 24. 播放和暂停Windows上的.wav或.mp3文件
- 25. 如何使用VBA播放波形文件或声音文件
- 26. 播放声音从WAV文件在C开始偏移一个时间#
- 27. 如何在C++中播放mp3文件?
- 28. 如何在C#中播放mp3文件?
- 29. 如何在播放中播放音频mp3文件
- 30. 如何让C程序播放声音文件?
[WAV信息(https://ccrma.stanford.edu/courses/422/projects/WaveFormat/) – Michael
为了得到一个有价值的和有益的反应,而不是在网上搜索评论,您需要表明你已经尝试过。也就是说,显示一些试图加载.mp3文件的示例代码。你绑定使用任何现有的库(但失败)。这些更有帮助。 – wmorrison365
p.s.你可以看看这些库如何做到这一点:http://en.cppreference.com/w/cpp/links/libs – wmorrison365