为了减少iPhone应用程序的下载大小,我正在压缩一些音频文件。具体来说,我在命令行上使用afconvert将.wav格式更改为.caf格式(带有ima4压缩)。
我已经阅读了有关该确切主题的this(wooji-juice.com)精彩文章。我在“解码ima4数据包”步骤时遇到了麻烦。我看了看他们的示例代码,然后被卡住了。请帮助一些伪代码或示例代码,它们可以指导我正确的方向。
谢谢!
附加信息:
这是我已完成的工作,遇到麻烦的地方...
我可以在模拟器和手机上播放.wav文件。
我可以使用afconvert在命令行上将.wav文件压缩为.caf w / ima4压缩。我正在使用带有CrashLanding的SoundEngine(我修复了一个内存泄漏)。
我修改了SoundEngine代码以查找mFormatID'ima4'。
我不理解上面开头带有“计算解压缩数据的大小”的链接的博客文章。为什么我需要这样做?另外,“数据包”一词指的是什么?我对任何音频编程都是新手。
最佳答案
从Wooji-Juice,Multimedia Wiki和Apple收集所有数据之后,这是我的建议(可能需要做一些实验):
档案结构
Apple IMA4文件由34个字节的数据包组成。这是用于构建文件的数据包单位。
每个34字节的数据包有两个部分:
前2个字节包含前同步码:初始预测变量和步长索引
剩下的32个字节包含声音半字节(4位半字节用于检索16位样本)
每个数据包都有32字节的压缩数据,代表64个16位样本。
如果声音文件是立体声文件,则将数据包交织(一个在左边,一个在右边);必须有偶数个数据包。
解码
每个34字节的数据包将导致对16位的64个样本进行解压缩。因此,未压缩数据的大小为每个数据包128个字节。
解码伪代码如下所示:
int[] ima_index_table = ... // Index table from [Multimedia Wiki][2]
int[] step_table = ... // Step table from [Multimedia Wiki][2]
byte[] packet = ... // A packet of 34 bytes compressed
short[] output = ... // The output buffer of 128 bytes
int preamble = (packet[0] << 8) | packet[1];
int predictor = preamble && 0xFF80; // See [Multimedia Wiki][2]
int step_index = preamble && 0x007F; // See [Multimedia Wiki][2]
int i;
int j = 0;
for(i = 2; i < 34; i++) {
byte data = packet[i];
int lower_nibble = data && 0x0F;
int upper_nibble = (data && 0xF0) >> 4;
// Decode the lower nibble
step_index += ima_index_table[lower_nibble];
diff = ((signed)nibble + 0.5f) * step / 4;
predictor += diff;
step = ima_step_table[step index];
// Clamp the predictor value to stay in range
if (predictor > 65535)
output[j++] = 65535;
else if (predictor < -65536)
output[j++] = -65536;
else
output[j++] = (short) predictor;
// Decode the uppper nibble
step_index += ima_index_table[upper_nibble];
diff = ((signed)nibble + 0.5f) * step / 4;
predictor += diff;
step = ima_step_table[step index];
// Clamp the predictor value to stay in range
if (predictor > 65535)
output[j++] = 65535;
else if (predictor < -65536)
output[j++] = -65536;
else
output[j++] = (short) predictor;
}