python - Python u-Law (MULAW) 波解压为原始波信号
问题描述
我在过去两周内搜索了这个问题,但找不到算法或解决方案。我有一些简短的 .wav 文件,但它具有 MULAW 压缩,并且 python 内部似乎没有wave.py
可以成功解压缩它的功能。所以我开始自己用python构建一个解码器。
我在基本元素中找到了一些关于 MULAW 的信息:
所以我需要一些指导,因为我不知道如何从有符号短整数到全波信号。这是我迄今为止收集到的初步想法:
所以从 wiki 我得到了一个 u-law 压缩和解压方程:
所以从压缩方程来看,看起来输出被限制在float
-1 到 +1 的范围内,并且有符号短整数从 –32,768 到 32,767 所以看起来我需要将它从 转换short int
为float
特定范围。
现在,老实说,我以前听说过量化,但我不确定我是否应该先尝试去量化然后解压缩或以其他方式,或者即使在这种情况下它是同一件事......使用术语的教程/文档可能有点棘手。
我正在使用的波形文件应该包含类似于语音合成的“A”声音,我可以通过比较一些音频软件和自定义波形分析器中的 2 个波形来验证成功,但我真的很想减少这个试验和错误部分过程。
所以我的想法是:
u = 0xff
data_chunk = b'\xe7\xe7' # -6169
data_to_r1 = unpack('h',data_chunk)[0]/0xffff # I suspect this is wrong,
# # but I don't know what else
u_law = ( -1 if data_chunk<0 else 1 )*( pow( 1+u, abs(data_to_r1)) -1 )/u
那么是否有某种算法或关键步骤我需要采取以下形式:第一:减压,第二:量化:第三?
由于我在谷歌上找到的所有内容都是如何读取.wav
PCM 调制的文件类型,而不是在出现野压缩时如何管理它。
解决方案
所以,在搜索了谷歌之后,在 github 中找到了解决方案(去图)。我搜索了许多算法,发现 1 在有损压缩的误差范围内。这适用于 30 -> 1 的正值和 -32 -> -1 的负值
老实说,我认为这个解决方案是足够的,但并不完全符合每个方程,但它是目前最好的解决方案。这段代码直接从gcc9108音频编解码器转录成python
def uLaw_d(i8bit):
bias = 33
sign = pos = 0
decoded = 0
i8bit = ~i8bit
if i8bit&0x80:
i8bit &= ~(1<<7)
sign = -1
pos = ( (i8bit&0xf0) >> 4 ) + 5
decoded = ((1 << pos) | ((i8bit & 0x0F) << (pos - 4)) | (1 << (pos - 5))) - bias
return decoded if sign else ~decoded
def uLaw_e(i16bit):
MAX = 0x1fff
BIAS = 33
mask = 0x1000
sign = lsb = 0
pos = 12
if i16bit < 0:
i16bit = -i16bit
sign = 0x80
i16bit += BIAS
if ( i16bit>MAX ): i16bit = MAX
for x in reversed(range(pos)):
if i16bit&mask != mask and pos>=5:
pos = x
break
lsb = ( i16bit>>(pos-4) )&0xf
return ( ~( sign | ( pos<<4 ) | lsb ) )
带测试:
print( 'normal :\t{0}\t|\t{0:2X}\t:\t{0:016b}'.format(0xff) )
print( 'encoded:\t{0}\t|\t{0:2X}\t:\t{0:016b}'.format(uLaw_e(0xff)) )
print( 'decoded:\t{0}\t|\t{0:2X}\t:\t{0:016b}'.format(uLaw_d(uLaw_e(0xff))) )
和输出:
normal : 255 | FF : 0000000011111111
encoded: -179 | -B3 : -000000010110011
decoded: 263 | 107 : 0000000100000111
正如你所看到的,263-255 = 8 在界限内。当我尝试实现G.711seeemmmm
中描述的方法时,该用户 Oliver Charlesworth 建议我查看,数据中最大值的解码值为 -8036,接近 uLaw 规范的最大值,但我无法反转工程师解码函数以从维基百科获得函数的二进制等效项。
最后,我必须说,我目前对 python 库不支持所有类型的压缩算法感到失望,因为它不仅仅是人们使用的工具,它也是 python 消费者学习的资源,因为大部分数据可以进一步深入研究代码不容易获得或理解。
编辑
在通过解码数据并写入 wav 文件后,wave.py
我成功地写入了一个新的原始线性 PCM 文件。这行得通……尽管我一开始持怀疑态度。
编辑2:::>你可以在compressions.py上找到真正的解决方案
推荐阅读
- gremlin - 我可以强制 GLV 使用 HTTP 而不是 WS 吗?
- python - 如何将原始 HTML/JavaScript 添加到 Dash 应用程序?
- entity-framework-6 - 实体框架:如何使用 Fluent API 将列的类型设置为 uniqueidentifier
- wordpress - 向 Woocommerce 产品页面添加自定义按钮
- php - 上传返回 502 Bad Gateway -> error_log: Cannot open shared object file: No such file or Directory
- apache - 如何在第二台服务器上安装通配符 SSL
- c# - StartCoRoutine(string) 没有实现预期的效果
- arm - 在 ARM Cortex-M、MSP 或 PSP 中,哪个堆栈用于复位?
- jquery - 有没有更好的方法来处理 Django 的 AJAX 文件下载?
- css - jsp和tomcat的css mime类型问题