Born Dead #0G
31 марта 2000
  Звук  

Coding своими руками - Алгоритм сжатия звука ADPCM.

<b>Coding своими руками</b> - Алгоритм сжатия звука ADPCM.
════════════════════════════════════════════════════════════════
ЇЄ╒▐╟░░╟▐╒ЄєЇCODING СВОИМИ РУКАМИ ЇєЄ╒▐╟░░╟▐╒ЄєЇ
════════════════════════════════════════════════════════════════

(c) MoNz7eR^Sa9e

   Итак,  ADPCM:  сжатие  с  потерями,  но  если  сжимать  16bit
оригинал (вся фишка в том, что чем качественней оригинал, имею в
виду   разрядность,   тем   качественней   полученный  архив)  и
использовать  4bit  для  архива,  то это звучит даже на PC очень
сильно (чуть  хуже  MP3),  а  если  2bit на выборку юзать, то на
спеке  с MCC методом тоже солидно звучит (я имею в виду выходной
сигнал 8-7bit!)

   Тема  такая,  за  основу  взят  простейший  дельта  паковщик,
разрядностью 1bit. (рис.1)

                ^       ,-. o
                |      ;  o\  o
                |     ; o   \   o
                |   ,'o     ::    o
                o-o-o--------(------o---------->
                |             \       o     _,o
                |              ~.       o_-~o
                |                ~-____-' o
                |
                            [рис.1]

   Он стремится догнать изменяющийся сигнал с помощью одинаковых
смещений по X. Типа

             если INсигнал > PACсигнал, то bit = 1, а
             если INсигнал < PACсигнал, то bit = 0.

   ADPCM  адаптирует  смещения  с  помощью  таблицы  и с помощью
умножения.  Не  буду  описывать  общий метод, объясню на примере
2bit'ного сжатия.

   В сжатом 2bit'ном виде хранится:

                   [  S  ]      [  k0  ]   ...
                 sign - знак   коэффициент
                 "+" или "-"    умножения

   При распаковке получаем формулу:

          X = X + (-1) * S * (TAB(i) * k0 + TAB(i)/2)

(при большей разрядности
          ... + k1*TAB(i)/2 + k2*TAB(i)/4 + TAB(i)/8
и т.д.)

   Причём  если  2bit = 0 или 2, то i = i - 1, если  1 или 3, то
i = i + 2. (i - смещение  по табличке приращений по X.)  В итоге
пакуемый сигнал быстро адаптируется под оригинал. (см. рис.2)

                ^
                |        o
            max + - - - - -o- - - - - - - - - -
                |      o,-.
                |      ;   \ °
                |     °     \
                |   o'      :: o
                o-°----------(---------------o->
                |             \            o_,-
                |              ~.o       o-~
                |                ~-____-'
                |                  o   °
                + - - - - - - - - - -o- - - - - и т.д.

                            [рис.2]

   Есть  у  меня  оригинал  таблички  приращений,  выдранный  из
PC'шного  Encoder'а,  так, что файлы, спакованные с этой таблой,
играются  где  угодно (если  заголовок правильный у файла). Одна
проблема  на  спеке,  подобрать  амплитуду  сигнала  так,  чтобы
быстрый распаковщик (есть исходник, играет по MCC примерно 20кГц
с распаковкой из 2bit!!!) после сложений не выпрыгнул за пределы
(не  перешёл  через ноль и не сменил знак), а так метод - просто
рульный!

   В  итоге  для паковки каждую выборку (а точнее, разницу между
выборками  из  оригинала  и  из  компаратора - из  запакованного
сигнала)  анализируют  так:  в  начале сохраняем первое значение
оригинала [pac(0) = in(0)]. Потом:

let bit1 = 0 : let bit0 = 0 : let d(n) = in(n) - pac(n)
if d(n) < 0 then bit1 = 1 : let d(n) = ABS d(n)
if d(n) > tabl(i) then bit0 = 1 : let i = i + 2 else i = i - 1

(для  многобитного  сжатия  вместо -1  и +2 используем таблицу с
кучей значений)

if i < 0 then i = 0
pac(n+1) = pac(n) + (-1)*bit1 + bit0*tabl(i) + tabl(i)/2

   и всё... весь принцип, конечно, без tabl(i) это не сработает,
кстати для эксперимента можете сгенерить её сами, начинается она
с   числа   7,  далее   Xn+1 = Xn * 1,1   (получается   примерно
похоже).  Почему  сразу  с  такого  большого  числа?  Потому что
сжимать  надо  как  минимум  16it сигнал, или пересэмплированный
8bit'ный  сигнал  с  отфильтрованной частотой среза (1/2 частоты
дискретизации).

   А для распаковки имеем:      
                                                                
OUT(0) = сохр. первая выборка сигнала                           
OUT(n+1) = OUT(n) + (-1)*bit1 + bit0*tabl(i) + tabl(i)/2        
if bit0 = 1 then i = i + 2 else i = i - 1              (i>=0!!!)
                                                                
   Вроде, совсем всё...                                         
                                                                
   Кстати,  ADPCM  расшифровывается  как  Adaptive  Differencial
Pulse Code Modulation!     



Другие статьи номера:

666 байт От Редакции - Об оболочке.

Coding своими руками - Алгоритм сжатия звука ADPCM.

Coding своими руками - Супер-быстрый MCC player.

Hints - Трюк с отгрузками в Чёрном Вороне.

Новости - Дата релиза Walker, новое издание из Самары.

Обзор софта - JPEG viewer v0.2, Minimal Tracker.

Партийная зона - Обзор демок с CC'000 Invitation Intro Compo.

Под звуком "ПИ" - Почему известные люди уходят со сцены?

Посмеёмся - Лебединая песня нефтяника: Рецензия на кинофильм "Армагеддон".

Реклама - Реклама и объявления.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Хит-парад - 10-ка лучших игр.
Юмор - Распределение вредоносных программ.
Guest texts - X-mus presents: Математические софизмы.
TOP TEN - Десяточка лучших игр.
Ассемблер - Флаги, операции сравнения и переноса.

В этот день...   1 января

SibNews #08, Woot! #01, Spectrum Magazine #01, ACNews #25, Psychoz #14, ACNews #14, Last 128 #08, Last 128 #06, Last 128 #05, Last 128 #04, Last 128 #03, Last 128 #02, Last 128 #09, Last 128 #3.5, Last 128 #8.025, Sinclair Club #05, Last 128 #M!R 01, Fantadrom #01, Buzz #20, Last 128 #01, DonNews #13, Nicron #120, Promised Land #01, Inferno #01, Marazm #25, Ultimathum #01, Marazm #21, Hooy Mag #02, KrNews #11, Marazm #22, Marazm #23, ZX Football 2000 #01, Codemania #01, Always #03, Bugs #02, IzhNews #08, Virtual Worlds #01, Listok #04, Scenergy #02, Flash Info #18, Marazm #16, Marazm #17, Zed #01, Balagan #02, ZX Format #08, ZX Power #03, Shock #01, Impulse #02, Deja Vu #03, ZX Club #08, ZX Club #06, Numberology #01, Marazm #13, Marazm #12, Marazm #14, Gorodok #02, Zodiac #01, Marazm #15, Deja Vu #07, Marazm #11, Deja Vu #07, Playboy #03, Crazy News #2, Crazy News #4, ZX Light #01, Crazy News #5, Playboy #02, ZX News #03, ZX Review #1-2, Read Me #02, Crazy News #3, Nicron #13, Read Me #01, Public Spirit #01, Faultless #06, Faultless #05, ZX Software #01, Stump #04, Speccy #07, Возраждение #0, Speccy #03, On-Line #17, Scene+ #01, Welcome Press #01, ZX Konig #04, Adventurer #01, Faultless #05, Faultless #04, Di Halt #01, Faultless #01, Playboy #01, Crazy News #1, Faultless #03, Pioneer #03, Sinclair Town #02, ZX Magazine #01, Eldorado #01, ZX Magazine #02, Spectron #01, ZX News #01, ZX Konig #02, 200 #W, Welcome Press #00, Dune #07, Subliminal Extacy #01, Subliminal Extacy #02, ZX Konig #01, Subliminal Extacy #00, Muchomor #01, Spectrofon #01, ZX Revija #02, Outlet #01, Outlet #1-3