|
Born Dead
#0G
31 марта 2000 |
|
Coding своими руками - Алгоритм сжатия звука 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!
Другие статьи номера:
Похожие статьи:
В этот день... 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