#1 Le 03/01/2010, à 21:42
- zebulon25
OpenAL recherche Tutoriel enregistrement linux[resolu]
Bonjour,
Je recherche un tutoriel sur openAL d'un enregistrement sous linux, j'ai trouvé un exemple windows sur developpez.com, la compilation se passe bien mais au lancement rien ne se passe.
Voici l'exemple :
////////////////////////////////////////////////////////////
/// En-têtes
////////////////////////////////////////////////////////////
#include <AL/al.h>
#include <AL/alc.h>
#include <sndfile.h>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <string.h>
#include <vector>
// Les différents devices audio utilisés
ALCdevice* Device = NULL;
ALCdevice* CaptureDevice = NULL;
////////////////////////////////////////////////////////////
/// Récupère la liste des noms des devices de capture disponibles
///
/// \param Devices : Tableau de chaînes à remplir avec les noms des devices
///
////////////////////////////////////////////////////////////
void GetCaptureDevices(std::vector<std::string>& Devices)
{
// Vidage de la liste
Devices.clear();
// Récupération des devices disponibles
const ALCchar* DeviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
if (DeviceList)
{
// Extraction des devices contenus dans la chaîne renvoyée
while (strlen(DeviceList) > 0)
{
Devices.push_back(DeviceList);
DeviceList += strlen(DeviceList) + 1;
}
}
else
{
std::cerr << "Impossible de récupérer la liste des devices de capture" << std::endl;
}
}
////////////////////////////////////////////////////////////
/// Initialise OpenAL (ouvre un device et crée un contexte audio)
///
/// \param DeviceName : Nom du device à ouvrir (NULL pour le device par défaut)
///
/// \return True si tout s'est bien passé, false en cas d'erreur
///
////////////////////////////////////////////////////////////
bool InitOpenAL(const char* DeviceName = NULL)
{
// Ouverture du device
Device = alcOpenDevice(DeviceName);
if (!Device)
{
std::cerr << "Impossible d'ouvrir le device par défaut" << std::endl;
return false;
}
// Création du contexte
ALCcontext* Context = alcCreateContext(Device, NULL);
if (!Context)
{
std::cerr << "Impossible de créer un contexte audio" << std::endl;
return false;
}
// Activation du contexte
if (!alcMakeContextCurrent(Context))
{
std::cerr << "Impossible d'activer le contexte audio" << std::endl;
return false;
}
return true;
}
////////////////////////////////////////////////////////////
/// Initialise la capture audio
///
/// \param DeviceName : Nom du device de capture à ouvrir (NULL pour le device par défaut)
///
/// \return True si tout s'est bien passé, false en cas d'erreur
///
////////////////////////////////////////////////////////////
bool InitCapture(const char* DeviceName = NULL)
{
// On commence par vérifier que la capture audio est supportée
if (alcIsExtensionPresent(Device, "ALC_EXT_CAPTURE") == AL_FALSE)
{
std::cerr << "La capture audio n'est pas supportée par votre systeme" << std::endl;
return false;
}
// Ouverture du device
CaptureDevice = alcCaptureOpenDevice(DeviceName, 44100, AL_FORMAT_MONO16, 44100);
if (!CaptureDevice)
{
std::cerr << "Impossible d'ouvrir le device de capture" << std::endl;
return false;
}
return true;
}
////////////////////////////////////////////////////////////
/// Sauvegarde un tableau d'échantillons dans un fichier audio
///
/// \param Filename : Nom du fichier audio à charger
/// \param Samples : Tableau d'échantillons
///
////////////////////////////////////////////////////////////
void SaveSound(const std::string& Filename, const std::vector<ALshort>& Samples)
{
// On renseigne les paramètres du fichier à créer
SF_INFO FileInfos;
FileInfos.channels = 1;
FileInfos.samplerate = 44100;
FileInfos.format = SF_FORMAT_PCM_16 | SF_FORMAT_WAV;
// On ouvre le fichier en écriture
SNDFILE* File = sf_open(Filename.c_str(), SFM_WRITE, &FileInfos);
if (!File)
{
std::cerr << "Impossible de créer le fichier audio" << std::endl;
return;
}
// Ecriture des échantillons audio
sf_write_short(File, &Samples[0], Samples.size());
// Fermeture du fichier
sf_close(File);
}
////////////////////////////////////////////////////////////
/// Ferme proprement le device de capture
///
////////////////////////////////////////////////////////////
void ShutdownCapture()
{
// Fermeture du device de capture
alcCaptureCloseDevice(CaptureDevice);
}
////////////////////////////////////////////////////////////
/// Ferme proprement OpenAL
///
////////////////////////////////////////////////////////////
void ShutdownOpenAL()
{
// Récupération du contexte
ALCcontext* Context = alcGetCurrentContext();
// Désactivation du contexte
alcMakeContextCurrent(NULL);
// Destruction du contexte
alcDestroyContext(Context);
// Fermeture du device
alcCloseDevice(Device);
}
////////////////////////////////////////////////////////////
/// Point d'entrée du programme
///
/// \return Code d'erreur de l'application
///
////////////////////////////////////////////////////////////
int main()
{
// Initialisation d'OpenAL avec le device par défaut
if (!InitOpenAL(NULL))
return 0;
// Récupération des devices de capture disponibles
std::vector<std::string> Devices;
GetCaptureDevices(Devices);
// On affiche la liste à l'utilisateur
std::cout << "Veuillez choisir un device pour la capture :" << std::endl << std::endl;
for (std::size_t i = 0; i < Devices.size(); ++i)
std::cout << "[" << i << "] " << Devices[i] << std::endl;
// Et on le laisse choisir
int Choice;
std::cin >> Choice;
// Initialisation de la capture
if (!InitCapture(Devices[Choice].c_str()))
return 0;
// Lancement de la capture
alcCaptureStart(CaptureDevice);
// On va stocker les échantillons capturés dans un tableau d'entiers signés 16 bits
std::vector<ALshort> Samples;
// On attend que l'utilisateur appuie sur entrée...
std::cout << "Appuyez sur entree pour commencer 5 secondes de capture..." << std::endl;
std::cin.ignore(10000, '\n');
std::cin.ignore(10000, '\n');
// ...Et c'est parti pour 5 secondes de capture
time_t Start = time(NULL);
while (time(NULL) - Start < 5)
{
// On récupère le nombre d'échantillons disponibles
ALCint SamplesAvailable;
alcGetIntegerv(CaptureDevice, ALC_CAPTURE_SAMPLES, 1, &SamplesAvailable);
// On lit les échantillons et on les ajoute au tableau
if (SamplesAvailable > 0)
{
std::size_t Start = Samples.size();
Samples.resize(Start + SamplesAvailable);
alcCaptureSamples(CaptureDevice, &Samples[Start], SamplesAvailable);
}
}
// On stoppe la capture
alcCaptureStop(CaptureDevice);
// On n'oublie pas les éventuels échantillons qu'il reste à récupérer
ALCint SamplesAvailable;
alcGetIntegerv(CaptureDevice, ALC_CAPTURE_SAMPLES, 1, &SamplesAvailable);
if (SamplesAvailable > 0)
{
std::size_t Start = Samples.size();
Samples.resize(Start + SamplesAvailable);
alcCaptureSamples(CaptureDevice, &Samples[Start], SamplesAvailable);
}
// On sauvegarde les échantillons capturés dans un fichier
SaveSound("capture.wav", Samples);
// Fermeture de la capture
ShutdownCapture();
// Fermeture d'OpenAL
ShutdownOpenAL();
// On attend que l'utilisateur appuie sur entrée...
std::cout << "Appuyez sur entree pour terminer..." << std::endl;
std::cin.ignore(10000, '\n');
return 1;
}
je choisis 'pulseaudio capture' et le logiciel 'freeze'.
Soit une âme charitable réussi à 'transcrire' ce bout de code pour linux, soit me montrer le chemin d'un petit tuto pour l'enregistrement sous linux.
merci.
PS : et je viens de voir que openal n'est pas compatible avec pulseaudio, une solution?
Dernière modification par zebulon25 (Le 18/01/2010, à 22:30)
Hors ligne
#2 Le 04/01/2010, à 00:49
- grim7reaper
Re : OpenAL recherche Tutoriel enregistrement linux[resolu]
Pas de problème apparent pour moi. Après compilation, l'exécution me donne ceci
Veuillez choisir un device pour la capture :
[0] ALSA Capture on default
[1] ALSA Capture on HDA Intel [ALC880 Analog] (hw:0,0)
[2] ALSA Capture on HDA Intel [ALC880 Analog] (hw:0,2)
[3] OSS Capture
0
Appuyez sur entree pour commencer 5 secondes de capture...
Appuyez sur entree pour terminer...
Et au final j'obtiens bien un fichier "capture.wav" avec mon enregistrement.
Tu n'as pas d'autres choix à part "pulseaudio" ?
Hors ligne
#3 Le 04/01/2010, à 14:18
- zebulon25
Re : OpenAL recherche Tutoriel enregistrement linux[resolu]
Je suis sous karmic avec un kernel 2.6.32.
En fait au démarrage de l'appli j'ai un 4 choix avec
[0] ALSA Capture on default
[1] ALSA Capture on HDA Intel (hw:0,0)
[2] OSS Capture
[3] Pulseaudio capture
Si je choisis 0 à 2 j'ai un message d'erreur me disant que le périphérique ne peut pas être atteint.
SI je choisis le choix Pulseaudio alors le programme reste comme figé, je n'ai pas de création de fichier .wav et il faut faire control+C pour sortir du programme.
J'ai installé pavucontrol et le programme n'apparait jamais dans 'enregistrement'.
J'ai une partition sous jaunty je ferai un essais ce soir.
Hors ligne
#4 Le 04/01/2010, à 18:48
- grim7reaper
Re : OpenAL recherche Tutoriel enregistrement linux[resolu]
Hum, alors le problème vient peut-être de pulseaudio alors (je ne l'ai pas chez moi ce qui expliquerais que je n'ai pas de problème avec ALSA et toi si).
Hors ligne
#5 Le 04/01/2010, à 20:52
- zebulon25
Re : OpenAL recherche Tutoriel enregistrement linux[resolu]
Je vais tester sur jaunty en supprimant pulseaudio, j'ai essayé sous jaunty avec pulseaudio et cela a donné le même résultat négatif.
Peux-tu me donner ta configuration STP?
Hors ligne
#6 Le 04/01/2010, à 20:58
- grim7reaper
Re : OpenAL recherche Tutoriel enregistrement linux[resolu]
J'ai aussi le kernel 2.6.32 mais par contre je suis sous Archlinux
Hors ligne
#7 Le 04/01/2010, à 21:55
- zebulon25
Re : OpenAL recherche Tutoriel enregistrement linux[resolu]
OK, bon après plusieurs essais cela fonctionne(bizarrement et aléatoirement) mais openal est en concurrence avec pulseaudio, donc point de salut, je vais utiliser alsa, cela fonctionne, j'aurais aimé utilisé une bibliothèque existante sous linux et windows, tant pis merci.
Dernière modification par zebulon25 (Le 04/01/2010, à 21:55)
Hors ligne
#8 Le 16/01/2010, à 21:09
- zebulon25
Re : OpenAL recherche Tutoriel enregistrement linux[resolu]
Bonne nouvelle j'ai essayé lucid alpha et pulseaudio fonctionne parfaitement avec openal!!! il n'y a plus de problème d'enregistrement, même la biliothèque sfml fonctionne et est présente dans les dépôt, bref lucid me semble être une très bone version d'ubuntu qui pointe son nez...
Hors ligne
#9 Le 16/01/2010, à 21:36
- grim7reaper
Re : OpenAL recherche Tutoriel enregistrement linux[resolu]
Très bonne nouvelle ça. Tu n'as plus qu'à passé le sujet en [résolu] maintenant .
Hors ligne