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

Python Discussion :

problème callback PyAudio


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2022
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2022
    Messages : 11
    Par défaut problème callback PyAudio
    Salut!
    Pour un projet concernant la réduction active du bruit, j'ai besoin d'écrire un programme python capable d'enregistrer via un micro (branché sur un port USB de mon pc), de lire ce fichier qui se créé en même temps pour déphaser (ici inverser les valeurs enregistrées par le micro) le signal et l'envoyer sur une autre enceinte (un autre port de mon pc). Tout ça en même temps oui... En me renseignant, j'ai cru comprendre que la fonction Callback de Pyaudio pourrait me permettre de faire un truc du genre.https://people.csail.mit.edu/hubert/pyaudio/docs/

    puis en suivant d'autres forums j'ai construit mon programme d'écriture et lecture en même temps (avec en amont un programme qui lit un audio sur une enceinte sur un port précis de mon pc, puis un programme qui enregistre par mon micro le son sorti de la 1ere enceinte, ça c'est réglé) ci-dessous:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    import pyaudio
    import wave
    import sounddevice as sd
    import soundfile as sf
    import scipy.io.wavfile as sc
    import numpy as np
    from matplotlib.pyplot import *
    import time
     
     
    Son1 = 'audio1.wav'
     
     
    def lecture_audio1(file):
        data, fs = sf.read(file)
        sd.play(data, fs, device=6)
     
    def enregistrement_micro():
        CHUNK = 1024 
        FORMAT = pyaudio.paInt16            
        CHANNELS = 1                         
        RATE = 44100                       
        RECORD_SECONDS = 60                
        microSave = "enregistrement_micro.wav"
     
        p = pyaudio.PyAudio()
     
        stream = p.open(format=FORMAT,
                        channels=CHANNELS,
                        rate=RATE,
                        input=True,
                        input_device_index= 1,
                        frames_per_buffer=CHUNK) #buffer
     
        print("...recording...")
     
        frames = []
     
        for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
            data = stream.read(CHUNK)
            frames.append(data)                             
     
     
        wf = wave.open(microSave, 'wb')
        wf.setnchannels(CHANNELS)                           
        wf.setsampwidth(p.get_sample_size(FORMAT))
        wf.setframerate(RATE)
        wf.writeframes(b''.join(frames))
        wf.close()
     
     
    #lecture enregitrement micro en même temps que son écriture (sur port jack)
     
    #audio_micro[0] donne la fréquence d'échantillonage, audio_micro[1] est un tableau numpy contenant les valeurs
     
    audio_micro = sc.read("enregistrement_micro.wav")
    fulldata = np.array([])
     
    def callback_function():
        # instantiate PyAudio 
        p = pyaudio.PyAudio()
     
        # appel de cette fonction lorsque de nouvelles données audio (enregistrées) sont disponibles
     
        def callback():
            global fulldata
            valeurs_son_dephase = audio_micro[1]*(-1)
            sc.write("enregistrement_déphasé.wav", audio_micro[0], valeurs_son_dephase)
            audio_dephase= sc.read("enregistrement_déphasé.wav")
            fulldata = np.append(fulldata,audio_dephase[1]) #saves filtered data in an array
            return (audio_dephase, pyaudio.paContinue)
     
        stream = p.open(format=pyaudio.paInt16,
                        channels=1,
                        rate=44100,
                        output=True,
                        output_device_index= 7,
                        stream_callback=callback)
     
        # start the stream
        stream.start_stream()
     
        while stream.is_active:
            time.sleep(0.1)
            stream.stop_stream()
     
        stream.close()
        p.terminate()
     
     
    #LANCEMENT
     
    lecture_audio1(Son1)
    enregistrement_micro()
    callback_function()
    inspiré de : https://stackoverflow.com/questions/...-callback-mode
    Sauf que, là est le problème: sans parler de callback, en utilisant le module "scipy.io.wavfile" pour inverser les valeurs enregistrées par le micro dans un autre fichier, ça marche, pas de problème. Mais je n'arrive pas à savoir si ce module est compatible avec le callback. Peut-être ai-je mal compris comment fonctionne le callback et le stream. Si quelqu'un veut m'éclairer je veux bien ! En testant mon programme: déjà l'audio "déphasé" n'est pas joué sur la 2ème enceinte, mais en plus en tracant les signaux "enregistrement_micro.wav" et "enregistrement_déphasé.wav" j'obtiens ceci:

    Nom : callback.PNG
Affichages : 106
Taille : 71,8 Ko

    Il n'y a pas de déphasage parfait. Je pense que c'est dû au temps de procédure de la fonction d'inversion des valeurs. C'est bien ca? (PS: Je réglerai la question d'amplitude différente après...) Je ne sais pas où modifier pour laisser le temps, si c'est bien ça, à l'inversion de valeurs d'être effectuée proprement.
    Voilà ! J'espere que quelqu'un pourra m'aider
    merci d'avance.

  2. #2
    Membre éprouvé
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 130
    Par défaut python pas ouf pour ça
    Bonjour,

    Le problème que tu exposes me semble difficilement solvable avec avec python.

    Si j'ai bien compris ton problème, tu souhaites faire de la réduction de bruit active en un point précis de l’espace.
    Si tu veux annuler le son capté par le microphone, et que ce son provient par exemple de la voie humaine soit environ 5 kHz pour les fréquences haute du spectre. Il faut un temps de réponse environ 8 fois plus court que la plus petite des périodes. Cela impose un temps de réponse inférieur à (1/5e3)/8 soit 0.025 ms.

    Or avec la librairie sounddevice de python et en optimisant au mieux les paramètres sur un pc rapide (linux core i5) je n'ai pas réussi a avoir un temps de réponse inférieur à 60 ms. J'ai eu un TP de 20 heures dessus donc j'ai vraiment eu le temps de tester toutes les combinaisons. Par défaut, le temps de réponse était d'environ 600 ms, voici les paramètres optimaux trouvés:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    with sd.Stream(
            callback=callback,
            samplerate=44100,
            channels=(1, 1),
            dtype=np.int16,
            blocksize=1024,
        ):
    En compilant et en écrivant le code directement en c++ avec la librairie rtaudio, nous avons réussi à atteindre un temps de réponse d'environ 35 ms.

    De toute façon dans un os classique, la carte son et le callback accumulent des valeurs (souvent 1024) avant de les envoyer au haut parleur. A 44100 Hz cela impose une latence incompréhensible de 23 ms. Le problème que tu soumet n'est donc pas solvable avec un ordinateur.

    Comme le traitement est très simple, la solution qui me semble la plus directe consisterait à faire un amplificateur inverseur avec de l’électronique analogique.

Discussions similaires

  1. Django et Ajax : problème callback
    Par vicax dans le forum Django
    Réponses: 3
    Dernier message: 17/10/2014, 19h42
  2. Problème callback débutant
    Par MiniJulie dans le forum R
    Réponses: 3
    Dernier message: 06/04/2011, 15h46
  3. Problème de callback
    Par ssr.sonia dans le forum C
    Réponses: 2
    Dernier message: 14/09/2007, 17h50
  4. Réponses: 7
    Dernier message: 03/03/2007, 19h15
  5. problème avec un appel de fonction de callback de C++ vers C#
    Par surfurax dans le forum Framework .NET
    Réponses: 1
    Dernier message: 29/01/2007, 10h09

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