繁体   English   中英

用Pygame播放ADPCM流

[英]Play ADPCM streams with Pygame

我有一些原始的ADPCM压缩音频流,我想用pygame播放它们,但据我所知,使用pygame不可能。 如何使用python将它们解压缩为普通PCM流(或pygame可以播放的其他内容),然后使用pygame播放它们?

我已经尝试过audioop模块,因为它具有将ADPCM转换为线性流的功能,但是我既不知道线性流是什么,也不知道如何使用将其转换的函数。

我已经尝试过audioop模块,因为它具有将ADPCM转换为线性流的功能,但是我既不知道线性流是什么,也不知道如何使用将其转换的函数。

简短的版本:“线性”就是您想要的。*因此,您想要的功能是adpcm2lin


你如何使用它?

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

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

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

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

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位。 这样可以为您提供非常动感的音域,从而使安静的声音在噪音中消失。 有多种压扩算法,可以为相同数量的比特提供更大的动态范围(当然会以丢失其他位置的其他信息为代价)。 有关其工作原理的详细信息,请参见μ律算法。 但是,如果您可以保留16位,则线性是可以的。

**实际上,使用4位原始ADPCM,您实际上无法进行单个采样…但是您可以进行2个采样,这足够接近。

***如果您确实很挑剔,则可能需要先转换为32位,然后再进行工作,然后再转换回16位,以避免累积损失。 但是,当您从4位ADPCM开始时,您不会在这里获得发烧级声音。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM