Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 03/01/2010, à 20: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, à 21:30)

Hors ligne

#2 Le 03/01/2010, à 23: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, à 13: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, à 17: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, à 19: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, à 19:58

grim7reaper

Re : OpenAL recherche Tutoriel enregistrement linux[resolu]

J'ai aussi le kernel 2.6.32 mais par contre je suis sous Archlinux smile

Hors ligne

#7 Le 04/01/2010, à 20: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, à 20:55)

Hors ligne

#8 Le 16/01/2010, à 20: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, à 20: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 wink.

Hors ligne