
G711 a-law u-law 按照非线性将16bit压缩为8bit
8000HZ / 50 * 2 = 320 压缩为160
G719 MDCT算法 保真 这一步无压缩
import numpy as np
============================
G.719 标准参数
============================
N = 960 # MDCT 输出长度
FRAME = 2 * N # 输入 1920 点
OVERLAP = N # 50% 重叠
Fs = 48000
============================
生成连续 PCM
============================
total = FRAME + OVERLAP
t = np.arange(total) / Fs
pcm = np.sin(2 * np.pi * 440 * t) * 1.0 # 小幅度,好观察
50% 重叠分块
x1 = pcm[:FRAME]
x2 = pcm[OVERLAP:OVERLAP+FRAME]
============================
正确 MDCT 公式
============================
def mdct(x):
N = len(x) // 2
X = np.zeros(N, dtype=np.float64)
for k in range(N):
val = 0.0
for n in range(2*N):
theta = (np.pi / N) * (n + 0.5 + N/2) * (k + 0.5)
val += x[n] * np.cos(theta)
X[k] = val
return X
============================
正确 IMDCT 公式
============================
def imdct(X):
N = len(X)
y = np.zeros(2*N, dtype=np.float64)
for n in range(2*N):
val = 0.0
for k in range(N):
theta = (np.pi / N) * (n + 0.5 + N/2) * (k + 0.5)
val += X[k] * np.cos(theta)
y[n] = val / N
return y
============================
变换 + 逆变换
============================
X1 = mdct(x1)
X2 = mdct(x2)
y1 = imdct(X1)
y2 = imdct(X2)
============================
TDAC 重叠相加(核心抵消)
============================
restored = y1[N:] + y2[:N]
original = pcm[N : N+N]
============================
结果对比
============================
print("==== 正确对比:重叠区原始 vs 恢复 ====")
print("原始前5点: ", original[:5])
print("恢复前5点: ", restored[:5])
max_err = np.max(np.abs(restored - original))
print(f"\n最大误差: {max_err:.2e}")
if max_err < 1e-6:
print("✅ 完美成功:MDCT + TDAC 100% 还原信号!")
else:
print("❌ 错误")
//////////////////
==== 正确对比:重叠区原始 vs 恢复 ====
原始前5点: [-0.95105652 -0.93169123 -0.90923611 -0.88376563 -0.85536426]
恢复前5点: [-0.95105652 -0.93169123 -0.90923611 -0.88376563 -0.85536426]
最大误差: 4.71e-13
✅ 完美成功:MDCT + TDAC 100% 还原信号!
///////////
原始 PCM 是一段连续信号
原始pcm:[===========================] 总长 2880 点
G.719 切成两块,重叠 50%
块1:[====================] 0 ~ 1919 (1920点)
块2: [====================] 960 ~ 2879 (1920点)
中间重叠的部分就是
960 ~ 1919 (共 960 点)
original = pcm[960 : 960+960]
= pcm[960 : 1920]
拿出原始信号中【两块重叠的区域】这是我们的目标真值。
restored = y1[N:] + y2[:N]
y1[N:] → 块 1 逆变换后的后半段 960 点
y2[:N] → 块 2 逆变换后的前半段 960 点
结论:
块 1 后半段 带畸变
块 2 前半段 带畸变
两个畸变加起来 = 0!
剩下的就是纯净原始信号!