How to play or open a sound file * .mp3 or * .wav in a C ++ program?

I am a computer science student. I have a final semester project to develop a short game in graphics along with sound.

+6
source share
6 answers

First of all, write the following code:

#include <Mmsystem.h> #include <mciapi.h> //these two headers are already included in the <Windows.h> header #pragma comment(lib, "Winmm.lib") 

Open * .mp3:

 mciSendString("open \"*.mp3\" type mpegvideo alias mp3", NULL, 0, NULL); 

To play * .mp3:

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

To play and wait for the * .mp3 to finish playing:

 mciSendString("play mp3 wait", NULL, 0, NULL); 

To play (repeat playback from the beginning) * .mp3:

 mciSendString("play mp3 from 0", NULL, 0, NULL); 

To play and wait for the * .mp3 to finish playing:

 mciSendString("play mp3 from 0 wait", NULL, 0, NULL); 

To play * .mp3 and play it every time it ends as a loop:

 mciSendString("play mp3 repeat", NULL, 0, NULL); 

If you want to do something when * .mp3 has finished playing, you need RegisterClassEx on the structure of WNDCLASSEX , CreateWindowEx and process its messages using GetMessage TranslateMessage and DispatchMessage in a while and call:

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

In the window procedure, add case MM_MCINOTIFY: The code will be executed there when mp3 finishes playing.

But , if you are programming the Console application and you are not dealing with windows , you can CreateThread in a paused state by specifying the CREATE_SUSPENDED flag in the dwCreationFlags parameter and save the return value in the static variable and call it dwCreationFlags you want. For example, I call it mp3. The type of this variable is static , of course, HANDLE .

Here is ThreadProc for lpStartAddress this thread:

 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 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 } } 

All you have to do is ResumeThread(mp3); every time you want to play your mp3, and something will happen every time it ends.

You can #define play_my_mp3 ResumeThread(mp3); make the code more readable.

Of course, you can remove the while (true) , SuspendThread and 0 codes if you want to play only the mp3 file once and do whatever you want when it is over.

If you just delete the SuspendThread call, then the sound will play again and again and do something when it ends. This is equivalent to:

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

in the windows.

To pause * .mp3 in the middle:

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

and renew it:

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

To stop it in the middle:

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

Please note that you cannot resume a sound that was stopped, but only paused, but you can play it by running the play command. When you finish playing this * .mp3, don't forget:

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

All these actions also apply to (working with) wave files, but with wave files you can use "waveaudio" instead of "mpegvideo". You can also just play them directly without opening them:

 PlaySound("*.wav", GetModuleHandle(NULL), SND_FILENAME); 

If you do not want to specify a module descriptor:

 sndPlaySound("*.wav", SND_FILENAME); 

If you do not want to wait for the end of playback:

 PlaySound("*.wav", GetModuleHandle(NULL), SND_FILENAME | SND_ASYNC); //or sndPlaySound("*.wav", SND_FILENAME | SND_ASYNC); 

Repeat wave file playback:

 PlaySound("*.wav", GetModuleHandle(NULL), SND_FILENAME | SND_ASYNC | SND_LOOP); //or sndPlaySound("*.wav", SND_FILENAME | SND_ASYNC | SND_LOOP); 

Please note that you must specify the flags SND_ASYNC and SND_LOOP , because you will never wait until the sound that is repeated countless times ends!

You can also fopen create a wave file and copy all its bytes to the buffer (huge / huge (very large) byte array) using the fread function, and then:

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

Either OpenFile , or CreateFile or CreateFile2 , and the ReadFile or ReadFileEx can be used instead of the fopen and fread functions.

Hope this fully answers your question.

+22
source

If you want to play the * .mp3 or * .wav file, I think the easiest way is to use SFML .

+5
source

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

SFML does not have mp3 support, as another suggested. What I always do is use Audacity and make all my music in ogg and leave all my sound effects as wav.

Downloading and playing wav is simple (rough example):

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

Streaming an ogg music file is also simple:

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

I would use FMOD to do this for your game. It has the ability to play any file mainly for sounds and quite simple to implement in C ++. Using FMOD and Dir3ect X together can be powerful and not so complex. If you are familiar with the Singleton classes, I would create a Singleton class for the sound manager on your main Windows OS, and then have access to it whenever I load or play new music or sound effects. here is an example of an audio manager

  #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 
+2
source

Try with simple C ++ code in VC ++.

 #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; } 
+2
source

Use the library to (a) read audio files and (b) play them. (I would recommend trying yourself at some point in your free time, but ...)

Maybe (* nix):

Windows: DirectX.

+1
source

All Articles