IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Calcul scientifique Python Discussion :

obtenir le signal d'un fichier audio pour scipy


Sujet :

Calcul scientifique Python

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 51
    Points : 34
    Points
    34
    Par défaut obtenir le signal d'un fichier audio pour scipy
    Bonjour,

    Pour tracer de jolies fft avec scipy, j'ai besoin de récupérer le signal sonore d'un fichier audio (mp3,wav...). Après quelques recherches, j'ai vu qu'il était possible d'utiliser pymedia pour acquérir le son puis le jouer, mais je n'ai pas trouvé comment obtenir le signal sous forme d'un tableau ou d'une liste afin de passer le boulot ensuite à scipy.

    Quelqu'un peut-il m'aider ?

    Merci,
    Sébastien

  2. #2
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 74
    Points : 88
    Points
    88
    Par défaut
    Tu peux peut-être simplement utiliser le module wave [1] et la méthode Wave_read.readframes(n)

    Wave_read.readframes(n)
    Reads and returns at most n frames of audio, as a string of bytes.
    [1] http://docs.python.org/library/wave.html

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 51
    Points : 34
    Points
    34
    Par défaut
    merci, ça à l'air de marcher ...


    mais (sinon ce serait trop simple), j'ai des petits soucis:
    j'ouvre mon fichier, pas de problèmes : son=wave.open("test.wav",'r')
    Je récupère la string de bit : chaine = son.readframes(100)

    Et là, je sais pas si je fais ce qu'il faut, pour avoir une liste de valeurs, je fais:
    liste = [ord(c)-128 for c in chaine]

    J'ai mis le "-128", car j'ai remarqué que sinon les valeurs allaient de 0 à 255.

    Après, j'affiche la liste sur un graphe grâce à un plot (from pylab, mais ca on s'en tape), et le graphe que j'obtiens ne correspond pas du tout au graphe que me donne audacity.

    Autre curiosité, je lui demande 100 frames, et la liste que j'ai est de 200 éléments.

    Merci de ton aide

  4. #4
    Membre expérimenté Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Points : 1 728
    Points
    1 728
    Par défaut
    Autre curiosité, je lui demande 100 frames, et la liste que j'ai est de 200 éléments.
    Au hasard, ton fichier son est en stéreo?
    "Etre conscient de la difficulté permet de l'éviter.."
    Lao-Tseu.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 51
    Points : 34
    Points
    34
    Par défaut
    Non il est bien en mono.

    Mais j'ai un peu avancé. Je me suis dit "Et si j'arretai de faire le kéké à vouloir prendre n'importe quel son, si je prenais un son sinusoidal" ... et bizarement, on voit plus de choses.

    Je me suis rendu compte que le signal qui m'interessait était en fait sur les cases 'impaires', donc pour avoir la courbe qui m'interesse, je dois faire :
    liste[1::2]
    Mais, là encore un petit détail, la conversion caractère -> int ne se fait pas comme il faut, j'ai du appliquer : if x >128 : return x-255 ; else return x à ma liste. (en gros le bit de poid fort n'est pas interprété comme un bit de signe). Y a t il une solution à ça ?

    Mais dans ce cas là, à quoi correspond le cases paires ? Je l'ai ploté, et ca donne un truc comme du bruit (aucune période, truc qui parait relativement aléatoire), bruit que je n'ai absolument pas dans mon fichier : ce fichier contient un son formé d'une sinusoïde pure

  6. #6
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 74
    Points : 88
    Points
    88
    Par défaut
    À mon avis, c'est un peu plus compliqué que ça.

    Quand tu utilises readframes(n) ça te renvoie une chaîne d'octets pour n frames.
    Cette chaîne est, je pense, de taille nombre de frames * nombre de canaux * format d'échantillonnage (en octets).
    Par exemple, un fichier avec 10 frames en stéréo échantillonné sur 16 bits renverra une chaîne de taille 10 * 2 * 2 = 40.

    D'après [1] :
    8-bit samples are stored as unsigned bytes, ranging from 0 to 255. 16-bit samples are stored as 2's-complement signed integers, ranging from -32768 to 32767.
    Il faut donc extraire les données de cette chaîne. Pour les fichiers wav échantillonnés sur 8 bits, il faut utiliser un unsigned char (0 à 255), et pour les wav échantillonnés sur 16 bits, il faut utiliser un signed short (-32768 à 32767). Tu peux utiliser struct pour faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import wave, struct
     
    def readwave(filename):
    	wav = wave.open(filename,'rb')
    	(nchannels, sampwidth, framerate, nframes, comptype, compname) = wav.getparams()
    	frames = wav.readframes(nframes)
            # http://docs.python.org/library/struct.html
            if sampwidth == 1:
              # 8 bit : unsigned char
              data = struct.unpack('%sB' % (nframes * nchannels), frames)
            elif sampwidth == 2:
              # 16 bits : signed short
    	  data = struct.unpack('%sh' % (nframes * nchannels), frames)
            return data
    Ensuite, il reste à découper les données restantes selon le nombre de canaux. Si c'est du mono, il n'y a rien à faire. Si c'est du stéréo, il faut lire un entier sur deux pour chaque piste :
    [gauche, droit, gauche, droit, gauche, droit...]

    Enfin, il ya peut-être également une histoire de little-endian et big-endian.

    [1] http://ccrma.stanford.edu/courses/42...ts/WaveFormat/

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 51
    Points : 34
    Points
    34
    Par défaut
    Merci beaucoup, ça marche très bien ! Je connaissais pas ce module struct de python, très utile pourtant !

    Par contre, je ne comprend pas pourquoi tu prends des unsigned char pour les 8 bits (pas de fichier 8 bits sous la main pour tester). Si on prend unsigned, ne va t on pas avoir un signal mal interprété ? (un peu comme j'avais en fait?)

  8. #8
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 74
    Points : 88
    Points
    88
    Par défaut
    J'ai simplement suivi ce que dit la doc :
    8-bit samples are stored as unsigned bytes, ranging from 0 to 255
    À tester pour voir si ça fonctionne bien avec des fichiers échantillonnés sur 8 bits.

  9. #9
    Membre régulier
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 74
    Points : 88
    Points
    88
    Par défaut
    Pour info dans Scipy 0.7 (qui n'est pas encore sorti), il y aura une méthode io.wavfile.read [1] peut-être plus simple à utiliser.

    [1] http://docs.scipy.org/doc/scipy/refe...file.read.html

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 51
    Points : 34
    Points
    34
    Par défaut
    oui mais j'en ai besoin maintenant ... et cette méthode marche, donc je ne vais pas attendre la sortie de scipy 0.7 :p

    Merci du tuyau !

    Seb

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Récupérer le signal d'un fichier audio
    Par fxaguessy dans le forum FMOD
    Réponses: 0
    Dernier message: 02/11/2008, 20h01
  2. Créer logiciel pour lire des fichiers audios (mp3 et compagnie)
    Par valebl dans le forum Langages de programmation
    Réponses: 5
    Dernier message: 30/05/2007, 11h12
  3. Fichier audio : Obtenir la durée
    Par d-Rek dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 30/01/2007, 17h08
  4. fonction pour lire les fichier audio
    Par tarek007 dans le forum Multimédia
    Réponses: 1
    Dernier message: 11/05/2005, 16h28
  5. obtenir la durée d'un fichier audio
    Par cgodefrw dans le forum DirectX
    Réponses: 2
    Dernier message: 07/10/2004, 16h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo