Декодирование ima4 формат аудио

Для сокращения размера загрузки приложения для iPhone, я сжимаю некоторые звуковые файлы. Конкретно я использую afconvert на командной строке для изменения .wav формата на .caf сжатие w/ima4 формата.

Я считал этот (wooji-juice.com) потрясающее сообщение об этой точной теме. Я испытываю затруднения w/"декодирование ima4 пакеты" шаг. Я посмотрел на их пример кода, и я застреваю. Помогите w/некоторый псевдо код или пример кода, который может вести меня в правильном направлении.

Спасибо!

Дополнительная информация: Вот то, что я завершил и где я испытываю затруднения... Я могу играть .wav файлы и в средстве моделирования и в по телефону. Я могу сжать .wav файлы до сжатия .caf w/ima4 с помощью afconvert на командной строке. Я использую SoundEngine, который приехал w/CrashLanding (я зафиксировал одну утечку памяти). Я изменил код SoundEngine для поиска mFormatID 'ima4'.

Я не понимаю сообщение в блоге, связанное выше запуска w/"Вычисление размера распакованных данных". Почему я должен сделать это? Кроме того, к чему относится термин "пакет"? Я очень плохо знаком с любым видом аудио программирования.

9
задан Jon Seigel 12 April 2010 в 13:42
поделиться

2 ответа

После сбора всех данных из Wooji-Juice , Multimedia Wiki и Apple , вот мое предложение (может потребоваться некоторый эксперимент):

Файловая структура

  • Файл Apple IMA4 состоит из пакета по 34 байта. Это пакетная единица, используемая для создания файла.
  • Каждый 34-байтовый пакет состоит из двух частей:
    • первые 2 байта содержат преамбулу: начальный предсказатель и индекс шага
    • 32 байта слева содержат звуковые полубайты. (4-битный полубайт используется для извлечения 16-битной выборки)
  • Каждый пакет содержит 32 байта сжатых данных, которые представляют 64 выборки по 16 бит.
  • Если звуковой файл является стереофоническим, пакеты чередуются (один для левого, один для правого); количество пакетов должно быть четным.

Декодирование

Каждый пакет размером 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;
}
11
ответ дан 4 December 2019 в 19:33
поделиться

Я думаю, что вам придется выполнить свою собственную INamingConvention , чтобы работать вокруг этого.

-121--2560817-

я лично использую git с cygwin. я предпочитаю это svn из-за боли, которую svn вызывал у меня в прошлом со слияниями. git был разработан с сделать слияния безболезненными, и это делает очень эффективную работу, чтобы придерживаться этого.

если cygwin не является вашей чашкой чая, и вам нужно иметь Windows Explorer интеграции, пожалуйста, ознакомьтесь с ToroityGit проект. Он имеет внешний вид и ощущение ToroireSVN, так что это легко взять. Вы можете даже запустить ToroitseGit и TortoitySVN бок о бок, если хотите.

Также TortoityGit построил поддержку SVN репо, чтобы вы могли проверить svn репо и получить все преимущества местных филиалов и то, что у вас есть.

-121--3227035-

Термин «пакет» относится к группе сжатых аудиоотсчетов с заголовком. Заголовок необходим для немедленного декодирования данных. Если вы считаете свой файл ima4 книгой, то каждый пакет - это страница. Вверху находятся значения, необходимые для декодирования этой страницы, за которыми следует сжатый звук.

Вот почему вам нужно вычислить размер распакованных данных (а затем освободить место для них) - так как они сжаты, вы должны преобразовать данные из сжатого аудио в несжатый аудио прежде, чем вы сможете их вывести. Чтобы выделить выходной буфер, необходимо знать, насколько он должен быть большим (обратите внимание, что может потребоваться выводить порции, превышающие один пакет за один раз).

Типичная структура, согласно предыдущему разделу «Обзор», состоит в том, что наборы 64 выборок, каждый 16 бит (так 128 байт) преобразуются в 2-байтовый заголовок и 32-байтовый набор сжатых выборок (всего 34 байт). Так, в типичном случае, вы можете получить ожидаемый выходной набор данных, взяв размер входных данных, разделив на 34, чтобы получить количество пакетов, затем умножив на 128 байт для несжатого звука на пакет.

Но вы не должны этого делать. Похоже, вместо этого вы должны запросить kAudioFilePropertyDataFormat, чтобы получить mBytesPerPacket - это значение «34» выше, и mFramesPerPacket - это 64, выше, которое умножается на 2 (для 16-байтовых выборок), чтобы получить 128 байт вывода.

Затем для каждого пакета необходимо выполнить декодирование, описанное в посте. В несколько более длинном псевдокоде, предполагая, что вы получаете массивы байтов, для обработки заголовка:

packet = GetPacket();
Header = (packet[0] << 8) | packet[1]; //Big-endian 16-bit value
step_index = Header & 0x007f; //Lower seven bits
predictor = Header & 0xff80; //Upper nine bits
for (i = 2; i < mBytesPerPacket; i++)
{
    nibble = packet[i] & 0x0f; //Low Nibble
    process that nibble, per the blogpost -- be careful on sign-extension!
    nibble = (packet[i] & 0xf0) >> 4; //High Nibble
    process that nibble, per the blogpost -- be careful on sign-extension!
}

Расширение sign-выше относится к тому факту, что пост включает в себя обработку каждого nibble как неподписанным, так и подписанным способом. Если высокий бит nibble (бит 3) равен 1, то он отрицательный; кроме того, битовый сдвиг может выполнять расширение знака. Это не обрабатывается в вышеуказанном псевдокоде.

1
ответ дан 4 December 2019 в 19:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: