python - 如何在声音设备中停止stream.write函数

标签 python audio python-sounddevice

是否可以在缓冲区完全耗尽之前停止stream.write函数?
当我尝试这样做时,声音会停止,但stream.write函数永远不会返回。

这是一个有效的示例,说明了如何使用小类播放纯净的音调而不阻塞主线程。

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数组填充缓冲区?我阅读了文档中的代码示例,但无法弄清楚该怎么做。

最佳答案

我猜最简单的方法是使用play()函数,该函数默认在后台开始播放(使用从底层PortAudio库创建的单独线程调用的回调函数)。
然后,您可以使用stop()函数停止播放。

如果您需要比简单回放NumPy数组更复杂的事情,则可以实现自己的回调函数。
例如,您可以查看play()函数的实现或examples,例如play_long_file.py

如前所述,您还可以使用所谓的“阻止” API(使用write()方法)。

无论哪种方式,您通常都会将音频数据分成一系列块。
这样,您可以安排在任何一个块之后停止播放。这也是play()函数在内部执行的操作。

关于python - 如何在声音设备中停止stream.write函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58252258/

相关文章:

android - 使用Google Chromecast从我的Android手机应用程序在电视上启动音频

python - 为什么使用 WASAPI 和 sounddevice 库录制设备时会出现 "Invalid device"错误?

python - 您如何使用在后台运行的 python 脚本轮询 JSON 文件中的更改并提取更改?

python - pd.date_range 在月底返回起始值,然后继续每月日期?

matlab - 在特定耳塞( channel )上播放歌曲

ios - 使用音频单元播放音频文件?

python - 无法使用声音设备录制声音

python - 如何在 python 中录制不确定持续时间的音频并允许暂停和恢复功能?

python - 从 Flask 中的另一条路线调用一条路线

python - pyserial写入功能 block 不写入数据并且不会超时