Как остановить функцию stream.write в sounddevice - PullRequest
0 голосов
/ 05 октября 2019

Можно ли остановить функцию stream.write до полного использования буфера? Когда я пытаюсь это сделать, звук останавливается, но функция stream.write никогда не возвращается.

Это рабочий пример того, как я хочу использовать небольшой класс для воспроизведения звуков чистых тонов без блокировки основногоthread.

import time
import sounddevice as sd
import numpy as np
from threading import Thread

toneduration = 10
samplerate = 44100
frequency = 440
amplitude = 0.5

sd.default.device = 1
sd.default.samplerate = samplerate
sd.default.channels = 2

class Sound(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.stream = sd.OutputStream()
        self.stream.start()

        vector1 = np.linspace(0, toneduration, toneduration * samplerate)
        vector2 = amplitude * np.sin(2 * np.pi * frequency * vector1)
        vector3 = np.array([vector2, vector2])
        self.soundVector = np.ascontiguousarray(vector3.T, dtype=np.float32)

    def run(self):
        self.stream.write(self.soundVector)
        print('end')

sound = Sound()
sound.start()
time.sleep(3)
sound.stream.close()

Я могу воспроизводить звуки заданной длительности, но если я остановлю поток вручную, используя stream.close(), функция не вернется (сообщение print('end') никогда не отображается, а поток нене закончено)

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

1 Ответ

0 голосов
/ 06 октября 2019

Полагаю, самым простым способом было бы использовать функцию play () , которая по умолчанию запускает воспроизведение в фоновом режиме (используя функцию обратного вызова, вызываемую из отдельного потока, созданного базовой библиотекой PortAudio). Затем вы можете использовать функцию stop () для остановки воспроизведения.

Если вам нужно что-то более сложное, чем простое воспроизведение массива NumPy, вы можете реализовать свою собственную функцию обратного вызова. В качестве примера вы можете посмотреть на реализацию функции play() или examples , например, play_long_file.py .

Как вы уже упоминали, вы можететакже используйте так называемый «блокирующий» API (используя метод write () ).

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

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