Пытаюсь записать с микрофона и воспроизвести в реальном времени

Я пытаюсь записать данные со своего микрофона, а затем воспроизвести их через динамики в реальном времени и с некоторыми задержками, но у меня с этим возникают некоторые проблемы. Я решил использовать python и alsaaudio, и мой текущий скрипт, с которым у меня возникли проблемы, можно найти здесь. Это работает с тем, что у меня есть до сих пор (не с задержкой), но производит некоторые щелчки. В документах alsaaudio есть это, чтобы сказать:

Наиболее распространенная причина проблем с воспроизведением звука PCM заключается в том, что запись на устройства PCM должна точно соответствовать скорости передачи данных устройства.

Если на устройство будет записано слишком мало данных, оно будет недогружено, и будут слышны некрасивые щелчки. И наоборот, если в устройство записывается слишком много данных, функция записи либо блокируется (режим PCM_NORMAL), либо возвращает ноль (режим PCM_NONBLOCK).

Кажется, я неправильно понимаю документы, там говорится о write():

PCM.запись(данные)

Записывает (воспроизводит) звук в данные. Длина данных должна быть кратна размеру кадра и должна быть точно равна размеру периода.

период в моем сценарии равен 160.

это говорит о read():

В режиме PCM_NORMAL эта функция блокируется до тех пор, пока не будет доступен полный период, а затем возвращает кортеж (длина, данные), где длина — это количество кадров захваченных данных, а данные — это захваченные звуковые кадры в виде строки. Длина возвращаемых данных будет равна размеру периода * размеру кадра в байтах.

в моем скрипте period_size*frame_size также должно быть равно 160, но когда я печатаю длину (часть возврата кортежа read()), я получаю 940. Очевидно, я не передаю нужное количество данных наружу. write(), но я не уверен, куда идти. Я собрал этот код в основном с помощью найденных мной примеров, и я только начал работать с alsaaudio/sound, пытаясь собрать несколько интересных проектов, так что я еще не очень много знаю.

Я также хотел записать вживую с микрофона, а затем воспроизвести с задержкой в ​​100 мс, отсюда и закомментированный time.sleep(). Если я раскомментирую его, длина, кажется, многократно увеличивается от 940 до -32, что в конечном итоге приводит к тому, что out.write() выдает исключение (недостаточно данных).

Может ли кто-нибудь сказать мне, как (или что не так с моим сценарием) я буду записывать и воспроизводить звуковые данные в реальном времени и с задержкой 100 мс?


person src    schedule 18.08.2011    source источник


Ответы (2)


вы не можете использовать sleep(0.1) для задержки вывода на 100 мс. вам нужно создать буфер, в котором хранятся аудиоданные 100 мс:

buf = []
while True:
    l, data = inp.read()
    buf.append(data)
    if len(buffer)>=10:
        out.write(buf[0])
        del buf[0]

измените 10 на некоторое число, которое вызовет задержку 100 мс.

person HYRY    schedule 18.08.2011
comment
Ясно спасибо. Я сделал это, и это определенно работает с задержкой (все еще с щелчком), но я не уверен, как определить, какое число вызовет правильную задержку. Я попытался напечатать прошедшее время, например this, и поиграться с числом, но оно, похоже, не изменилось. Также это кажется более эхом - person src; 18.08.2011
comment
Плевать на эхо, ха-ха. Микрофон был как раз рядом с динамиками, да. - person src; 18.08.2011

Вы пробовали алсалуп? Попробуйте "человек алсалуп". Вы также можете выбрать задержку с помощью этой команды.

person akostadinov    schedule 02.10.2012