Компресія μ-Law

B Сполучених Штатах найбільшого поширення набула так звана кодуваннямю-muna(Іноді пишеться u-Law або mu-Law) Щоб не ускладнювати записи формул, будемо вважати, що всі моментальні значення представляютсобой дробові числа в діапазоні від -1 до +1

Якщо ви працюєте з 16-бітними отсчетами, то вам необхідно перед примі-

нением формул поділити їх на 32768

Нехай у нас є вибіркаs  Тоді відповідний їй відлік мю-типу sm

обчислюється за формулою: sm = sign (s) log (1 + 255 | s |) / log (1 + 255) Цю

формулу простіше запамятати, якщо розглядати її тільки для позитивних значень У такому випадку вона відразу приймає вид log (1 +255 s) / log (1 +255) Використовуване тут число 255 іноді замінюється іншими величинами

Для перетворення вибірок мю-типу назад в лінійні відліки достатньо скористатися зворотної формулою: s = (256sm 1) / 255 He забудьте, що це вірно тільки для позитивних чисел: при роботі з негативними величинами вам доведеться користуватися абсолютними значеннями і міняти знак у числа, одержуваного в результаті перетворення

Розглянуті нами формули безпосередньо в програмах не застосовуються, так як обчислення логарифма і зведення числа в ступінь вимагають багато машинного часу Витрат часу можна уникнути, використовуючи в програмах заздалегідь прораховані таблиці перетворення Однак спочатку кодування мютіпа розроблялося для апаратної реалізації, а в такому випадку довідкові таблиці не так ефективні З цієї причини в стандарті ITU G711 описується особлива апроксимація, яка може бути легко обчислена апаратно Як видно з рис 111, результати, одержувані за допомогою цієї апроксимації, дуже близькі до даних, що отримуються за допомогою формул Хоча відмінностей достатньо, щоб не змішувати два ці способи

Описаний нижче клас DecompressG711MuLaw забезпечує виконання процедур декомпресіі, відповідних стандарту G711

Лістинг 113 Інтерфейс для кодування мю-типу

class DecompressG711MuLaw: public AbstractDecompressor {

public:

DecompressG711MuLaw(AudioAbstract &ampa)

size_t GetSamples(AudioSample *buffer, size_t length)

}

AudioSample MuLawDecode(AudioByte) AudioByte MuLawEncode(AudioSample)

Щоб ви могли, при бажанні, поекспериментувати, я зробив методи

MuLawDecode і MuLawEncode відкритими

Для прискорення обробки даних клас DecompressG711MuLaw застосовує метод MuLawEncode для ініціалізації внутрішньої таблиці, після чого отримана таблиця використовується для швидкого декодування Ініціалізація таблиці потрібно тільки один раз, при створенні обєкта класу DecompressG711MuLaw

Лістинг 114 Реалізація методів кодування мю-типу

/ * Перетворення мю-типу * /

static bool muLawDecodeTableInitialized = false

static AudioSample muLawDecodeTable[256]

/ / Конструктор инициализирует таблицю декодування

DecompressG711MuLaw::DecompressG711MuLaw(AudioAbstract &ampa)

: AbstractDecompressor(a) {

/ / Кодування: мю-типу, стандарт ITU G711

cerr &lt&lt &quotEncoding: ITU G711 mu-Law\n"

if (muLawDecodeTableInitialized) { muLawDecodeTableInitialized = true for(int i=0i&lt256i++)

muLawDecodeTable[i] = MuLawDecode(i)

}

}

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

Лістинг 114 Реалізація методів для кодування мю-типу (продовження)

size_t DecompressG711MuLaw::GetSamples(AudioSample *buffer, size_t length) {

AudioByte *byteBuff =

reinterpret_cast&ltAudioByte *&gt(buffer) size_t read = ReadBytes(byteBuff,length) for(long i=read-1 i&gt=0 i–)

buffer[i] = muLawDecodeTable[ byteBuff[i] ]

return read

}

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

Лістинг 114 Реалізація методів кодування мю-типу (продовження)

AudioByte MuLawEncode(AudioSample s) {

unsigned char sign = (s <0)? 0:0 x80; / / Записуємо знак.

if (s <0) s =-s; / / Робимо вибірку

/ / Позитивною

signed long adjusted = static_cast&ltlong&gt(s) &lt&lt (16sizeof(AudioSample)*8)

adjusted += 128L+4L

if (adjusted &gt 32767) adjusted = 32767

unsigned char exponent = numBits[(adjusted&gt&gt7)&amp0xFF] 1 unsigned char mantissa = (adjusted &gt&gt (exponent + 3)) &amp 0xF return ~(sign | (exponent &lt&lt 4) | mantissa)

}

Аналогічним чином працює і декодер Старший біт використовується для запису знака, три наступних для визначення, наскільки треба зрушити 4 молодших біта

Лістинг 114 Реалізація методів кодування мю-типу (продовження)

AudioSample MuLawDecode(AudioByte ulaw) {

ulaw = ~ulaw

unsigned char exponent = (ulaw &gt&gt 4) &amp 0x7

unsigned char mantissa = (ulaw &amp 0xF) + 16

unsigned long adjusted = (mantissa &lt&lt (exponent + 3))1284

return (ulaw &amp 0x80) adjusted : adjusted

}

Якщо ви добре розбираєтеся в форматах арифметики з плаваючою точкою, ви повинні помітити, що запропонований варіант запису дуже сильно нагадує формат запису 8-бітного числа з плаваючою точкою: один біт для знаку, три для експоненти і чотири для запису мантиси Зверніть увагу, що подібно до більшості форматів з плаваючою точкою старший біт мантиси відкидається, і в методі MuLawDecode вам доводиться відновлювати його, додаючи 16 до мантисі

При вивченні даного алгоритму ви повинні звернути увагу на один момент, що вимагає додаткового обговорення Зауважимо, що в методі MuLawENcode проводиться зсув 16-бітного відліку ІКМ на 128, а потім на 4 перед рештою перетворенням B методі MuLawDecode ці значення аналогічним чином віднімаються після перетворення Якщо розглядати такі перетворення як апроксимацію логарифма, то число 128 використовується для обходу розривності основної функції Якщо ви подивитеся на даний алгоритм уважніше, ви також помітите, що використовуються взагалі тільки 13 старших біт

Додавання чотирьох округлює значення до найближчого, кратного восьми,

підвищуючи тим самим точність

Джерело: Кінтцель Т Керівництво програміста по роботі зі звуком = 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>

*

*