Je suis étudiant en informatique. J'ai un projet de semestre final pour développer un petit jeu graphique avec le son.
Tout d'abord, écrivez le code suivant:
#include <Mmsystem.h>
#include <mciapi.h>
//these two headers are already included in the <Windows.h> header
#pragma comment(lib, "Winmm.lib")
Pour ouvrir * .mp3:
mciSendString("open \"*.mp3\" type mpegvideo alias mp3", NULL, 0, NULL);
Pour jouer au * .mp3:
mciSendString("play mp3", NULL, 0, NULL);
Pour jouer et attendre la fin de la lecture du * .mp3:
mciSendString("play mp3 wait", NULL, 0, NULL);
Pour rejouer (relire depuis le début) le * .mp3:
mciSendString("play mp3 from 0", NULL, 0, NULL);
Pour rejouer et attendre la fin de la lecture du * .mp3:
mciSendString("play mp3 from 0 wait", NULL, 0, NULL);
Pour jouer au * .mp3 et le rejouer chaque fois qu'il se termine comme une boucle:
mciSendString("play mp3 repeat", NULL, 0, NULL);
Si vous voulez faire quelque chose quand le * .mp3 a fini de jouer, alors vous devez RegisterClassEx
par la structure WNDCLASSEX
, CreateWindowEx
et traiter ses messages avec le GetMessage, TranslateMessage et DispatchMessage fonctions dans une boucle while
et appelez:
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).
Dans la procédure de la fenêtre, ajoutez le case MM_MCINOTIFY:
Le code qu'il contient sera exécuté lorsque la lecture du mp3 sera terminée.
Mais si vous programmez une Console Application et que vous ne traitez pas avec windows, alors vous pouvez CreateThread
en état de suspension par en spécifiant l'indicateur CREATE_SUSPENDED
dans le paramètre dwCreationFlags
et conservez la valeur de retour dans une variable static
et appelez-la comme vous voulez. Par exemple, je l'appelle mp3. Le type de cette variable static
est bien entendu HANDLE
.
Voici le ThreadProc
pour le lpStartAddress
de ce fil:
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
}
}
Tout ce que vous avez à faire maintenant est de ResumeThread(mp3);
chaque fois que vous voulez rejouer votre mp3 et quelque chose se produira à chaque fois.
Vous pouvez #define play_my_mp3 ResumeThread(mp3);
pour rendre votre code plus lisible.
Bien sûr, vous pouvez supprimer les codes while (true)
, SuspendThread
et à partir de, si vous souhaitez lire votre fichier mp3 uniquement ne fois et faites ce que vous voulez quand ce sera fini.
Si vous seulement supprimez l'appel SuspendThread
, alors le son sera reproduit encore et encore et fera quelque chose à chaque fois qu'il sera terminé. Cela équivaut à:
mciSendString("play mp3 repeat notify", NULL, 0, hwnd); //or MAKELONG(hwnd, 0) instead
dans les fenêtres.
Pour mettre en pause le * .mp3 au milieu:
mciSendString("pause mp3", NULL, 0, NULL);
et pour le reprendre:
mciSendString("resume mp3", NULL, 0, NULL);
Pour l'arrêter au milieu:
mciSendString("stop mp3", NULL, 0, NULL);
Notez que vous ne pouvez pas reprendre un son qui a été arrêté, mais seulement en pause, mais vous pouvez le rejouer en exécutant la commande play. Lorsque vous avez fini de jouer à ce * .mp3, n'oubliez pas de:
mciSendString("close mp3", NULL, 0, NULL);
Toutes ces actions s'appliquent également aux fichiers wave (travailler avec), mais avec les fichiers wave, vous pouvez utiliser "waveaudio" au lieu de "mpegvideo". Vous pouvez également les jouer directement sans les ouvrir:
PlaySound("*.wav", GetModuleHandle(NULL), SND_FILENAME);
Si vous ne souhaitez pas spécifier de descripteur pour un module:
sndPlaySound("*.wav", SND_FILENAME);
Si vous ne voulez pas attendre la fin de la lecture:
PlaySound("*.wav", GetModuleHandle(NULL), SND_FILENAME | SND_ASYNC);
//or
sndPlaySound("*.wav", SND_FILENAME | SND_ASYNC);
Pour lire le fichier wave encore et encore:
PlaySound("*.wav", GetModuleHandle(NULL), SND_FILENAME | SND_ASYNC | SND_LOOP);
//or
sndPlaySound("*.wav", SND_FILENAME | SND_ASYNC | SND_LOOP);
Notez que vous devez spécifier les drapeaux SND_ASYNC
Et SND_LOOP
, Car vous n'attendez jamais qu'un son, qui se répète d'innombrables fois, soit terminé!
Vous pouvez également fopen
le fichier wave et copier tous ses octets dans un tampon (un énorme/énorme (très grand) tableau d'octets) avec la fonction fread
puis:
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);
Soit OpenFile
ou CreateFile
ou CreateFile2
Et soit ReadFile
ou ReadFileEx
fonctions peuvent être utilisées à la place de fopen
et fread
fonctions.
J'espère que cela répond parfaitement à votre question.
http://sfml-dev.org/documentation/2.0/classsf_1_1Music.php
SFML n'a pas de support mp3 comme un autre l'a suggéré. Ce que je fais toujours, c'est utiliser Audacity et transformer toute ma musique en ogg, et laisser tous mes effets sonores en wav.
Charger et jouer un wav est simple (exemple grossier):
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();
La diffusion d'un fichier musical ogg est également simple:
#include <SFML/Audio.hpp>
...
sf::Music music;
if (!music.openFromFile("music.ogg"))
return -1; // error
music.play();
Si vous voulez lire le fichier * .mp3 ou * .wav, je pense que la façon la plus simple serait d'utiliser SFML .
Essayez avec du code c ++ simple dans 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;
}
J'utiliserais FMOD pour le faire pour votre jeu. Il a la capacité de lire n'importe quel fichier principalement pour les sons et est assez simple à implémenter en C++. utiliser FMOD et Dir3ect X ensemble peut être puissant et pas si difficile. Si vous êtes familier avec les classes Singleton, je créerais une classe Singleton d'un gestionnaire de son dans votre cpp principal gagnant et y aurais accès à chaque fois pour charger ou jouer de la nouvelle musique ou des effets sonores. voici un exemple de gestionnaire audio
#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
Utilisez une bibliothèque pour (a) lire le (s) fichier (s) audio et (b) les lire. (Je recommanderais d'essayer les deux vous-même à un moment donné de votre temps libre, mais ...)
Peut-être (* nix):
Windows: DirectX.