Отмена воспроизведения звука с помощью pyaudio - PullRequest
1 голос
/ 07 ноября 2019

Я пишу вокодер на Python для Raspberry Pi, что-то, что бы изменить голос так, чтобы он был неузнаваем. Я записываю аудио и делаю воспроизведение в режиме реального времени с функцией обратного вызова - это работает. Теперь мне нужно удалить шум из входных данных, представленных в виде массива Numpy (НЕ .wav-файл, как большинство учебников и постов на SO!). Я пытался использовать несколько аудио-шумоподавителей, но в частности этот: https://pypi.org/project/noisereduce/ (учебник: https://timsainburg.com/noise-reduction-python.html, источник: https://github.com/timsainb/noisereduce). Это не работает для меня.
Мой основной.py:

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()

Я записываю шумовую выборку в течение 1 секунды, а затем захожу в бесконечный цикл воспроизведения записи, где я хочу подавить шум на входе и получить его на выходе. По какой-то причине он работает только один раз:Я получаю «X» и «Y» распечатаны один раз, спустя много времени (почему?), И программа продолжается и продолжает, но больше не входит в функцию обратного вызова. Любые идеи почему? Любые предложения, другие библиотеки проще в использованииздесь и т.д. приветствуются.

...