python - 如何在 sounddevice 中停止 stream.write 函数
问题描述
是否可以在缓冲区完全消耗之前停止 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()
函数的实现或查看示例,例如play_long_file.py。
正如您所提到的,您还可以使用所谓的“阻塞”API(使用write()方法)。
无论哪种方式,您通常会将音频数据拆分为一系列块。这样,您可以安排在任何一个块之后停止播放。这也是play()
函数内部所做的。
推荐阅读
- r - 如何修复圆形树状图中的重叠标签?
- php - 如何从不同的搜索字段输出信息?
- ios - 从集合视图单元格内的按钮按下实例化故事板
- excel - 由于页面布局在宽度上添加了额外的像素,Word Wrap 在打印 Excel 表时添加了空白行
- blueprism - 如何通过 Blue Prism 中的代码阶段访问工作队列?
- excel - 将excel中的名称从(Last,First)重组为(First Last)
- android - 如何在 Android 和 IOS 上无需设置即可使用 Firebase 和 Flutter
- swift - 无法返回最后带有 catch 块的承诺链
- perl - Windows 和 linux 中的 Perl 超时命令
- javascript - 在发送到后端时显示数据