Forum Programmation.python Python : Monitorer de l'audio

Posté par (page perso) . Licence CC by-sa
Tags :
1
5
août
2013

J'ai besoin de, pendant que je playe un son, afficher un vu-metre. enfin, je me charge de fabriquer le vu-metre hein (genre un slider en GTK, ou mieux en HTML5) mais avant j'ai besoin de données numériques.

Pour player le son, tout marche, plein de libs (j'ai essayé pygame et pygst, et d'autres, ça marche, ça play et même pardois ça recorde) et même des programmes externes genre sox/play via subprocess. En fait peu importe la lib, moi je voudrais lire la sortie ALSA.

Voici où j'en suis de mes recherches :

Tout ce que je suis parvenu à afficher so far, c'est le volume :(

import pygame,time
pygame.init()

print "Mixer settings", pygame.mixer.get_init()
print "Mixer channels", pygame.mixer.get_num_channels()
pygame.mixer.music.set_volume(1.0)
pygame.mixer.music.load('/home/px/gare_du_nord-catchlak.wav')
print "Play"
pygame.mixer.music.play()
pygame.mixer.music.set_volume(0.5)

while pygame.mixer.music.get_busy():
    print "Pos", pygame.mixer.music.get_pos()
    print "Vol", pygame.mixer.music.get_volume()
    time.sleep(1)

Le truc qui m'intéresse spécifiquement c'est de player un sample, de voir jusqu'où monte le vu-metre, pour après en player un autre et avoir une notion d'amplitude de l'un par rapport à l'autre.
Après j'aimerais bien (mais là c'est overkill) une idée - visuelle - des fréquences d'un fichier par rapport à un autre…

Bon voilà, merci de votre attention :)

  • # quebecois ?

    Posté par . Évalué à 2.

    non parce que le nombre de mot anglais dans tes phrases pourtant francaises est important.

    sinon

    http://blog.yjl.im/2011/02/capture-device-volume-meter.html (input only, moi c'est la sortie que je veux)

    pourtant c'est exactement ce qu'il fait,
    il "ecoute" ce qui est enregistré

    I wanted to show the spectrum of current output. […]
    I found this nice page about how to use Capture device to get system output.

    en gros il monte un systeme de boucle,
    il enregistre la sortie du player, et fait le vumetre sur l'enregistrement.

    • [^] # Re: quebecois ?

      Posté par (page perso) . Évalué à 0.

      http://blog.yjl.im/2011/02/capture-device-volume-meter.html (input only, moi c'est la sortie que je veux)

      pourtant c'est exactement ce qu'il fait,
      il "ecoute" ce qui est enregistré

      Oui, enregistré, c'est l' entrée, la dernière fois que j'ai vérifié dans le manuel.

      Ce n'est pas ça que je veux faire, c'est pour ça que j'ai linké (oups, lié, pardon) le poste (mais merci de me le relire, c'est sympa) et si tu avais lu les commentaires (je parle même pas de faire tourner le script) tu verrais que pour faire ça, il faut re-diriger la sortie dans l'entrée, par exemple en utilisant pulse. Et ce n'est pas (mais du tout, hein ?) ce que je veux faire, comme je croyais l'avoir expliqué clairement dans un post dont je vois pas bien pourquoi il est moinssé, mais je suis habitué à tout ici.

      Et désolé pour l'anglais, excuse, c'est vrai que play/record, c'est rare comme formulation.

      Donc je reprends. Je souhaite mesurer ce qui sort de la machine (bus PCM pour ALSA only, ou sortie Pulse s'il en est) en python. Je précise que je produis ce qui sort, puisque je joue un son (avec pygame, mais comme je l'ai dit, peu importe).

      Quelqu'un a déjà fait ça ?

      • [^] # Re: quebecois ?

        Posté par . Évalué à 1. Dernière modification le 05/08/13 à 10:50.

        oui c'est expliqué que tu veux avoir un visuel sur ce qui "sort" de la carte

        Emetteur du son --> carte son -> haut parleur

        sauf que pour avoir le visuel sur ce qui sort, il n'y a que 2 solutions :

        Solution A :
        se brancher entre l'emeteur et la sortie (comme tu le ferais avec entre ton micro et ton ampli en mettant une table de mixage entre les deux)

        Emetteur du son -> logiciel intermediaire -> carte son -> haut parleur
        

        Solution B :
        à defaut de pouvoir s'intercaler entre les deux, c'est la solution que tu avais trouvé dans un lien qui consiste à analyser ce qui est emis par la sortie, en l'enregistrant via une boucle.

        Emetteur -> carte son -> haut parleur
                               |
        Enregistreur <-carte son
        
  • # carte son

    Posté par (page perso) . Évalué à 1.

    Il te faut surtout une carte son avec monitoring hard comme une maudio par exemple.

    Ensuite dans ton programme tu scrute les line in et tu te met sur le line monitoring et tu aura tout ce qui se passe sur la carte son.

  • # Pulseaudio

    Posté par . Évalué à 0.

    J'ai eu le même problème il y a peu et m'en suis sorti avec pulseaudio : tu peux enregistrer depuis les "monitor".

    • [^] # Re: Pulseaudio

      Posté par (page perso) . Évalué à 1.

      Intéressant, tu as un bout de code pour illustrer ça ?

      • [^] # Re: Pulseaudio

        Posté par . Évalué à 1.

        Dans un premier module pasimple.py :

        from ctypes import *
        from pulseaudio import lib_pulseaudio
        
        lib = cdll.LoadLibrary('libpulse-simple.so.0')
        
        # pa_simple_new()
        pa_simple_new = lib.pa_simple_new
        pa_simple_new.restype = c_void_p
        pa_simple_new.argstypes = [
            c_char_p,           # Server name or NULL for default
            c_char_p,           # Description for the client
            lib_pulseaudio.pa_stream_direction,             # Stream direction, record or playback
            c_char_p,           # Sink or source name, NULL for default
            c_char_p,           # Stream description
        
            POINTER(lib_pulseaudio.pa_sample_spec), # Sample type to use
            POINTER(lib_pulseaudio.pa_channel_map),         # Channel map to use or NULL for default
            POINTER(lib_pulseaudio.pa_buffer_attr),         # Buffer attributes or NULL for default
            POINTER(c_int),         # A pointer to the error code for when the routine returns NULL
        ]
        
        # pa_simple_read()
        pa_simple_read = lib.pa_simple_read
        pa_simple_read.restype = c_int
        pa_simple_read.argstypes = [ c_void_p, c_char_p, c_size_t, POINTER(c_int) ]

        Puis, pour l'utiliser :

        from pulseaudio import lib_pulseaudio
        import pasimple
        import ctypes
        
        ss = lib_pulseaudio.pa_sample_spec(lib_pulseaudio.PA_SAMPLE_S16LE, 44100, 1)
        
        buf = ctypes.create_string_buffer(4096)
        
        s = pasimple.pa_simple_new(
                None, # server name NULL for default
                "avrvu", # program name
                2, # record
                "alsa_output.pci-0000_00_14.2.analog-stereo.monitor", #device
                "vu-record", 
                ctypes.byref(ss),
                None,
                None,
                None
        )
        
        while True:
            ret = pasimple.pa_simple_read(s, ctypes.byref(buf), 4096, None)
            #print ret
            data = buf.raw
            # your processing here

        Avec ces bouts de code, j'ai pu faire un vu-mètre. Pour trouver le bon "monitor" sur ta machine il faudra te tourner vers les utilitaires de pulseaudio ; je n'ai plus la commande sous la main.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.