Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5

Bug volume avec ALSA
#1

Bonjour à tous,

Je rencontre un problème aléatoire depuis quelques semaines, et je ne parviens pas à en venir à bout (que c'est fâcheux! ^^)

Déjà dans un premier temps voici le contexte:
  • OS: raspbian
  • Kernel 3.10.36+ #665
  • firmware mis à jour avec "rpi-update"
  • pulse-audio non installé, uniquement ALSA


J'ai développé un soft en C++ qui définit le volume global du système avec Alsa puis lance la lecture d'un flux audio avec VLC (après un fork).
Seulement, lorsque j'utilise alsa-lib pour définir le volume, je vois bien le volume varier (en ouvrant une seconde console en SSH), mais VLC se lance avec un volume sonore très élevé, et qui ne correspond absolument pas au volume affiché. En revanche si après quelques secondes je rappelle la fonction pour setter le volume, cette fois-ci le volume est correctement appliqué. Parfois, et de manière aléatoire, VLC démarre avec le bon volume. En rebootant, rebelotte le problème est de retour.

J'ai demandé sur le forum VLC, et on m'a immédiatement répondu que VLC ne pouvait pas prendre la main sur le volume global, et qu'il était donc hors de cause. J'ai par ailleurs testé avec plusieurs versions de VLC (dont une compilée manuellement) et j'ai rencontré le même comportement. Il m'a par ailleurs été suggéré que le problème devait venir de mon driver ALSA (j'ai regardé le code source (ou une partie) mais à vrai dire je ne sais pas trop quoi en faire).

Afin de rendre les choses plus simples, j'ai extrait de mon projet la partie problématique, qui permet de reproduire le problème.
Par la même occasion, ça en devient du C, car plus de classes.


Pour reproduire le problème sur une raspbian:

  1. installer les headers Alsa (et surement d'autres choses avec): sudo apt-get install libasound2-dev
  2. avoir VLC installé sur sa distrib (normalement c'est le cas par défaut, sinon "sudo apt-get install vlc")
  3. configurer ALSA pour que le son sorte sur le jack: sudo amixer cset numid=3 1 (1 étant la sortie jack)
  4. compiler mon code source (vous devez avoir les fichiers "test-alsa-vlc.c" et "makefile"). Dans le répetoire dans lequel vous avez mis ces 2 fichiers, un simple make
  5. ouvrir 2 sessions SSH distinctes pour voir évoluer le volume
  6. dans la première, taper "alsamixer" et mettre le volume à 100%. Garder alsamixer ouvert pour voir l'évolution
  7. dans la seconde lancer l'exécutable compilé juste avant. Pour ça tapez, ./ALSA_test

Voici ce qu'il se passe chez moi:
  1. le volume passe à 20% dans alsamixer (c'est ce qui est demandé au démarrage de mon exécutable)
  2. VLC démarre la lecture du flux audio (fun radio dans le cas présent) avec un volume très fort (le problème est ici!)
  3. Au bout d'une minute, le volume passe à 21% (il est sensé augmenté) et le son devient très bas (nous avons ici le volume correct!).

Si jamais le volume est très bas dès le début, essayez de rebooter et de relancer l'exécutable, et le problème devrait apparaitre (c'est ce qu'il se passe chez moi).

Voici ci dessous le code source simplifié test-alsa-vlc.c:

Code :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
#include <signal.h>
#include <pthread.h>
#include <thread>
#include <alsa/asoundlib.h>
#include <cstdint>

// Prototypes
int run_VLC();
void set_alsa_volume(long vol);


// Main function
int main(int argc, const char* argv[])
{
    // Set the initial volume
    set_alsa_volume(-3837); // 20% in alsamixer

    pid_t child_pid = -1;
    
    // Fork to run VLC in a child process
    if ( (child_pid=fork()) == -1) {
        perror("An error occured during fork");
        exit(EXIT_FAILURE);
    
    } else if ( child_pid == 0 ) { // Child process
        // Run VLC
        run_VLC();
    
    } else { // Parent process    
        sleep(60); // Wait for 1 minute
        
        // Set a volume level higher than the previous
        set_alsa_volume(-3706); // 21% in alsamixer
        
        sleep(60); // Wait for 1 minute
        
        // Kill VLC
        if (child_pid != -1) {
            kill(child_pid, SIGTERM);
        }
    }
    
    return EXIT_SUCCESS;
}


void set_alsa_volume(long vol)
{
    snd_mixer_t *m_handle;
    snd_mixer_elem_t* m_elem;
    
    // Open an empty mixer
    if (snd_mixer_open(&(m_handle), SND_MIXER_ELEM_SIMPLE) < 0) {
        printf("Error snd_mixer_open");
        return;
    }
    
    if (snd_mixer_attach(m_handle, "hw:0") < 0) {
        printf("Error snd_mixer_attach");
        return;
    }
    
    if (snd_mixer_selem_register(m_handle, NULL, NULL) < 0) {
        printf("Error snd_mixer_selem_register");
        return;
    }
    
    // Load the mixer elements
    if (snd_mixer_load(m_handle) < 0) {
        printf("Error snd_mixer_load");
        return;
    }
    
    snd_mixer_selem_id_t *simpleElemId;
    snd_mixer_selem_id_alloca(&simpleElemId);
    snd_mixer_selem_id_set_index(simpleElemId, 0);
    snd_mixer_selem_id_set_name(simpleElemId, "PCM");
    
    m_elem = snd_mixer_find_selem(m_handle, simpleElemId);
    if (m_elem == NULL) {
        printf("Error snd_mixer_find_selem");
        return;
    }
    
    // Set the volume
    if (snd_mixer_selem_set_playback_volume_all(m_elem, vol) == 0) {
        std::cout << "ALSA volume level set to " << vol << std::endl;
    }
}


int run_VLC()
{
    // Build the array of arguments
    char * arguments[4] = { "cvlc",
                            "-vvv", // Verbose mode
                            "http://streaming.radio.funradio.fr/fun-1-44-128",
                            NULL
                          };

    if ( execv("/usr/bin/cvlc", const_cast<char * const *>(arguments)) == -1 ) {
        // Should never be printed if execv() is properly executed
        perror("Error in execv() when trying to run VLC");
    }
    
    return EXIT_FAILURE;
}

Et le fichier makefile:

Code :
# Compiler to use for C++
CC=g++

CFLAGS=-std=c++0x

LIBRARY=-lasound

all: test-alsa-vlc.o
    $(CC) $(CFLAGS) $(LIBRARY) -o ALSA_test $^

test-alsa-vlc.o: test-alsa-vlc.c
    $(CC) $(CFLAGS) -c $< -o $@

Je vous mets également les différents posts que j'ai déjà rédigé en anglais (mais qui n'ont pas eu beaucoup de succès Sad) :
- http://raspberrypi.stackexchange.com/que...g-playback
- http://stackoverflow.com/questions/22734...g-alsa-lib

Je n'arrive pas à identifier l'origine du problème. Je pense que cela vient du driver ou de la libraire alsa, mais sans grande certitude.
Je m'en remets donc à vos conseils, pour ceux qui s'y connaissent en drivers, ou ont une idée.
Pouvez-vous SVP dans un premier temps me dire si vous rencontrez le même comportement sur vos PI?

Si vous avez un problème pour tester (ou même compiler) le code chez vous, n'hésitez pas à me le dire, j'ai peut être oublié de mentionner une étape (déjà pas mal bidouillé, je ne sais plus exactement ce que j'ai installé/configuré).

Merci d'avance à tous Smile
Répondre
#2

Salut,

Merci d'avoir très bien détaillé ton problème et avoir mis en place le moyen de le reproduire etc.. C'est très rare et appréciable.
Malheuresement, cela dépasse mes compétences ..

a tout hasard, l'histoire d'affiner dans la recherche:
est ce que le probème est similaire avec autre chose que VLC ? (histoire d'être sûr que c'est Alsa le pb)
est ce que tu es sûr que vlc ne démarre rien au démarrage, et donc de "précharge" pas un truc au moment ou c'est enccore à 100% (je ne vois pas pourquoi, mais un petit "ps" pour vérifier rapidement)
tu dis que tu met manuellement a 100% avant de lancer ton programme, si jamais tu mets manuellement a 10% .. qu'est ce qui se passe..? ( VLC prend 10% ou 100% apres avoir lancé to programme)
Répondre
#3

Merci pour ta réponse rapide, ça fait plaisir!

Pour te répondre dans l'ordre:
  • Oui le problème est similaire avec d'autres logiciels. J'ai par exemple essayé avec mpg123 avec un fichier MP3 lu en local (je viens de le refaire à l'instant pour confirmer!)
  • Je n'ai pas l'impression que VLC ne démarre quoi que ce soit au démarrage (en tout cas "ps -aux" n'indique rien de tel)
  • Lorsque je sette le volume manuellement à 10% avant de lancer mon programme => même problème (alsamixer indique 20%, et le son démarre très fort)

Effectivement ces points pouvaient manquer Wink

Merci
Répondre
#4

Bon..bahh je n'ai plus trop d'idée.. Tu m'as l'air bien plus calé que nous tous ici sur Alsa et le C. Tongue
C'est peut etre un bug a remonter aux developpeurs...

(Je n'ai pas de Rasp avec lequel tester sous la main ce WE)
Répondre
#5

Salut,
Je te remercie moi aussi pour avoir détaillé ton problème, c'est génial et ça change.
Pour ton problème je pense que c'est un problème de communication avec Alsa. Je pense que VLC ne va pas chercher au démarrage le volume et doit démarrer sur un reste de l'ancienne config. Ça doit venir, je pense, d'un fichier qui soit n'est pas modifié ou supprimé après la nouvelles consigne.
Ça fait longtemps que je n'ai pas joué avec alsa, je ne rappelle plus trop.
@+
Nicolas.

Projet en cours : Commande de projecteurs via un Raspberry
Mon blogTopic sur le forumDépôt GitHub
Répondre
#6

Salut,

Merci pour toutes ces remarques sympathiques Wink

En fait j'ai pensé que le problème venait de VLC aussi. Mais en essayant avec mpg123 j'ai eu exactement le même problème, donc VLC semble hors de cause. Par ailleurs le bug est aléatoire, parfois cela marche, puis après un redémarrage le bug réapparait...

J'ai ouvert ce matin un rapport de bug à cette adresse, on va voir ce que ça donne:
https://github.com/raspberrypi/linux/issues/570

Par contre si vous pouvez essayer de faire tourner le code chez vous, pour voir s'il est reproductible sur plusieurs PI, cela pourra donner plus de "poids" au bug que j'ai remonté sur le tracker.

Merci à tous,
Bon lundi de Paques
Répondre
#7

Salut,

On peux tester mercredi soir ensemble si tu veux ? Je suis pas dispo ce soir Sad.

On se cale sur skype, comme d'hab.
Répondre
#8

Bon, j'ai testé sur mon Rasp tout neuf avec Raspbian, et même constat Sad.
Répondre
#9

Bon, pour terminer ce post, il s'agissait d'un problème côté firmware :

https://github.com/raspberrypi/linux/iss...t-41503375

Fixé et commité, comme ils disent !
Répondre
#10

C'est marrant que personne n'ai signalé ça avant…

Projet en cours : Commande de projecteurs via un Raspberry
Mon blogTopic sur le forumDépôt GitHub
Répondre
#11

Ouais, pourtant je pense qu'Alsa est pas mal utilisé sur le Rasp...
Répondre


Atteindre :


Utilisateur(s) parcourant ce sujet : 1 visiteur(s)