Загальний опис роботи

B IMA ADPCM для зберігання кожного відліку використовуються 4 біта Кодує модуль бере різницю між двома відліками, ділить її на поточний розмір кроку і використовує отриману величину в якості чергового стисненого 4-бітного вихідного значення Декомпрессор, навпаки, бере це 4-бітове значення, примножує його на поточну величину кроку і додає вийшов результат до попереднього відліком, отримуючи тим самим черговий відлік Змінюючи розмір кроку, за допомогою 4-бітного коду можна записати великий діапазон значень

Для скорочення обсягу інформації сам розмір кроку не зберігається Замість нього компресор зберігає індекс у таблицю, що містить 88 можливих значень розміру кроку Величини розмірів кроку слідують приблизно експоненційної кривої цікаво порівняти ці значення з графіком функції 11n

Лістинг 131 Таблиця допустимих значень розміру кроку для IMA ADPCM

static const int _stepSizeTable[89] = {

7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,

34,

37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130,

143,

157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,

494,

544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411,

1552,

1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026,

4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,

11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623,

27086, 29794, 32767

}

Для зберігання в таблиці індексу розміру кроку потрібно всього 7 біт 16 біт займає поточне нестиснене значення Для економії місця сучасні компресори відкидають молодші біти поточного нестисненого відліку, що дозволяє розміщувати інформацію про стан процесу всього в 16 бітах

Лістинг 132 Інформація стану IMA ADPCM

struct ImaState {

int index / / Індекс у таблиці значень розміру кроку

int previousValue / / Величина останньої вибірки

}

Важливим елементом IMA ADPCM є механізм управління розміром кроку B 4-бітний відлік записується представлене в прямому коді зі знаком число в діапазоні від -7 до +7 Оскільки декомпресора невідома величина наступного відліку, він повинен зробити вибір, грунтуючись на попередніх значеннях Якщо отримане в результаті перетворення прирощення 4-бітове число велике, можливо, що наступне буде ще більше і для його розміщення не вистачить чотирьох біт Якщо 4-бітове представлення прирощення величина невелика, значить, ви не повною мірою використовуєте наявні у вас 4 біти інформації B результаті, якщо величина, що виходить при розподілі приросту на розмір кроку, наближається до нуля розмір кроку зменшується, якщо вона зростає крок збільшується

Кожен 4-бітний напівбайт являє собою число, записане впрямому ході зі знаком старший біт це знак числа, а інші біти містять число від нуля до 7 (B відміну від більш широко поширеного формату, що використовує додатковий код, при записі в прямому коді зі знаком робиться відмінність між +0 і -0)

Лістинг 133 Таблиця корекції індексу IMA ADPCM

static const int indexAdjustTable[16] = {

-1, 1, 1, 1, / / ​​+0 +3, зменшення кроку

2, 4, 6, 8, / / ​​+ 4 + 7, збільшення кроку

-1, 1, 1, 1, / / ​​-0 -3, зменшення кроку

2, 4, 6, 8,          // -4 -7,   збільшення кроку

}

Декомпресія

Найцікавіша особливість функції ImaAdpcmDecode полягає в тому, що в ній 4-бітна закодована величина не множиться безпосередньо на поточний розмір кроку Замість цього використовується послідовність бітових операцій, що дає приблизно такий же результат Однак ці бітові операції не можуть бути безпосередньо множенням: ми не можемо використовувати множення, якщо хочемо отримати коректно сформований вихідна число

Лістинг 134 Функція декодування IMA ADPCM

AudioSample ImaAdpcmDecode(AudioByte deltaCode, ImaState &ampstate)

{

/ / Отримуємо значення поточної величини кроку int step = _stepSizeTable [stateindex]

/ / Створюємо прирощення, масштабуючи поточну величину кроку

/ / Приблизно так: прирощення = (deltaCode + 5) * крок / 4

int difference = step&gt&gt3

if (deltaCode &amp 1 ) difference += step&gt&gt2 if (deltaCode &amp 2 ) difference += step&gt&gt1 if (deltaCode &amp 4 ) difference += step

if (deltaCode &amp 8 ) difference = difference

/ / Обчислюємо нову вибірку

statepreviousValue += difference

if (statepreviousValue &gt 32767) statepreviousValue = 32767

else if (statepreviousValue &lt 32768) statepreviousValue = -32768

/ / Оновлюємо величину кроку для обробки наступної вибірки

stateindex += indexAdjustTable[deltaCode]

if (stateindex &lt 0) stateindex = 0

else if (stateindex &gt 88) stateindex = 88

return statepreviousValue

}

Компресія

Практично робота компресора йде саме так, як можна було б очіку-

дати Спочатку обчислюється прирощення, а потім за допомогою послідовності бітових операцій проводиться приблизне поділ на поточний розмір кроку (Ha багатьох мікропроцесорах бітові операції виконуються набагато швидше, ніж реальна операція ділення) Зверніть увагу на використання безпосереднього виклику ImaAdpcmDecode для забезпечення гарантії коректності оновлення інформації про стан

Лістинг 135 Функція кодування IMA ADPCM

AudioByte ImaAdpcmEncode(AudioSample sample, ImaState &ampstate) {

int diff = sample statepreviousValue int step = _stepSizeTable[stateindex] int deltaCode = 0

/ / Записуємо знаковий біт

if (diff &lt 0) { deltaCode = 8 diff = diff }

/ / B сутності, виходить deltaCode = (diff << 2) / mar,

/ / За винятком того, що округлення обробляється особливо

if (diff &gt= step ) { deltaCode |= 4 diff = step }

step &gt&gt= 1

if (diff &gt= step ) { deltaCode |= 2 diff = step }

step &gt&gt= 1

if (diff> = step) {deltaCode | = 1 diff = step } ImaAdpcmDecode (deltaCode, state) / / Оновлюємо стан return deltaCode

}

Джерело: Кінтцель Т Керівництво програміста по роботі зі звуком = A Programmers Guide to Sound: Пер з англ М: ДМК Пресс, 2000 432 с, іл (Серія «Для програмістів»)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*