iphone - 解码ima4音频格式

标签 iphone file-format ima4

为了减少 iPhone 应用程序的下载大小,我压缩了一些音频文件。具体来说,我在命令行上使用 afconvert 将 .wav 格式更改为 .caf 格式(使用 ima4 压缩)。

我已阅读 this (wooji-juice.com) 关于这个主题的精彩帖子。我在“解码 ima4 数据包”步骤中遇到问题。我查看了他们的示例代码,但我被困住了。请帮助使用一些伪代码或示例代码来指导我正确的方向。

谢谢!

其他信息: 这是我已完成的工作以及遇到的问题...... 我可以在模拟器和手机上播放 .wav 文件。 我可以在命令行上使用 afconvert 将 .wav 文件压缩为 .caf w/ima4 压缩。我正在使用带有 CrashLanding 的 SoundEngine(我修复了一个内存泄漏)。 我修改了 SoundEngine 代码以查找 mFormatID 'ima4'。

我不明白上面链接的博客文章,开头是“计算解压数据的大小”。为什么我需要这样做?另外,术语“数据包”指的是什么?我对任何类型的音频编程都很陌生。

最佳答案

收集完 Wooji-Juice 的所有数据后, Multimedia WikiApple ,这是我的建议(可能需要一些实验):

文件结构

  • Apple IMA4 文件由 34 字节的数据包组成。这是用于构建文件的数据包单元。
  • 每个 34 字节数据包由两部分组成:
    • 前 2 个字节包含前导码:初始预测器和步骤索引
    • 剩下的 32 个字节包含声音半字节(4 位半字节用于检索 16 位样本)
  • 每个数据包都有 32 字节的压缩数据,代表 16 位的 64 个样本。
  • 如果声音文件是立体声,则数据包是交错的(一个用于左,一个用于右);数据包数量必须为偶数。

解码

每个34字节的数据包将导致解压缩64个16位的样本。因此未压缩数据的大小为每个数据包 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;
}

关于iphone - 解码ima4音频格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2130831/

相关文章:

file-format - CorelDraw 文件格式

audio - 播放ima4文件

iphone - UITableViewCell 中的 UILabel 溢出

iphone - NSUserDefaults 的读取访问是 "expensive"操作吗?

iphone - 如何获取 iPhone 设备上已安装的应用程序列表?

iphone - Objective-c:在数组内分配变量而不是字符串

xml - 用于定义(输入参数)命令行工具的任何通用(xml?)格式?

preview - CKAN数据预览工具可以预览哪些文件格式?