У меня есть установка с raspberry pi 3, на которой работает последняя версия jessie со всеми установленными обновлениями, в которой я предоставляю Bluetooth-приемник A2DP, где я подключаюсь к телефону, чтобы воспроизвести музыку.
Через pulseaudio источник (телефон) направляется на выход alsa (приемник). Это работает достаточно хорошо.
Теперь я хочу проанализировать аудиопоток, используя python3.4 с librosa, и я нашел многообещающий пример с использованием < href="https://people.csail.mit.edu/hubert/pyaudio/docs/#example-callback-mode-audio-io" rel="nofollow noreferrer">pyaudio, который был адаптирован для использования ввод pulseaudio (который волшебным образом работает, потому что он используется по умолчанию) вместо wavfile:
"""PyAudio Example: Play a wave file (callback version)."""
import pyaudio
import wave
import time
import sys
import numpy
# instantiate PyAudio (1)
p = pyaudio.PyAudio()
# define callback (2)
def callback(in_data, frame_count, time_info, status):
# convert data to array
data = numpy.fromstring(data, dtype=numpy.float32)
# process data array using librosa
# ...
return (None, pyaudio.paContinue)
# open stream using callback (3)
stream = p.open(format=p.paFloat32,
channels=1,
rate=44100,
input=True,
output=False,
frames_per_buffer=int(44100*10),
stream_callback=callback)
# start the stream (4)
stream.start_stream()
# wait for stream to finish (5)
while stream.is_active():
time.sleep(0.1)
# stop stream (6)
stream.stop_stream()
stream.close()
wf.close()
# close PyAudio (7)
p.terminate()
Теперь, когда поток данных в принципе работает, есть задержка (длина буфера), с которой вызывается stream_callback. Поскольку в документах указано
Обратите внимание, что PyAudio вызывает функцию обратного вызова в отдельном потоке.
я бы предположил, что пока работает обратный вызов, буфер продолжает заполнять основной поток. Конечно, была бы начальная задержка для заполнения буфера, после чего я ожидал получить синхронный поток.
Мне нужна более длинная часть в буфере (см. frame_in_buffer), чтобы librosa могла правильно выполнять анализ.
Как такое возможно? Это ограничение софт-портов для raspberry ARM?
Я нашел другие ответы, но они используют блокировка ввода/вывода. Как бы я обернул это в поток, чтобы анализ librosa (который может занять некоторое время) не блокировал заполнение буфера?
Этот блог, похоже, снижает производительность проблемы с cython, но я не думаю, что задержка связана с производительностью. Или может это? Другим, кажется, нужны некоторые настройки ALSA, но поможет ли это при использовании pulseaudio?
Спасибо, любой вклад приветствуется!
stream.stop_stream()
, иstream.close()
? Какая разница? - person Matthew D. Scholefield   schedule 29.06.2017