gpt4 book ai didi

python - 使用 Pygame 播放 ADPCM 流

转载 作者:太空宇宙 更新时间:2023-11-04 10:43:26 24 4
gpt4 key购买 nike

我有一些原始的 ADPCM 压缩音频流,我想用 pygame 播放它们,但据我所知,这在 pygame 中是不可能的。我怎样才能用 python 将它们解压缩为普通的 PCM 流(或其他 pygame 可以播放的东西),然后用 pygame 播放它们?

我已经尝试过 audioop 模块,因为它有一些东西可以将 ADPCM 转换为线性流,但我既不知道线性流是什么,也不知道如何使用转换它们的函数。

最佳答案

I already tried the audioop module as it has got something that converts ADPCM to linear streams but I neither know what linear streams are nor how to use the function that converts them.

简短的版本:“线性”是你想要的。* 所以,你想要的函数是 adpcm2lin


如何使用它?

audioop 中的几乎所有内容都以相同的方式工作:循环帧,并在每个帧上调用一个函数。如果您的输入数据有一些固有的帧大小,例如当您从 MP3 文件(使用外部库)读取时,或者您的输出库需要一些特定的帧大小,那么您在确定帧的方式上会受到一些限制。但是当您处理原始 PCM 格式时,帧的大小是您想要的,从单个样本到整个文件。**

为了简单起见,我们先处理整个文件:

with open('spam.adpcm', 'rb') as f:
adpcm = f.read()
pcm, _ = audioop.adpcm2lin(adpcm, 2, None)

如果您的 adpcm 文件太大而无法加载到内存中并一次处理所有文件,您将需要跟踪状态,因此:

with open('spam.adpcm', 'rb') as f:
state = None
while True:
adpcm = f.read(BLOCKSIZE)
if not adpcm:
return
pcm, state = audioop.adpcm2lin(adpcm, 2, state)
yield pcm

当然,我假设您不需要转换采样率或执行任何其他操作。如果这样做,任何此类转换都应该在 ADPCM 解压缩之后进行。***


* 长版本:“线性”表示样本直接编码,而不是通过另一种算法映射。例如,如果您有一个 16 位 A-to-D,并且您将音频保存在一个 8 位线性 PCM 文件中,那么您只是保存了每个样本的前 8 位。这为您提供了一个非常动态的范围,因此更安静的声音会在噪音中消失。有多种压扩算法可以为相同的位数提供更宽的动态范围(当然,代价是在其他地方丢失其他信息);有关它们如何工作的详细信息,请参阅 μ-law 算法。但如果你能保持 16 位,线性就可以了。

** 实际上,使用 4 位原始 ADPCM,你真的不能做一个样本......但你可以做 2 个样本,这已经足够接近了。

*** 如果您真的很挑剔,您可能想先转换为 32 位,然后执行工作,然后再转换回 16 位以避免累积损失。但是当您开始使用 4 位 ADPCM 时,您不会在这里寻求发烧友的声音。

关于python - 使用 Pygame 播放 ADPCM 流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19144864/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com