Как воспроизводить звук в реальном времени на Python, а также постоянно записывать? - PullRequest
0 голосов
/ 06 марта 2019

Я хочу создать глушитель речи.По сути, это то, что повторяет вам то, что вы только что сказали, но это непрерывно.Я пытался использовать библиотеку звукового устройства и записывать то, что я говорю, а также воспроизводить ее.Затем я изменил его, чтобы изначально записать то, что я говорил, а затем воспроизвести его, а также записать что-то новое.Однако он не работает так, как мне бы хотелось.Есть предложения для других библиотек?Или, если кто-то видит предложение для кода, который у меня уже есть.

Вместо того, чтобы постоянно воспроизводить меня, он запускается и останавливается.Это происходит через определенные промежутки времени.Таким образом, он будет записывать в течение 500 мс, затем воспроизводить его в течение 500 мс, а затем снова начать запись.Требуется поведение: запись в течение 500 мс во время воспроизведения звука, который он записывает, с некоторой задержкой мс.

import sounddevice as sd
import numpy as np

fs = 44100
sd.default.samplerate = fs
sd.default.channels = 2
#the above is to avoid having to specify arguments in every function call
duration = .5

myarray = sd.rec(int(duration*fs))
while(True):
    sd.wait()
    myarray = sd.playrec(myarray)
    sd.wait()

Ответы [ 2 ]

0 голосов
/ 07 марта 2019

Перефразируя мой собственный ответ от https://stackoverflow.com/a/54569667:

Функции sd.play(), sd.rec() и sd.playrec() не предназначены для многократного использования в быстрой последовательности.Внутри они каждый раз создают sd.OutputStream, sd.InputStream или sd.Stream (соответственно), воспроизводят / записывают аудиоданные и снова закрывают поток.Из-за открытия и закрытия потока будут возникать пробелы.Это ожидаемо.

Для непрерывного воспроизведения вы можете использовать так называемый «режим блокировки», создав отдельный поток и вызвав read () и / или write () методы для него.

Или, что я обычно предпочитаю, вы можете использовать так называемый «неблокирующий режим», создав собственную функцию «обратного вызова» и передав ее в потокна создание.В этой функции обратного вызова вы можете, например, записать входные данные в queue.Queue и прочитать выходные данные из той же очереди.Заранее заполнив очередь определенным количеством нулей, вы можете указать, как долго должна быть задержка между вводом и выводом.

Вы можете взглянуть на examples , чтобы увидеть, как обратный вызовиспользуются функции и очереди.

Дайте мне знать, если вам нужна дополнительная помощь, тогда я могу попытаться привести конкретный пример кода.

0 голосов
/ 07 марта 2019

Я вижу здесь потенциальную проблему, когда вы пытаетесь использовать myarray в качестве входа и выхода функции .playrec().Я бы порекомендовал иметь два массива, один для записи живого звука, а другой для воспроизведения записанного звука.

Вместо использования команды .playrec() вы можете просто быстро переключаться между использованием .record() и .play() с небольшой задержкой между циклами while.

Например, следующий код должен записывать одну миллисекунду, ждать миллисекунду и затем воспроизводить одну миллисекунду звука:

duration = 0.001

while(True):
    myarray= sd.rec(int(duration*fs))
    sd.wait()
    sd.play(myarray, (int(duration*fs)))

После воспроизведения нет задержки в миллисекунде, потому что выхочу сразу вернуться к записи следующей миллисекунды. Следует отметить, однако, что при этом запись аудио не сохраняется более одной миллисекунды! Вы должны добавить свой собственный код, который добавляет к массиву заданный размер и заполняет его.со временем.

...