title: Denoising audio playback with pyaudio
body: <p>I'm writing a vocoder in Python for Raspberry Pi, something to change voice to be unrecognizable. I record audio and do a playback in real time with callback function - it works. Now I need to denoise the input, represented as a Numpy array (NOT .wav file like most tutorials and posts on SO do!). I've tried using several audio denoisers, but in particular this one: <a href="https://pypi.org/project/noisereduce/" rel="nofollow noreferrer">https://pypi.org/project/noisereduce/</a> (tutorial: <a href="https://timsainburg.com/noise-reduction-python.html" rel="nofollow noreferrer">https://timsainburg.com/noise-reduction-python.html</a>, source: <a href="https://github.com/timsainb/noisereduce" rel="nofollow noreferrer">https://github.com/timsainb/noisereduce</a>). It does not work for me.<br>
  My main.py:</p>
  
  <pre><code>from copy import copy
  import numpy as np
  import pyaudio as pa
  import time
  import noisereduce as nr
  
  p = pa.PyAudio()
  
  FORMAT = pa.paFloat32
  NP_FORMAT = np.float32
  CHANNELS = 2
  CHUNK = 1024
  RATE = int(p.get_default_input_device_info()['defaultSampleRate'])
  NOISE_SAMPLE = None
  
  
  # function for manipulating input data
  def callback(in_data, frame_count, time_info, flag):
      data = copy(np.frombuffer(in_data))  # copy, since original is read-only
  
      # here everything is ok for first time
      # print("X")
      out_data = nr.reduce_noise(audio_clip=data, noise_clip=NOISE_SAMPLE)
      # print("Y")
      # I get here only once
  
      return out_data, pa.paContinue
  
  
  def get_noise():
      audio = pa.PyAudio()
      stream = audio.open(format=FORMAT, channels=CHANNELS,
                          rate=RATE, input=True,
                          frames_per_buffer=CHUNK)
  
      frames = []
      RECORD_SECONDS = 1
      for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
          data = stream.read(CHUNK)
          frames.append(np.frombuffer(data))
  
      # stop Recording
      stream.stop_stream()
      stream.close()
      audio.terminate()
  
      return np.array(frames, dtype=NP_FORMAT).flatten()
  
  
  def main():
      global NOISE_SAMPLE
      NOISE_SAMPLE = get_noise()
  
      stream = p.open(format=FORMAT,
                      rate=RATE,
                      channels=CHANNELS,
                      input=True,
                      output=True,
                      frames_per_buffer=CHUNK,
                      stream_callback=callback)
  
      stream.start_stream()
  
      # main input loop
      while True:
          time.sleep(1)
  
      stream.stop_stream()
      stream.close()
      p.terminate()
  
  
  if __name__ == "__main__":
      main()
  
  </code></pre>
  
  <p>I record noise sample for 1 second and then go into infinite record-playback loop, where I want to denoise the input and get it to output. It works only once for some reason: I get "X" and "Y" printed out once, after a long time (why?), and program goes on and on, but does not enter callback function any more. Any ideas why? Any suggestions, other libraries easier to use here etc. are welcome.</p>