2016-03-25 3 views
1

Bonjour Je travaille avec pyaudio pour créer une application qui enregistre et reproduit l'audio en temps réel en ajoutant un filtre passe-bas au signal audio. Lorsque je tente d'exécuter ce code cette erreur apparaît ci-dessous:Pyaudio: Erreur de lecture: 4

Pyaudio: Erreur de lecture: 4

from pyaudio import PyAudio, paContinue, paFloat32 
from time import sleep 
from numpy import array, random, arange, float32, float64, zeros 
import sounddevice as sd 

fs   = 44100 # Hz 
threshold  = 0.8  # absolute gain 
delay   = 40  # samples 
signal_length = 1  # second 
release_coeff = 0.5555 # release time factor 
attack_coeff = 0.5  # attack time factor 
dtype   = float32 # default data type 
block_length = 1024 # samples 


class Limiter: 
    def __init__(self, attack_coeff, release_coeff, delay, dtype=float32): 
    self.delay_index = 0 
    self.envelope = 0 
    self.gain = 1 
    self.delay = delay 
    self.delay_line = zeros(delay, dtype=dtype) 
    self.release_coeff = release_coeff 
    self.attack_coeff = attack_coeff 

def limit(self, signal, threshold): 
    for i in arange(len(signal)): 
     self.delay_line[self.delay_index] = signal[i] 
     self.delay_index = (self.delay_index + 1) % self.delay 

     # calculate an envelope of the signal 
     self.envelope *= self.release_coeff 
     self.envelope = max(abs(signal[i]), self.envelope) 

     # have self.gain go towards a desired limiter gain 
     if self.envelope > threshold: 
      target_gain = (1+threshold-self.envelope) 
     else: 
      target_gain = 1.0 
     self.gain = (self.gain*self.attack_coeff + 
         target_gain*(1-self.attack_coeff)) 

     # limit the delayed signal 
     signal[i] = self.delay_line[self.delay_index] * self.gain 




    print "Recording Audio" 
    signal = sd.rec(signal_length * fs, samplerate=fs, channels=1, dtype=dtype) 
    sd.wait() 
    print "Audio recording complete , Play Audio" 





original_signal = array(signal, copy=True, dtype=dtype) 
limiter = Limiter(attack_coeff, release_coeff, delay, dtype) 

def callback(in_data, frame_count, time_info, flag): 
    if flag: 
     print("Playback Error: %i" % flag) 
     played_frames = callback.counter 
     callback.counter += frame_count 
     limiter.limit(signal[played_frames:callback.counter], threshold) 
    return signal[played_frames:callback.counter], paContinue 

callback.counter = 0 

pa = PyAudio() 

stream = pa.open(format = paFloat32, 
       channels = 1, 
       rate = fs, 
       frames_per_buffer = block_length, 
       output = True, 
       stream_callback = callback) 

while stream.is_active(): 
    sleep(0.1) 

stream.close() 
pa.terminate() 
+1

Donnez-nous un retraçage complet –

+0

Bonjour. Je suis nouveau sur python où dois-je mettre le code pour récupérer la trace et quel code de retour dois-je ajouter. Je vous remercie. –

+0

La traceback est l'erreur complète en rouge habituellement vu dans le shell. La dernière ligne de la traceback devrait être l'erreur: 'Pyaudio: Erreur de lecture: 4' –

Répondre

1

Vous ne devriez pas mélanger PyAudio et sounddevice! Quoi qu'il en soit, les fonctions sounddevice.rec() et sounddevice.wait() ne fonctionneront pas correctement si elles sont appelées dans une fonction de rappel (car elles utilisent leur propre "flux" avec leur propre fonction de rappel en interne).

+0

OK. Alors, quelle pourrait être la solution? Le code est essentiellement censé enregistrer un micro et lire l'audio avec un filtre passe-bas pour créer un effet de picotement. –

+0

Ce sont deux questions distinctes. Si vous affichez le code de votre filtre passe-bas, je peux vous montrer comment l'utiliser avec 'sounddevice'. Fondamentalement, vous pouvez simplement utiliser l'exemple ["wire"] (http://python-sounddevice.readthedocs.org/en/latest/#callback-streams), appliquer votre filtre passe-bas à 'indata' et assigner le résultat à 'outdata [:]'. Vous devez seulement faire attention à ce que l'état du filtre soit maintenu entre les appels de rappel consécutifs. – Matthias

+0

Bonjour Matthias. J'ai donné le code ci-dessus pour ajouter un limiteur similaire à un filtre passe-bas. D'une certaine manière créer un effet de mubbling sur la personne parle sur le micro. Si vous avez un code qui fait quelque chose de similaire s'il vous plaît partager. Merci. –