Pages : 1
#1 Le 13/12/2007, à 20:56
- jokos
jouer son en c
Bonjour,
J'ai un problème en c pour lire un son ou une musique. La lecture doit s'effectuer de manière asynchrà´ne.
j'ai vu qu'il y avait moyen en utilisant la fonction
sndPlaySound("nom_du_fichier_wav",SND_ASYNC);
mais pour cela il faut importer
#include <mmsystem.h>
mais je n'arrive pas a l'installer sur ubuntu (pas dans les paquets)
J'ai également vu qu'il y avait moyen avec FMODEX, je pense que je l'ai installé correctement mais je ne suis pas certain non plus.
Avec cette méthode j'ai essayé
FMOD_SYSTEM *sys;
FMOD_SOUND *sound;
FMOD_CHANNEL *channel;
jusque là ca va.
Puis je fais
FMOD_System_Create(&sys);
FMOD_System_Init(sys, 1, FMOD_INIT_NORMAL, NULL);
et la j'obtient une erreur a la compilation
undefined reference to `FMOD_System_Create'
j'ai copié ce code d'un petit tutoriel mais je n'y arrive pas.
Dépité j'ai ensuite essayé en faisant un
system("vlc chemin_vers_son");
La ca marchait mais le problème est que le code est bloquant.
Bref je pense que vous avez compris mon problème.
Si quelqu'un peu m'éclairer je l'en remercie d'avance.
http://www.freetetris.be -- tetris en réseau (applet java)
Hors ligne
#2 Le 13/12/2007, à 21:38
- teto
Re : jouer son en c
Je n'ai jamais utilisé Fmodex ( seulement Fmod ) mais dans tous les cas:
undefined reference to `FMOD_System_Create'
signale que soit tu oublié un header ( *.h ) soit tu as oublié de linker FmodEx ( un fichier *.a ou *.lib je ne sais plus ca dépend du systeme ).
Si ca t'intéresse LouLou a écrit un article sympa sur developpez.com à propos d'OpenAl ( cf google ou exalead.fr )
La révolution est en marche.
Hors ligne
#3 Le 13/12/2007, à 22:23
- jokos
Re : jouer son en c
ok merci.
Si j'ai utiliser Fmodex et pas Fmod c est tout simplement que sur le site Fmod ils ne proposent pas ou plus Fmod.
Je vais essayer de trouver comment lier correctement Fmodex.
http://www.freetetris.be -- tetris en réseau (applet java)
Hors ligne
#4 Le 13/12/2007, à 23:14
- Link31
Re : jouer son en c
Regarde plutà´t du cà´té de OpenAL ou de SDL (Fmod, çapucestpaslibre).
Hors ligne
#5 Le 14/12/2007, à 00:36
- jokos
Re : jouer son en c
je ne connaissais pas openAl.
Je vais essayer de voir comment ca marche.
merci.
http://www.freetetris.be -- tetris en réseau (applet java)
Hors ligne
#6 Le 14/12/2007, à 01:31
- jokos
Re : jouer son en c
j'ai essayé par OpenAl.
lorque je fais
#include <AL/al.h>
#include <AL/alc.h>
ALCcontext * pContext = NULL; // Create a context
ALCdevice * pDevice = NULL; // Create a device
mon programme compile.
mais lorsque je fais
pDevice = alcOpenDevice (NULL); // Open the device
j'obtiens
undefined reference to `alcOpenDevice
bref encore le même problème, une question de lien surement comme avant mais je croyais que vu que c'est synaptic qui gère cela il n'y aurai pas de problème.
Pouvez vous me dire quoi faire?
merci.
Dernière modification par jokos (Le 14/12/2007, à 01:35)
http://www.freetetris.be -- tetris en réseau (applet java)
Hors ligne
#7 Le 14/12/2007, à 01:34
- Link31
Re : jouer son en c
Comme pour beaucoup de bibliothèques, il faut rajouter ça aux options de compilation :
`pkg-config openal --libs --cflags`
Hors ligne
#8 Le 14/12/2007, à 16:28
- jokos
Re : jouer son en c
ok merci j'ai rajouté l'option.
J'essaye de suivre le tutoriel http://loulou.developpez.com/tutoriels/ … miers-pas/
Mais celui si est en c++. D'o๠quelques petits problème d'adaptabilité.
j'arrive maintenant à faire:
ALCdevice* Device;
ALCcontext* Context;
// Ouverture du device
Device = alcOpenDevice(NULL);
if (!Device)
return;
// Création du contexte
Context = alcCreateContext(Device, NULL);
if (!Context)
return;
// Activation du contexte
if (!alcMakeContextCurrent(Context))
return;
j'ai du ensuite installer libsndfile pour charger un son.
Ensuite en c++ on doit faire ca
ALuint LoadSound(const std::string& Filename)
{
// Ouverture du fichier audio avec libsndfile
SF_INFO FileInfos;
SNDFILE* File = sf_open(Filename.c_str(), SFM_READ, &FileInfos);
if (!File)
return 0;
.....
j'ai un probleme a la 2eme ligne de la fonction car elle utilise un string qui n'existe pas en c.
J'aimerai savoir si il est possible de contourner cela, si oui comment.
Si vous connaissez un tutoriel openal pour le c ca m'interresse également.
merci.
Dernière modification par jokos (Le 14/12/2007, à 16:29)
http://www.freetetris.be -- tetris en réseau (applet java)
Hors ligne
#9 Le 14/12/2007, à 21:31
- robrob
Re : jouer son en c
c_str() retourne la chaine de caractère C classique (char*) correspondante au string
Hors ligne
#10 Le 15/12/2007, à 15:53
- jokos
Re : jouer son en c
merci maintenant ca marche avec le char*.
Mais j'ai un autre problème du au fait que par après je dois faire la Lecture des échantillons audio au format entier 16 bits signé. Pour celà je dois créer une structure de type Vector. J'essaye de trouver par quoi le remplacer mais je ne trouve pas.
std::vector<ALshort> Samples(NbSamples);
if (sf_read_short(File, &Samples[0], NbSamples) < NbSamples)
return 0;
merci pour votre aide
http://www.freetetris.be -- tetris en réseau (applet java)
Hors ligne
#11 Le 15/12/2007, à 16:17
- jokos
Re : jouer son en c
j'ai utilisé un
ALshort *Samples;
à la place, je suppose que c'est comme cela qu'il falait faire.
Maintenant j'arrive a faire compiler le bout de code adapté repris du tutoriel mais je n'ai toujours aucun son.
Je post ci-dessous le code utilisé (pas tres beau car il manque de tests mais logiquement il devrai fonctionner sans cela temporairement). Si quelqu'un ayant déja utilisé cette bibliothèque pouvait m'éclairer sur ce que j'ai fait de mal, cela m'aiderai énormément.
void InitOpenAL()
{
// Ouverture du device
Device = alcOpenDevice(NULL);
if (!Device)
return;
Context = alcCreateContext(Device, NULL);
if (!alcMakeContextCurrent(Context))
return;
}
void loadAndPlayMusic() {
SF_INFO FileInfos;
char* path = "chemin vers un .wav";
SNDFILE* File = sf_open(path, SFM_READ, &FileInfos);
ALsizei NbSamples = static_cast<ALsizei>(FileInfos.channels * FileInfos.frames);
ALsizei SampleRate = static_cast<ALsizei>(FileInfos.samplerate);
ALshort *Samples;
sf_read_short(File, Samples, NbSamples);
ALenum Format;
switch (FileInfos.channels)
{
case 1 : Format = AL_FORMAT_MONO16; break;
case 2 : Format = AL_FORMAT_STEREO16; break;
//default : return 0;
}
// Création du tampon OpenAL
ALuint Buffer;
alGenBuffers(1, &Buffer);
alBufferData(Buffer, Format, &Samples[0], NbSamples * sizeof(ALushort), SampleRate);
ALuint Source;
alGenSources(1, &Source);
// On attache le tampon contenant les échantillons audio à la source
alSourcei(Source, AL_BUFFER, Buffer);
alSourcePlay(Source);
ALint Status;
do
{
// Récupération et affichage de la position courante de lecture en secondes
ALfloat Seconds = 0.f;
alGetSourcef(Source, AL_SEC_OFFSET, &Seconds);
//std::cout << "\rLecture en cours... " << std::fixed << std::setprecision(2) << Seconds << " sec";
printf("lecture en cour\n");
// Récupération de l'état du son
alGetSourcei(Source, AL_SOURCE_STATE, &Status);
}
while (Status == AL_PLAYING);
}
Je passe bien dans la boucle de fin mais elle se termine apres 2-3 sec contre 1 min de durée normale. Et aucun son ne sort.
merci pour votre aide
http://www.freetetris.be -- tetris en réseau (applet java)
Hors ligne
#12 Le 15/12/2007, à 17:02
- toto2k
Re : jouer son en c
salut
je m'y connais pas en openAL mais il y a peut etre des infos interessantes sur cette page ,
#13 Le 15/12/2007, à 19:47
- robrob
Re : jouer son en c
merci maintenant ca marche avec le char*.
Mais j'ai un autre problème du au fait que par après je dois faire la Lecture des échantillons audio au format entier 16 bits signé. Pour celà je dois créer une structure de type Vector. J'essaye de trouver par quoi le remplacer mais je ne trouve pas.std::vector<ALshort> Samples(NbSamples); if (sf_read_short(File, &Samples[0], NbSamples) < NbSamples) return 0;
merci pour votre aide
Le template vector permet de créer des tableaux dynamiques. Ici le tableau n'est pas dynamique donc l'utilisation d'un tableau classique ne posera pas de problème (je dirai même que le code d'origine est une mauvaise utilisation des vecteurs):
ALshort* Samples=(ALshort*)malloc(NbSamples*sizeof(ALshort));
if (sf_read_short(File, Samples, NbSamples) < NbSamples)
return 0;
(ne pas oublier de détruire le tableau à la fin avec un free)
Hors ligne
#14 Le 15/12/2007, à 19:57
- robrob
Re : jouer son en c
Le static_cast c'est du C++ et plutà´t pour les classes (il me semble):
ALsizei NbSamples = static_cast<ALsizei>(FileInfos.channels * FileInfos.frames);
ALsizei SampleRate = static_cast<ALsizei>(FileInfos.samplerate);
En C, on fait plutà´t:
ALsizei NbSamples = (ALsizei)(FileInfos.channels * FileInfos.frames);
ALsizei SampleRate = (ALsizei)(FileInfos.samplerate);
Hors ligne
#15 Le 15/12/2007, à 20:06
- jokos
Re : jouer son en c
merci beaucoup ca marche maintenant.
Pour le moment la lecture est blocante, je ne peux donc pas exécuter d'autres instruction en même temps.
Dois je utiliser un thread ou y a t'il une autre fonction qui s'exécute dans un thread implicitement.
merci.
http://www.freetetris.be -- tetris en réseau (applet java)
Hors ligne
Pages : 1