Почему эта программа pyaudio не производит звук? - PullRequest
1 голос
/ 21 марта 2019

Я использую lubuntu 18.04, python 3.6.5 и pyaudio 0.2.11 от Anaconda, установленные:

conda install nwani :: portaudio nwani :: pyaudio

Я использую pyaudio с канала nwani, потому что он исправил ошибку. См. Обсуждение OSError: Нет доступного устройства ввода по умолчанию

Однако я все еще очень стараюсь заставить что-то работать должным образом. Около половины примеров, которые я пробовал из Интернета, провалились Я буду придерживаться специфики. Кто-нибудь может понять, почему приложенный код не выводит звук непосредственно с микрофона?

Отладочная печать непрерывно записывает в консоль «цикл», и генератор генерирует байтовые массивы правильного размера, но звук по-прежнему не воспроизводится.

Я действительно знаю, что в коде генератора что-то останавливает звук. Я определил это, отправив аудиоданные из волнового файла в выходной поток из цикла генератора - он не излучается. Но если я поменяю генератор на:

if True: yield 1

, таким образом, вызывая непрерывную работу цикла генератора, но без выполнения каких-либо манипуляций с буфером, генерируется волновой файл.

Полная программа:

import pyaudio
from six.moves import queue

# Audio recording parameters
RATE = 16000
CHUNK = int(RATE / 10)  # 100ms


class MicrophoneStream(object):
    """Opens a recording stream as a generator yielding the audio chunks."""
    def __init__(self, rate, chunk, audio):
        self._rate = rate
        self._chunk = chunk
        self._audio_interface = audio

        # Create a thread-safe buffer of audio data
        self._buff = queue.Queue()
        self.closed = True

    def __enter__(self):
        self._audio_stream = self._audio_interface.open(
            format=pyaudio.paInt16,
            channels=1, rate=self._rate,
            input=True, frames_per_buffer=self._chunk,
            stream_callback=self._fill_buffer,
        )

        self.closed = False

        return self

    def __exit__(self, type, value, traceback):
        self._audio_stream.stop_stream()
        self._audio_stream.close()
        self.closed = True
        # Signal the generator to terminate so that the client's
        # streaming_recognize method will not block the process termination.
        self._buff.put(None)
        self._audio_interface.terminate()

    def _fill_buffer(self, in_data, frame_count, time_info, status_flags):
        """Continuously collect data from the audio stream, into the buffer."""
        self._buff.put(in_data)
        return None, pyaudio.paContinue

    def generator(self):
        while not self.closed:
            # Use a blocking get() to ensure there's at least one chunk of
            # data, and stop iteration if the chunk is None, indicating the
            # end of the audio stream.
            chunk = self._buff.get()
            if chunk is None:
                return
            data = [chunk]

            # Now consume whatever other data's still buffered.
            while True:
                try:
                    chunk = self._buff.get(block=False)
                    if chunk is None:
                        return
                    data.append(chunk)
                except queue.Empty:
                    break

            yield b''.join(data)


p = pyaudio.PyAudio()

outputStream = p.open(format=pyaudio.paInt16, channels=1, rate=RATE, output=True)

with MicrophoneStream(RATE, CHUNK, p) as inputStream:
    for data in inputStream.generator():
        outputStream.write(data)
        print('looping')


outputStream.stop_stream()
outputStream.close()
p.terminate()
...