Python 方法可以减少应该连续的进程中的"breaks"或暂停,特别是音频?



我正试图在播放歌曲时编辑该歌曲。到目前为止,我已经成功地创建了一个流,它几乎满足了我的需求。我将分享它是如何工作的,以及让我来这里寻求建议的问题。

我把一首歌作为数组y和采样率sr。然后,一个数据馈送,每5秒提供一次新的ping(下面表示为arguments=[](。在播放期间,我使用ping来编辑我的歌曲。然后,每5秒重复一次。

import librosa as lr
y, sr = lr.load(song)
arguments=[] # Populated from external source.
for arg in arguments:
end += some_interval
if end > y.size: ... # breaks out of the loop if the song is over.
x, sr = song_edit(y[front:end],sr, arg)
sd.play(x, sr, blocking=True)
front=end

问题:

  • 在一段5秒的音乐剪辑结束后和下一段音乐剪辑结束时会出现轻微延迟。在音乐领域,这从根本上是有问题的

我考虑过的解决方案:

  • 由于在sd.play中blocking=True,因此在播放整个剪辑时,代码将停止。因此,延迟必须是可解的
  • 我曾考虑过线程或多处理。这是最好的方法吗?我的理解是线程不起作用,因为我的论点不是预先确定的
  • 我错过了什么

编辑:我测试了这个:

#x, sr = song_edit(y[front:end],sr, arg)
sd.play(y[front:end], sr, blocking=True)

延迟仍然存在!因此,延迟必须由循环的迭代或sd.play中的固有延迟引起。

更接近答案:典型的播放(歌曲(功能,如librosa、pyaudio、sounddevice和许多其他功能,主要是为jupyter笔记本电脑和简单的实现而设计的。(忘记来源(。我提到的每个库(我确信pyaudio和sd(都有一个Stream类,它比简单的播放函数更适合分析。

PyAudio:Stream对象的一个可选参数是回调。当流恢复时,流循环通过回调函数,回调函数向流提供数据。

# define callback (2)
def callback(in_data, frame_count, time_info, status):
data = wf.readframes(frame_count)
print('We Done it!')
return (data, pyaudio.paContinue)

# open stream using callback (3)
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True,
stream_callback=callback)

这段代码来自PyAudio文档,但我做了一个小改动:回调函数中的print语句。该代码的输出(连同一些其他行,如实例化对象(将是音频输出+"0";我们做到了"每秒打印多次。

我仍然不完全理解回调是如何工作的,但这有助于推动我的旅程。

相关内容

最新更新