-- $Id: wc-streams-codec.adb,v 1.2 2005/02/11 02:59:38 ken Exp $ -- -- (c) Warren W. Gay VE3WWG ve3wwg@home.com, ve3wwg@yahoo.com -- -- Protected under the GNU GPL License with Ada.Streams, Ada.IO_Exceptions; use Ada.Streams, Ada.IO_Exceptions; with WC.Streams.Endian; with WC.CInts; use WC.Streams.Endian; use WC.CInts; package body WC.Streams.Codec is CVSID: constant String := "$Header: /home/cvsroot/bush/src/ADAVOX-0.51/wc/wc-streams-codec.adb,v 1.2 2005/02/11 02:59:38 ken Exp $"; pragma Optimize(Time); -------------------------------------------------- -- IMPORTANT NOTE : The MPEG 1 Layer 3 (MP3) -- support is planned for, but not complete here. -- I repeat: MP3 support is NOT YET SUPPORTED. -------------------------------------------------- -- MPEG 1 Layer 3 : -------------------------------------------------- -- This CODEC is an Ada95 Adaptation of the mpg123 library code by : -- Michael Hipp (email: hippm@informatik.uni-tuebingen.de) -- Oliver Fromme -- Which used code or ideas from: -- MPEG Software Simulation Group: reference decoder package -- Tobias Bading: idea for DCT64 in subband synthesis from maplay package -- Jeff Tsay and Mikko Tommila: MDCT36 from maplay package -- Philipp Knirsch : DCT36/manual unroll idea -- Thomas Woerner <..> (SGI Audio) -- Damien Clermonte <..> (HP-UX audio fixes) -- Niclas Lindstrom : OS2 port -- Stefan Bieschewski : Pentium optimizations, decode_i586.s -- Martin Denn : NAS port -- Niklas Beisert MPEG 2.5 tables -- and : NetBSD -- Kevin Brintnall BSD patch -- Tony Million: win32 port -- Steven Tiger Lang: advanced shuffle -- Henrik P Johnson: HTTP auth patch -- Eric B. Mitchell: esd port -- Ryan R. Prosser esd port for Solaris -- Daniel Kobras : lot of (DK)-bugfixes -- and more .... -------------------------------------------------- procedure Pump_MPEG1L3(In_Str, Out_Str : Audio_Stream) is type Real is new float digits 6; type Real_Array is array(Integer range <>) of Real; type Integer_Array is array(Integer range <>) of Integer; -- These tables are derived from the tabinit.c code : Cos_64 : constant Real_Array(0..15) := ( +5.00602998235196295208435796064705414E-01, +5.05470959897543639031524537186257362E-01, +5.15447309922624556720142929844286073E-01, +5.31042591089784158753066278801924227E-01, +5.53103896034444523772781454606928264E-01, +5.82934968206133840922748140522813287E-01, +6.22504123035664790541347107799552418E-01, +6.74808341455005732643923632707583238E-01, +7.44536271002298527998865956822882595E-01, +8.39349645415526863351761421849772660E-01, +9.72568237861960817271147344831305759E-01, +1.16943993343288467725345908254652727E+00, +1.48416461631416627536816932320107298E+00, +2.05778100995341077148435837695927830E+00, +3.40760841846871887221744057416827900E+00, +1.01900081235480336134049950125302075E+01 ); Cos_32 : constant Real_Array(0..7) := ( +5.02419286188155684051356852926062402E-01, +5.22498614939688902757825017530990408E-01, +5.66944034816357690946455466507458709E-01, +6.46821783359990102322319843741738055E-01, +7.88154623451250237675062143560822392E-01, +1.06067768599034711126012642257165908E+00, +1.72244709823833414485353549006063645E+00, +5.10114861868915510628025300476906523E+00 ); Cos_16 : constant Real_Array(0..3) := ( +5.09795579104159178574461053212729666E-01, +6.01344886935045281565331842799082551E-01, +8.99976223136415601070500075442382126E-01, +2.56291544774150534453417693558918700E+00 ); Cos_8 : constant Real_Array(0..1) := ( +5.41196100146196994759399678809330680E-01, +1.30656296487637630396403537469396383E+00 ); Cos_4 : constant Real := +7.07106781186547476080687252286693933E-01; Dec_Win : constant Real_Array(0..543) := ( -0.00000000000000000000000000000000000E+00, +1.44995574951171875000000000000000000E+01, -1.06496749877929687500000000000000000E+02, -- 2 +2.29492996215820312500000000000000000E+02, -1.01846891784667968750000000000000000E+03, +2.57642137145996093750000000000000000E+03, -- 5 -3.28689968872070312500000000000000000E+03, +1.87439279632568359375000000000000000E+04, -3.75178550109863281250000000000000000E+04, -- 8 -1.87439279632568359375000000000000000E+04, -3.28689968872070312500000000000000000E+03, -2.57642137145996093750000000000000000E+03, -- 11 -1.01846891784667968750000000000000000E+03, -2.29492996215820312500000000000000000E+02, -1.06496749877929687500000000000000000E+02, -- 14 -1.44995574951171875000000000000000000E+01, -0.00000000000000000000000000000000000E+00, +1.44995574951171875000000000000000000E+01, -- 17 -1.06496749877929687500000000000000000E+02, +2.29492996215820312500000000000000000E+02, -1.01846891784667968750000000000000000E+03, -- 20 +2.57642137145996093750000000000000000E+03, -3.28689968872070312500000000000000000E+03, +1.87439279632568359375000000000000000E+04, -- 23 -3.75178550109863281250000000000000000E+04, -1.87439279632568359375000000000000000E+04, -3.28689968872070312500000000000000000E+03, -- 26 -2.57642137145996093750000000000000000E+03, -1.01846891784667968750000000000000000E+03, -2.29492996215820312500000000000000000E+02, -- 29 -1.06496749877929687500000000000000000E+02, -1.44995574951171875000000000000000000E+01, +4.99984741210937500000000000000000000E-01, -- 32 +1.54995269775390625000000000000000000E+01, -1.08996673583984375000000000000000000E+02, +2.59492080688476562500000000000000000E+02, -- 35 -9.99969482421875000000000000000000000E+02, +2.75841581726074218750000000000000000E+03, -2.97940907287597656250000000000000000E+03, -- 38 +1.96673997802734375000000000000000000E+04, -3.74948557128906250000000000000000000E+04, -1.78194561767578125000000000000000000E+04, -- 41 -3.56689114379882812500000000000000000E+03, -2.39392694091796875000000000000000000E+03, -1.03146852111816406250000000000000000E+03, -- 44 -2.00493881225585937500000000000000000E+02, -1.03996826171875000000000000000000000E+02, -1.29996032714843750000000000000000000E+01, -- 47 +4.99984741210937500000000000000000000E-01, +1.54995269775390625000000000000000000E+01, -1.08996673583984375000000000000000000E+02, -- 50 +2.59492080688476562500000000000000000E+02, -9.99969482421875000000000000000000000E+02, +2.75841581726074218750000000000000000E+03, -- 53 -2.97940907287597656250000000000000000E+03, +1.96673997802734375000000000000000000E+04, -3.74948557128906250000000000000000000E+04, -- 56 -1.78194561767578125000000000000000000E+04, -3.56689114379882812500000000000000000E+03, -2.39392694091796875000000000000000000E+03, -- 59 -1.03146852111816406250000000000000000E+03, -2.00493881225585937500000000000000000E+02, -1.03996826171875000000000000000000000E+02, -- 62 -1.29996032714843750000000000000000000E+01, +4.99984741210937500000000000000000000E-01, +1.74994659423828125000000000000000000E+01, -- 65 -1.10996612548828125000000000000000000E+02, +2.90491134643554687500000000000000000E+02, -9.75970214843750000000000000000000000E+02, -- 68 +2.93941029357910156250000000000000000E+03, -2.64391931152343750000000000000000000E+03, +2.05873717041015625000000000000000000E+04, -- 71 -3.74268577880859375000000000000000000E+04, -1.68949843902587890625000000000000000E+04, -3.81988342285156250000000000000000000E+03, -- 74 -2.21243247985839843750000000000000000E+03, -1.03996826171875000000000000000000000E+03, -1.73494705200195312500000000000000000E+02, -- 77 -1.00996917724609375000000000000000000E+02, -1.19996337890625000000000000000000000E+01, +4.99984741210937500000000000000000000E-01, -- 80 +1.74994659423828125000000000000000000E+01, -1.10996612548828125000000000000000000E+02, +2.90491134643554687500000000000000000E+02, -- 83 -9.75970214843750000000000000000000000E+02, +2.93941029357910156250000000000000000E+03, -2.64391931152343750000000000000000000E+03, -- 86 +2.05873717041015625000000000000000000E+04, -3.74268577880859375000000000000000000E+04, -1.68949843902587890625000000000000000E+04, -- 89 -3.81988342285156250000000000000000000E+03, -2.21243247985839843750000000000000000E+03, -1.03996826171875000000000000000000000E+03, -- 92 -1.73494705200195312500000000000000000E+02, -1.00996917724609375000000000000000000E+02, -1.19996337890625000000000000000000000E+01, -- 95 +4.99984741210937500000000000000000000E-01, +1.89994201660156250000000000000000000E+01, -1.12496566772460937500000000000000000E+02, -- 98 +3.22490158081054687500000000000000000E+02, -9.46471115112304687500000000000000000E+02, +3.11840483093261718750000000000000000E+03, -- 101 -2.28043040466308593750000000000000000E+03, +2.15023437805175781250000000000000000E+04, -3.73138612365722656250000000000000000E+04, -- 104 -1.59730125274658203125000000000000000E+04, -4.04587652587890625000000000000000000E+03, -2.03143800354003906250000000000000000E+03, -- 107 -1.04346815490722656250000000000000000E+03, -1.46995513916015625000000000000000000E+02, -9.79970092773437500000000000000000000E+01, -- 110 -1.04996795654296875000000000000000000E+01, +4.99984741210937500000000000000000000E-01, +1.89994201660156250000000000000000000E+01, -- 113 -1.12496566772460937500000000000000000E+02, +3.22490158081054687500000000000000000E+02, -9.46471115112304687500000000000000000E+02, -- 116 +3.11840483093261718750000000000000000E+03, -2.28043040466308593750000000000000000E+03, +2.15023437805175781250000000000000000E+04, -- 119 -3.73138612365722656250000000000000000E+04, -1.59730125274658203125000000000000000E+04, -4.04587652587890625000000000000000000E+03, -- 122 -2.03143800354003906250000000000000000E+03, -1.04346815490722656250000000000000000E+03, -1.46995513916015625000000000000000000E+02, -- 125 -9.79970092773437500000000000000000000E+01, -1.04996795654296875000000000000000000E+01, +4.99984741210937500000000000000000000E-01, -- 128 +2.04993743896484375000000000000000000E+01, -1.13496536254882812500000000000000000E+02, +3.55489151000976562500000000000000000E+02, -- 131 -9.10972198486328125000000000000000000E+02, +3.29439945983886718750000000000000000E+03, -1.88794238281250000000000000000000000E+03, -- 134 +2.24098160858154296875000000000000000E+04, -3.71553660736083984375000000000000000E+04, -1.50555405273437500000000000000000000E+04, -- 137 -4.24587042236328125000000000000000000E+03, -1.85244346618652343750000000000000000E+03, -1.04246818542480468750000000000000000E+03, -- 140 -1.21996276855468750000000000000000000E+02, -9.49971008300781250000000000000000000E+01, -9.49971008300781250000000000000000000E+00, -- 143 +4.99984741210937500000000000000000000E-01, +2.04993743896484375000000000000000000E+01, -1.13496536254882812500000000000000000E+02, -- 146 +3.55489151000976562500000000000000000E+02, -9.10972198486328125000000000000000000E+02, +3.29439945983886718750000000000000000E+03, -- 149 -1.88794238281250000000000000000000000E+03, +2.24098160858154296875000000000000000E+04, -3.71553660736083984375000000000000000E+04, -- 152 -1.50555405273437500000000000000000000E+04, -4.24587042236328125000000000000000000E+03, -1.85244346618652343750000000000000000E+03, -- 155 -1.04246818542480468750000000000000000E+03, -1.21996276855468750000000000000000000E+02, -9.49971008300781250000000000000000000E+01, -- 158 -9.49971008300781250000000000000000000E+00, +4.99984741210937500000000000000000000E-01, +2.24993133544921875000000000000000000E+01, -- 161 -1.13996520996093750000000000000000000E+02, +3.89488113403320312500000000000000000E+02, -8.69473464965820312500000000000000000E+02, -- 164 +3.46739418029785156250000000000000000E+03, -1.46745521545410156250000000000000000E+03, +2.33077886810302734375000000000000000E+04, -- 167 -3.69528722534179687500000000000000000E+04, -1.41440683441162109375000000000000000E+04, -4.41986511230468750000000000000000000E+03, -- 170 -1.67544886779785156250000000000000000E+03, -1.03746833801269531250000000000000000E+03, -9.84969940185546875000000000000000000E+01, -- 173 -9.14972076416015625000000000000000000E+01, -8.49974060058593750000000000000000000E+00, +4.99984741210937500000000000000000000E-01, -- 176 +2.24993133544921875000000000000000000E+01, -1.13996520996093750000000000000000000E+02, +3.89488113403320312500000000000000000E+02, -- 179 -8.69473464965820312500000000000000000E+02, +3.46739418029785156250000000000000000E+03, -1.46745521545410156250000000000000000E+03, -- 182 +2.33077886810302734375000000000000000E+04, -3.69528722534179687500000000000000000E+04, -1.41440683441162109375000000000000000E+04, -- 185 -4.41986511230468750000000000000000000E+03, -1.67544886779785156250000000000000000E+03, -1.03746833801269531250000000000000000E+03, -- 188 -9.84969940185546875000000000000000000E+01, -9.14972076416015625000000000000000000E+01, -8.49974060058593750000000000000000000E+00, -- 191 +4.99984741210937500000000000000000000E-01, +2.44992523193359375000000000000000000E+01, -1.13996520996093750000000000000000000E+02, -- 194 +4.23987060546875000000000000000000000E+02, -8.21974914550781250000000000000000000E+02, +3.63538905334472656250000000000000000E+03, -- 197 -1.01846891784667968750000000000000000E+03, +2.41942616271972656250000000000000000E+04, -3.67063797760009765625000000000000000E+04, -- 200 -1.32405959167480468750000000000000000E+04, -4.56936054992675781250000000000000000E+03, -1.50195416259765625000000000000000000E+03, -- 203 -1.02846861267089843750000000000000000E+03, -7.64976654052734375000000000000000000E+01, -8.79973144531250000000000000000000000E+01, -- 206 -7.99975585937500000000000000000000000E+00, +4.99984741210937500000000000000000000E-01, +2.44992523193359375000000000000000000E+01, -- 209 -1.13996520996093750000000000000000000E+02, +4.23987060546875000000000000000000000E+02, -8.21974914550781250000000000000000000E+02, -- 212 +3.63538905334472656250000000000000000E+03, -1.01846891784667968750000000000000000E+03, +2.41942616271972656250000000000000000E+04, -- 215 -3.67063797760009765625000000000000000E+04, -1.32405959167480468750000000000000000E+04, -4.56936054992675781250000000000000000E+03, -- 218 -1.50195416259765625000000000000000000E+03, -1.02846861267089843750000000000000000E+03, -7.64976654052734375000000000000000000E+01, -- 221 -8.79973144531250000000000000000000000E+01, -7.99975585937500000000000000000000000E+00, +9.99969482421875000000000000000000000E-01, -- 224 +2.64991912841796875000000000000000000E+01, -1.13496536254882812500000000000000000E+02, +4.59485977172851562500000000000000000E+02, -- 227 -7.67476577758789062500000000000000000E+02, +3.79838407897949218750000000000000000E+03, -5.40983489990234375000000000000000000E+02, -- 230 +2.50677349700927734375000000000000000E+04, -3.64163886260986328125000000000000000E+04, -1.23466231994628906250000000000000000E+04, -- 233 -4.69435673522949218750000000000000000E+03, -1.33145936584472656250000000000000000E+03, -1.01596899414062500000000000000000000E+03, -- 236 -5.54983062744140625000000000000000000E+01, -8.44974212646484375000000000000000000E+01, -6.99978637695312500000000000000000000E+00, -- 239 +9.99969482421875000000000000000000000E-01, +2.64991912841796875000000000000000000E+01, -1.13496536254882812500000000000000000E+02, -- 242 +4.59485977172851562500000000000000000E+02, -7.67476577758789062500000000000000000E+02, +3.79838407897949218750000000000000000E+03, -- 245 -5.40983489990234375000000000000000000E+02, +2.50677349700927734375000000000000000E+04, -3.64163886260986328125000000000000000E+04, -- 248 -1.23466231994628906250000000000000000E+04, -4.69435673522949218750000000000000000E+03, -1.33145936584472656250000000000000000E+03, -- 251 -1.01596899414062500000000000000000000E+03, -5.54983062744140625000000000000000000E+01, -8.44974212646484375000000000000000000E+01, -- 254 -6.99978637695312500000000000000000000E+00, +9.99969482421875000000000000000000000E-01, +2.89991149902343750000000000000000000E+01, -- 257 -1.11996582031250000000000000000000000E+02, +4.95484878540039062500000000000000000E+02, -7.06978424072265625000000000000000000E+02, -- 260 +3.95487930297851562500000000000000000E+03, -3.49989318847656250000000000000000000E+01, +2.59257087860107421875000000000000000E+04, -- 263 -3.60833987884521484375000000000000000E+04, -1.14641501312255859375000000000000000E+04, -4.79585363769531250000000000000000000E+03, -- 266 -1.16496444702148437500000000000000000E+03, -1.00046946716308593750000000000000000E+03, -3.59989013671875000000000000000000000E+01, -- 269 -8.04975433349609375000000000000000000E+01, -6.49980163574218750000000000000000000E+00, +9.99969482421875000000000000000000000E-01, -- 272 +2.89991149902343750000000000000000000E+01, -1.11996582031250000000000000000000000E+02, +4.95484878540039062500000000000000000E+02, -- 275 -7.06978424072265625000000000000000000E+02, +3.95487930297851562500000000000000000E+03, -3.49989318847656250000000000000000000E+01, -- 278 +2.59257087860107421875000000000000000E+04, -3.60833987884521484375000000000000000E+04, -1.14641501312255859375000000000000000E+04, -- 281 -4.79585363769531250000000000000000000E+03, -1.16496444702148437500000000000000000E+03, -1.00046946716308593750000000000000000E+03, -- 284 -3.59989013671875000000000000000000000E+01, -8.04975433349609375000000000000000000E+01, -6.49980163574218750000000000000000000E+00, -- 287 +9.99969482421875000000000000000000000E-01, +3.14990386962890625000000000000000000E+01, -1.10496627807617187500000000000000000E+02, -- 290 +5.31983764648437500000000000000000000E+02, -6.39980468750000000000000000000000000E+02, +4.10437474060058593750000000000000000E+03, -- 293 +4.98984771728515625000000000000000000E+02, +2.67661831359863281250000000000000000E+04, -3.57089102172851562500000000000000000E+04, -- 296 -1.05941766815185546875000000000000000E+04, -4.87485122680664062500000000000000000E+03, -1.00296939086914062500000000000000000E+03, -- 299 -9.80970062255859375000000000000000000E+02, -1.79994506835937500000000000000000000E+01, -7.69976501464843750000000000000000000E+01, -- 302 -5.49983215332031250000000000000000000E+00, +9.99969482421875000000000000000000000E-01, +3.14990386962890625000000000000000000E+01, -- 305 -1.10496627807617187500000000000000000E+02, +5.31983764648437500000000000000000000E+02, -6.39980468750000000000000000000000000E+02, -- 308 +4.10437474060058593750000000000000000E+03, +4.98984771728515625000000000000000000E+02, +2.67661831359863281250000000000000000E+04, -- 311 -3.57089102172851562500000000000000000E+04, -1.05941766815185546875000000000000000E+04, -4.87485122680664062500000000000000000E+03, -- 314 -1.00296939086914062500000000000000000E+03, -9.80970062255859375000000000000000000E+02, -1.79994506835937500000000000000000000E+01, -- 317 -7.69976501464843750000000000000000000E+01, -5.49983215332031250000000000000000000E+00, +9.99969482421875000000000000000000000E-01, -- 320 +3.39989624023437500000000000000000000E+01, -1.07496719360351562500000000000000000E+02, +5.68482650756835937500000000000000000E+02, -- 323 -5.65482742309570312500000000000000000E+02, +4.24537043762207031250000000000000000E+03, +1.06096762084960937500000000000000000E+03, -- 326 +2.75881580505371093750000000000000000E+04, -3.52939228820800781250000000000000000E+04, -9.73870278930664062500000000000000000E+03, -- 329 -4.93134950256347656250000000000000000E+03, -8.45974182128906250000000000000000000E+02, -9.59470718383789062500000000000000000E+02, -- 332 -9.99969482421875000000000000000000000E-01, -7.34977569580078125000000000000000000E+01, -4.99984741210937500000000000000000000E+00, -- 335 +9.99969482421875000000000000000000000E-01, +3.39989624023437500000000000000000000E+01, -1.07496719360351562500000000000000000E+02, -- 338 +5.68482650756835937500000000000000000E+02, -5.65482742309570312500000000000000000E+02, +4.24537043762207031250000000000000000E+03, -- 341 +1.06096762084960937500000000000000000E+03, +2.75881580505371093750000000000000000E+04, -3.52939228820800781250000000000000000E+04, -- 344 -9.73870278930664062500000000000000000E+03, -4.93134950256347656250000000000000000E+03, -8.45974182128906250000000000000000000E+02, -- 347 -9.59470718383789062500000000000000000E+02, -9.99969482421875000000000000000000000E-01, -7.34977569580078125000000000000000000E+01, -- 350 -4.99984741210937500000000000000000000E+00, +1.49995422363281250000000000000000000E+00, +3.64988861083984375000000000000000000E+01, -- 353 -1.03996826171875000000000000000000000E+02, +6.04981536865234375000000000000000000E+02, -4.84985198974609375000000000000000000E+02, -- 356 +4.37736640930175781250000000000000000E+03, +1.64994964599609375000000000000000000E+03, +2.83881336364746093750000000000000000E+04, -- 359 -3.48384367828369140625000000000000000E+04, -8.89922840881347656250000000000000000E+03, -4.96734840393066406250000000000000000E+03, -- 362 -6.93978820800781250000000000000000000E+02, -9.34971466064453125000000000000000000E+02, +1.44995574951171875000000000000000000E+01, -- 365 -6.94978790283203125000000000000000000E+01, -4.49986267089843750000000000000000000E+00, +1.49995422363281250000000000000000000E+00, -- 368 +3.64988861083984375000000000000000000E+01, -1.03996826171875000000000000000000000E+02, +6.04981536865234375000000000000000000E+02, -- 371 -4.84985198974609375000000000000000000E+02, +4.37736640930175781250000000000000000E+03, +1.64994964599609375000000000000000000E+03, -- 374 +2.83881336364746093750000000000000000E+04, -3.48384367828369140625000000000000000E+04, -8.89922840881347656250000000000000000E+03, -- 377 -4.96734840393066406250000000000000000E+03, -6.93978820800781250000000000000000000E+02, -9.34971466064453125000000000000000000E+02, -- 380 +1.44995574951171875000000000000000000E+01, -6.94978790283203125000000000000000000E+01, -4.49986267089843750000000000000000000E+00, -- 383 +1.49995422363281250000000000000000000E+00, +3.94987945556640625000000000000000000E+01, -9.99969482421875000000000000000000000E+01, -- 386 +6.41480422973632812500000000000000000E+02, -3.96987884521484375000000000000000000E+02, +4.49886270141601562500000000000000000E+03, -- 389 +2.26643083190917968750000000000000000E+03, +2.91656099090576171875000000000000000E+04, -3.43449518432617187500000000000000000E+04, -- 392 -8.07725349426269531250000000000000000E+03, -4.98284793090820312500000000000000000E+03, -5.47483291625976562500000000000000000E+02, -- 395 -9.08472274780273437500000000000000000E+02, +2.84991302490234375000000000000000000E+01, -6.59979858398437500000000000000000000E+01, -- 398 -3.99987792968750000000000000000000000E+00, +1.49995422363281250000000000000000000E+00, +3.94987945556640625000000000000000000E+01, -- 401 -9.99969482421875000000000000000000000E+01, +6.41480422973632812500000000000000000E+02, -3.96987884521484375000000000000000000E+02, -- 404 +4.49886270141601562500000000000000000E+03, +2.26643083190917968750000000000000000E+03, +2.91656099090576171875000000000000000E+04, -- 407 -3.43449518432617187500000000000000000E+04, -8.07725349426269531250000000000000000E+03, -4.98284793090820312500000000000000000E+03, -- 410 -5.47483291625976562500000000000000000E+02, -9.08472274780273437500000000000000000E+02, +2.84991302490234375000000000000000000E+01, -- 413 -6.59979858398437500000000000000000000E+01, -3.99987792968750000000000000000000000E+00, +1.99993896484375000000000000000000000E+00, -- 416 +4.24987030029296875000000000000000000E+01, -9.44971160888671875000000000000000000E+01, +6.77979309082031250000000000000000000E+02, -- 419 -3.02490768432617187500000000000000000E+02, +4.60935932922363281250000000000000000E+03, +2.90891122436523437500000000000000000E+03, -- 422 +2.99180869445800781250000000000000000E+04, -3.38134680633544921875000000000000000E+04, -7.27377801513671875000000000000000000E+03, -- 425 -4.97934803771972656250000000000000000E+03, -4.06987579345703125000000000000000000E+02, -8.79473159790039062500000000000000000E+02, -- 428 +4.14987335205078125000000000000000000E+01, -6.24980926513671875000000000000000000E+01, -3.49989318847656250000000000000000000E+00, -- 431 +1.99993896484375000000000000000000000E+00, +4.24987030029296875000000000000000000E+01, -9.44971160888671875000000000000000000E+01, -- 434 +6.77979309082031250000000000000000000E+02, -3.02490768432617187500000000000000000E+02, +4.60935932922363281250000000000000000E+03, -- 437 +2.90891122436523437500000000000000000E+03, +2.99180869445800781250000000000000000E+04, -3.38134680633544921875000000000000000E+04, -- 440 -7.27377801513671875000000000000000000E+03, -4.97934803771972656250000000000000000E+03, -4.06987579345703125000000000000000000E+02, -- 443 -8.79473159790039062500000000000000000E+02, +4.14987335205078125000000000000000000E+01, -6.24980926513671875000000000000000000E+01, -- 446 -3.49989318847656250000000000000000000E+00, +1.99993896484375000000000000000000000E+00, +4.54986114501953125000000000000000000E+01, -- 449 -8.84972991943359375000000000000000000E+01, +7.13978210449218750000000000000000000E+02, -2.00993865966796875000000000000000000E+02, -- 452 +4.70785632324218750000000000000000000E+03, +3.57689083862304687500000000000000000E+03, +3.06435648040771484375000000000000000E+04, -- 455 -3.32459853820800781250000000000000000E+04, -6.48980194091796875000000000000000000E+03, -4.95784869384765625000000000000000000E+03, -- 458 -2.72491683959960937500000000000000000E+02, -8.48974090576171875000000000000000000E+02, +5.29983825683593750000000000000000000E+01, -- 461 -5.84982147216796875000000000000000000E+01, -3.49989318847656250000000000000000000E+00, +1.99993896484375000000000000000000000E+00, -- 464 +4.54986114501953125000000000000000000E+01, -8.84972991943359375000000000000000000E+01, +7.13978210449218750000000000000000000E+02, -- 467 -2.00993865966796875000000000000000000E+02, +4.70785632324218750000000000000000000E+03, +3.57689083862304687500000000000000000E+03, -- 470 +3.06435648040771484375000000000000000E+04, -3.32459853820800781250000000000000000E+04, -6.48980194091796875000000000000000000E+03, -- 473 -4.95784869384765625000000000000000000E+03, -2.72491683959960937500000000000000000E+02, -8.48974090576171875000000000000000000E+02, -- 476 +5.29983825683593750000000000000000000E+01, -5.84982147216796875000000000000000000E+01, -3.49989318847656250000000000000000000E+00, -- 479 +2.49992370605468750000000000000000000E+00, +4.84985198974609375000000000000000000E+01, -8.14975128173828125000000000000000000E+01, -- 482 +7.48977142333984375000000000000000000E+02, -9.24971771240234375000000000000000000E+01, +4.79235374450683593750000000000000000E+03, -- 485 +4.26986968994140625000000000000000000E+03, +3.13410435180664062500000000000000000E+04, -3.26440037536621093750000000000000000E+04, -- 488 -5.72732521057128906250000000000000000E+03, -4.91884988403320312500000000000000000E+03, -1.43995605468750000000000000000000000E+02, -- 491 -8.16975067138671875000000000000000000E+02, +6.34980621337890625000000000000000000E+01, -5.54983062744140625000000000000000000E+01, -- 494 -2.99990844726562500000000000000000000E+00, +2.49992370605468750000000000000000000E+00, +4.84985198974609375000000000000000000E+01, -- 497 -8.14975128173828125000000000000000000E+01, +7.48977142333984375000000000000000000E+02, -9.24971771240234375000000000000000000E+01, -- 500 +4.79235374450683593750000000000000000E+03, +4.26986968994140625000000000000000000E+03, +3.13410435180664062500000000000000000E+04, -- 503 -3.26440037536621093750000000000000000E+04, -5.72732521057128906250000000000000000E+03, -4.91884988403320312500000000000000000E+03, -- 506 -1.43995605468750000000000000000000000E+02, -8.16975067138671875000000000000000000E+02, +6.34980621337890625000000000000000000E+01, -- 509 -5.54983062744140625000000000000000000E+01, -2.99990844726562500000000000000000000E+00, +2.49992370605468750000000000000000000E+00, -- 512 +5.19984130859375000000000000000000000E+01, -7.29977722167968750000000000000000000E+01, +7.83476089477539062500000000000000000E+02, -- 515 +2.24993133544921875000000000000000000E+01, +4.86335157775878906250000000000000000E+03, +4.98734779357910156250000000000000000E+03, -- 518 +3.20085231475830078125000000000000000E+04, -3.20085231475830078125000000000000000E+04, -4.98734779357910156250000000000000000E+03, -- 521 -4.86335157775878906250000000000000000E+03, -2.24993133544921875000000000000000000E+01, -7.83476089477539062500000000000000000E+02, -- 524 +7.29977722167968750000000000000000000E+01, -5.19984130859375000000000000000000000E+01, -2.49992370605468750000000000000000000E+00, -- 527 +2.49992370605468750000000000000000000E+00, +5.19984130859375000000000000000000000E+01, -7.29977722167968750000000000000000000E+01, -- 530 +7.83476089477539062500000000000000000E+02, +2.24993133544921875000000000000000000E+01, +4.86335157775878906250000000000000000E+03, -- 533 +4.98734779357910156250000000000000000E+03, +3.20085231475830078125000000000000000E+04, -3.20085231475830078125000000000000000E+04, -- 536 -4.98734779357910156250000000000000000E+03, -4.86335157775878906250000000000000000E+03, -2.24993133544921875000000000000000000E+01, -- 539 -7.83476089477539062500000000000000000E+02, +7.29977722167968750000000000000000000E+01, -5.19984130859375000000000000000000000E+01, -- 542 -2.49992370605468750000000000000000000E+00 ); Int_Win_Base : constant Integer_Array(0..256) := ( 0, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -3, -3, -4, -4, -5, -5, -6, -- 17 -7, -7, -8, -9, -10, -11, -13, -14, -16, -17, -19, -21, -24, -26, -29, -31, -35, -38, -- 35 -41, -45, -49, -53, -58, -63, -68, -73, -79, -85, -91, -97, -104, -111, -117, -125, -132, -139, -- 53 -147, -154, -161, -169, -176, -183, -190, -196, -202, -208, -213, -218, -222, -225, -227, -228, -228, -227, -- 71 -224, -221, -215, -208, -200, -189, -177, -163, -146, -127, -106, -83, -57, -29, 2, 36, 72, 111, -- 89 153, 197, 244, 294, 347, 401, 459, 519, 581, 645, 711, 779, 848, 919, 991, 1064, 1137, 1210, -- 107 1283, 1356, 1428, 1498, 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962, 2001, 2032, 2057, 2075, 2085, 2087, -- 125 2080, 2063, 2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131, 970, 794, 605, 402, 185, -- 143 -45, -288, -545, -814, -1095, -1388, -1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788, -5153, -5517, -- 161 -5879, -6237, -6589, -6935, -7271, -7597, -7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838, -9916, -9959, -- 179 -9966, -9935, -9863, -9750, -9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134, -6574, -5959, -5288, -4561, -3776, -2935, -- 197 -2037, -1082, -70, 998, 2122, 3300, 4533, 5818, 7154, 8540, 9975, 11455, 12980, 14548, 16155, 17799, 19478, 21189, -- 215 22929, 24694, 26482, 28289, 30112, 31947, 33791, 35640, 37489, 39336, 41176, 43006, 44821, 46617, 48390, 50137, 51853, 53534, -- 233 55178, 56778, 58333, 59838, 61289, 62684, 64019, 65290, 66494, 67629, 68692, 69679, 70590, 71420, 72169, 72835, 73415, 73908, -- 251 74313, 74630, 74856, 74992, 75038 ); begin raise Unsupported_Format; end Pump_MPEG1L3; -------------------------------------------------- -- IMA/DVI ADPCM Algorithm : -------------------------------------------------- -- NOTE : -- This CODEC has been tested to work with -- monophonic 2,3,4 and 5 bit compressed files, -- produced with CoolEdit-2000. However, when -- sterio files are produced by CoolEdit-2000, -- only the 4-bit sample files play correctly -- here. While CoolEdit-2000 is able to play its -- own sterio files, I strongly suspect that the -- created files are incorrect. It is suspected -- that CoolEdit incorrectly interleaves the -- 2,3 and 5-bit samples for non-monophonic files. -------------------------------------------------- procedure Pump_IMA_ADPCM(In_Str, Out_Str : Audio_Stream) is type Audio_Byte_Array is array(Audio_U16 range <>) of Audio_Byte; type Audio_I16_Array is array(Audio_U16 range <>) of Audio_I16; type Samples_Out_Array is array(Audio_U16 range <>,Audio_U16 range <>) of Audio_I16; Bits_Per_Sample : Audio_U16; -- Bits per IMA ADPCM Sample Block_Size : Audio_U16; -- Size of the samples block Samples_Per_Block : Audio_U16; -- Max # of samples per block N_Chan : Audio_U16 := Audio_U16( Channels(In_Str.all) ); type Hdr_Recd is record Samp_0 : Audio_I16; Step_Tbl_Index : Audio_Byte; Reserved : Audio_Byte; end record; type Hdr_Recd_Array is array(1..N_Chan) of Hdr_Recd; type IMA_Recd(Bytes : Audio_U16) is record Header : Hdr_Recd_Array; Samples : Audio_Byte_Array(1..Bytes); end record; Step_Table : constant array(0..Audio_I16(88)) of Audio_U16 := ( 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 ); function Step_Index(X : Audio_I16) return Audio_I16 is begin if X < Step_Table'First then return Step_Table'First; elsif X > Step_Table'Last then return Step_Table'Last; else return X; end if; end Step_Index; -- Index Tables : Idx_Tab2 : constant Audio_I16_Array(0..Audio_U16(3)) := ( -1, 2, -1, 2); Idx_Tab3 : constant Audio_I16_Array(0..Audio_U16(7)) := ( -1, -1, 1, 2, -1, -1, 1, 2 ); Idx_Tab4 : constant Audio_I16_Array(0..Audio_U16(15)) := ( -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 ); Idx_Tab5 : constant Audio_I16_Array(0..Audio_U16(31)) := (-1,-1,-1,-1,-1,-1,-1,-1,1,2,4,6,8,10,13,16,-1,-1,-1,-1,-1,-1,-1,-1,1,2,4,6,8,10,13,16); -- Bit size specific values : Index_Tab : constant array(2..Audio_U16(5)) of Audio_U16 := ( 3, 7, 15, 31 ); -- Upper bounds for idx_tab() Samps_Tab : constant array(2..Audio_U16(5)) of Audio_U16 := ( 32, 32, 8, 32 ); -- Samples per "data word" Bytes_Tab : constant array(2..Audio_U16(5)) of Audio_U16 := ( 8, 12, 4, 20 ); -- Bytes per "data word" Masks_Tab : constant array(2..Audio_U16(5)) of Audio_U16 := ( 3, 7, 15, 31 ); -- Bit mask for each bit size Signs_Tab : constant array(2..Audio_U16(5)) of Audio_Byte := ( 2, 4, 8, 16 ); -- Sign mask for each bit size begin Audio_U16'Read(In_Str,Block_Size); -- Determine the block size Audio_U16'Read(In_Str,Bits_Per_Sample); -- Determine bits / sample Audio_U16'Read(In_Str,Samples_Per_Block); -- Max # of samples per block declare Chan_Wd_Bytes : Audio_U16 := Bytes_Tab(Bits_Per_Sample) * N_Chan; -- # of bytes needed to satisfy all channels for 1 "data word" N_Samps : Audio_U16 := 0; -- # of samples in the current block Sign : Audio_Byte := Signs_Tab(Bits_Per_Sample); -- Sign bit mask Step_X : Audio_I16_Array(1..N_Chan); -- Step table index Idx_Tab : Audio_I16_Array(0..Index_Tab(Bits_Per_Sample)); -- index table Bytes_Avail : Audio_U16 := 0; -- Bytes available to read Sample_Bytes : Audio_U16 := 0; -- Bytes available for samples X : Audio_I16; -- Current Index value Samp_0 : Audio_I16; -- Prior sample A_Bits : Audio_U16 := 0; -- Bits held in Acc Mask : Audio_U16 := Masks_Tab(Bits_Per_Sample); -- Bit mask for sample delta Acc : Audio_U16 := 0; -- Bit accumulator Wd_Samps : Audio_U16 := Samps_Tab(Bits_Per_Sample); -- Samples / "data word" Samp_Delta : Audio_Byte := 0; -- Sample Delta Step : Audio_U16; -- Current step value Diff : Audio_I32 := 0; -- Computed difference Samp_X : Audio_I32 := 0; -- New Sample X begin case Bits_Per_Sample is when 2 => Idx_Tab := Idx_Tab2; -- 2 bit table when 3 => Idx_Tab := Idx_Tab3; -- 3 bit table when 4 => Idx_Tab := Idx_Tab4; -- 4 bit table when 5 => Idx_Tab := Idx_Tab5; -- 5 bit table when others => raise Program_Error; end case; loop Bytes_Avail := Audio_U16(In_Items(In_Str.all,1)); if Bytes_Avail > Block_Size then Bytes_Avail := Block_Size; end if; exit when Bytes_Avail <= 4 * N_Chan; -- Exit if we don't have enough for a header Sample_Bytes := Bytes_Avail - 4 * N_Chan; -- Compute the bytes available for samples exit when Sample_Bytes < 4; -- Exit when no sample bytes exist N_Samps := ((Bytes_Avail - (4 * N_Chan)) * 8) / ( Bits_Per_Sample * N_Chan ) + 1; if N_Samps > Samples_Per_Block then N_Samps := Samples_Per_Block; end if; declare BX : Audio_U16 := 1; -- Index into Block.Samples(BX) SX : Audio_U16 := 2; -- Sample Index (1st sample comes from header) Block : IMA_Recd(Sample_Bytes); -- IMA ADPCM Block Emit : Samples_Out_Array(1..N_Samps,1..N_Chan); begin IMA_Recd'Read(In_Str,Block); -- Read in the block -- Force bad data to not exceed array bounds for X in Block.Header'Range loop Emit(1,X) := Block.Header(X).Samp_0; -- First sample for channel X Step_X(X) := Step_Index( Audio_I16(Block.Header(X).Step_Tbl_Index) ); end loop; -- The remaining bytes is the data portion : loop exit when SX + 1 > N_Samps; -- Exit when all samples have been processed -- Check if this is a short "last block" : if Sample_Bytes + 1 - BX < Chan_Wd_Bytes then for FX in SX..Emit'Last(1) loop -- Fill all remaining samples.. for Chx in Emit'Range(2) loop -- for all channels.. Emit(FX,Chx) := Block.Header(Chx).Samp_0; -- with the last generated sample end loop; end loop; exit; end if; for Chx in 1..N_Chan loop -- For all channels X := Step_X(Chx); -- Get Step_Table index for this channel Samp_0 := Block.Header(Chx).Samp_0; -- Previous sample A_Bits := 0; -- No sample bits in acc yet for PX in 1..Wd_Samps loop -- for all samples in a "data word" if A_Bits < Bits_Per_Sample then if A_Bits = 0 then Acc := Audio_U16( Block.Samples(BX) ); else Acc := Acc or Shift_Left( Audio_U16( Block.Samples(BX) ), Natural(A_Bits) ); end if; A_Bits := A_Bits + 8; BX := BX + 1; end if; Samp_Delta := Audio_Byte( Acc and Mask ); -- Extract a delta (n-bits) Acc := Shift_Right(Acc,Natural(Bits_Per_Sample)); -- Shift out used up delta bits A_Bits := A_Bits - Bits_Per_Sample; -- Now have fewer bits in Acc Step := Step_Table(X); -- Get current step value Diff := Audio_I32( Shift_Right(Step,Natural(Bits_Per_Sample-1)) ); for Z in 1..Bits_Per_Sample loop if ( Samp_Delta and Shift_Right(Audio_U8(Sign),Natural(Z)) ) /= 0 then Diff := Diff + Audio_I32( Shift_Right(Step,Natural(Z-1)) ); end if; end loop; if ( Samp_Delta and Sign ) /= 0 then -- Test delta sign Diff := -Diff; -- Make the delta negative end if; -- Compute the next sample based upon the difference Samp_X := Audio_I32(Samp_0) + Diff; -- prior + delta if Samp_X > 32767 then -- Range clamping.. Samp_X := 32767; elsif Samp_X < -32768 then Samp_X := -32768; end if; Emit(SX+PX-1,Chx) := Audio_I16( Samp_X ); -- Save for later write to Out_Str X := Step_Index( X + Idx_Tab(Audio_U16(Samp_Delta)) ); Samp_0 := Audio_I16(Samp_X); -- Current sample becomes previous sample end loop; -- End "data word" Step_X(Chx) := X; -- Save index Block.Header(Chx).Samp_0 := Samp_0; -- Save previous sample end loop; -- for all channels SX := SX + Wd_Samps; -- # of samples created in inner loop from a "data word" end loop; -- for all samples to be decompressed Samples_Out_Array'Write(Out_Str,Emit); -- Write all decompressed samples to out stream end; -- for samples within the current IMA ADPCM block end loop; -- for all available bytes of data end; end Pump_IMA_ADPCM; -------------------------------------------------- -- Microsoft ADPCM : -------------------------------------------------- procedure Pump_MS_ADPCM(In_Str, Out_Str : Audio_Stream) is Chans : Audio_U16 := Audio_U16(Channels(In_Str.all)); -- # of Audio Channels type Samples_Out_Array is array(Audio_U16 range <>,Audio_U16 range <>) of Audio_I16; type Audio_Byte_Array is array(Audio_U16 range <>) of Audio_Byte; type Audio_I16_Array is array(Audio_U16 range <>) of Audio_I16; type Coef_Set is record Coef1 : Audio_I16; -- ADPCM coefficient 1 Coef2 : Audio_I16; -- ADPCM coefficient 2 end record; type Coef_Set_Array is array (Audio_U16 range <>) of Coef_Set; type Block_Hdr(Chans : Audio_U16) is record Predictor : Audio_Byte_Array(1..Chans); Init_Delta : Audio_I16_Array(1..Chans); Sample_1 : Audio_I16_Array(1..Chans); Sample_2 : Audio_I16_Array(1..Chans); end record; type ADPCM_Block(Chans, Sample_Bytes : Audio_U16) is record Header : Block_Hdr(Chans); Samples : Audio_Byte_Array(1..Sample_Bytes); end record; type Chan_Info_Type is record Predictor : Audio_U16; -- From Block_Hdr Init_Delta : Audio_I32; Sample_1 : Audio_I16; Sample_2 : Audio_I16; Coef1 : Audio_I16; -- Coefficients.. Coef2 : Audio_I16; end record; type Chan_Info_Array is array(1..Chans) of Chan_Info_Type; ------------------------------------------------------------ function Sample_Bytes(Block_Bytes : Audio_U16) return Audio_U16 is begin if Block_Bytes < 7 * Chans then return 0; -- No samples in this block end if; return Block_Bytes - 7 * Chans; -- This does not include the initial 2 samples! end Sample_Bytes; ------------------------------------------------------------ Fixed_Point_Coef_Base : constant Audio_I32 := 256; Fixed_Point_Adaption_Base : constant Audio_I32 := 256; Min_Delta : constant Audio_I32 := 16; Adaption_Table : constant array(-8..Audio_I32(7)) of Audio_I32 := ( 768, 614, 512, 409, 307, 230, 230, 230, -- Adaption Table constants 230, 230, 230, 230, 307, 409, 512, 614 ); Block_Size : Audio_U16; -- ADPCM Block size Bits_Per_ADPCM : Audio_U16; -- Often provided as zero, but should be 4 Samples_Per_Block : Audio_U16; -- # of samples per ADPCM block Sample_Length : Audio_U32; -- # of samples in this file Num_Coef : Audio_U16; -- # of Coefficients begin Audio_U16'Read(In_Str,Block_Size); -- Fetch the block size Audio_U16'Read(In_Str,Bits_Per_ADPCM); -- Often given as zero, but should be 4 Audio_U16'Read(In_Str,Samples_Per_Block); -- # of samples per block Audio_U32'Read(In_Str,Sample_Length); -- Sample length of this "play" Audio_U16'Read(In_Str,Num_Coef); -- Read the number of coefficients if Num_Coef > 256 then raise Program_Error; end if; declare Byte_Count : Audio_U16 := 0; -- Bytes available to read Samp_Bytes : Audio_U16 := 0; -- Bytes available as sample data within the block Coef : Coef_Set_Array(1..Num_Coef); -- Coefficient set Pred_Samp : Audio_I32; -- Predicted Sample Edelta : Audio_I32; -- Input ADPCM error delta New_Delta : Audio_I32; -- New iDelta New_Sampl : Audio_I32; -- New generated 16-bit PCM sample begin Coef_Set_Array'Read(In_Str,Coef); -- Read in the Coefficients loop -------------------------------------------------- -- Determine if the next ADPCM Block is a partial -------------------------------------------------- Byte_Count := Audio_U16(In_Items(In_Str.all,1)); -- How many incoming bytes are available? if Byte_Count > Block_Size then Byte_Count := Block_Size; -- Use regular block size end if; Samp_Bytes := Sample_Bytes(Byte_Count); -- How many bytes after the block header? exit when Samp_Bytes < 1; -- Exit when there is no more data to process -------------------------------------------------- -- Allow For The Last Partial ADPCM Block : -------------------------------------------------- declare Fetch : Boolean := True; -- Nibble fetching state Byte : Audio_U8; -- Current byte Nibble : Audio_U8; -- Current nibble Info : Chan_Info_Array; -- Extra Channel state info N_Samps : Audio_U16 := ( Samp_Bytes * 8 ) / ( 4 * Chans ) + 2; -- Includes the initial 2 samples Smpc : Audio_U16 := 2; -- Sample count including the initial 2 Out_Samps : Samples_Out_Array(1..N_Samps,1..Chans); -- Buffer for output samples Block : ADPCM_Block(Chans,Samp_Bytes); -- Precisely sized block SX : Audio_U16 := Block.Samples'First; -- Sample Index into Block.Samples() array begin ADPCM_Block'Read(In_Str,Block); -- Read the ADPCM Block -------------------------------------------------- -- Initialize predictors, coefficients etc. : -------------------------------------------------- for X in Block.Header.Predictor'range loop Info(X).Predictor := Audio_U16(Block.Header.Predictor(X)) + Coef'First; Info(X).Init_Delta := Audio_I32( Block.Header.Init_Delta(X) ); Info(X).Sample_1 := Block.Header.Sample_1(X); Info(X).Sample_2 := Block.Header.Sample_2(X); Info(X).Coef1 := Coef(Info(X).Predictor).Coef1; Info(X).Coef2 := Coef(Info(X).Predictor).Coef2; Out_Samps(1,X) := Block.Header.Sample_2(X); Out_Samps(2,X) := Block.Header.Sample_1(X); end loop; -------------------------------------------------- -- Decompress all samples in this block : -------------------------------------------------- loop exit when Smpc >= N_Samps; for X in Info'Range loop -- For all channels -- Predict the next sample : Pred_Samp := ( Audio_I32( Info(X).Sample_1 ) * Audio_I32( Info(X).Coef1 ) + Audio_I32( Info(X).Sample_2 ) * Audio_I32( Info(X).Coef2 ) ) / Fixed_Point_Coef_Base; if Fetch then -- Fetch the error delta out of the Block.Samples array Byte := Block.Samples(SX); -- Current byte Nibble := Shift_Right(Byte,4); -- Current nibble else Nibble := Byte and 16#0F#; -- Least significant nibble SX := SX + 1; end if; Fetch := Fetch xor True; -- Two nibbles to every byte if ( Nibble and 16#08# ) = 0 then Edelta := Audio_I32( Nibble ); else Edelta := -Audio_I32( 8 - (Nibble and 7) ); end if; New_Sampl := Pred_Samp + Info(X).Init_Delta * Edelta; if New_Sampl > 32767 then New_Sampl := 32767; -- Fix overly positive sample value elsif New_Sampl < -32768 then New_Sampl := -32768; -- Fix overly negative sample value end if; Out_Samps(Smpc+1,X) := Audio_I16( New_Sampl ); New_Delta := ( Info(X).Init_Delta * Adaption_Table(Edelta) ) / Fixed_Point_Adaption_Base; if New_Delta < Min_Delta then Info(X).Init_Delta := Min_Delta; -- Fix overly negative delta else Info(X).Init_Delta := New_Delta; -- Else save OK delta end if; Info(X).Sample_2 := Info(X).Sample_1; -- N-1 sample becomes N-2 sample Info(X).Sample_1 := Audio_I16( New_Sampl ); -- New sample becomes N-1 sample end loop; -- for all channels Smpc := Smpc + 1; end loop; -- for all samples in the block Samples_Out_Array'Write(Out_Str,Out_Samps); -- Write expanded samples to output stream end; -- end of the current ADPCM block end loop; -- end of all samples to play end; end Pump_MS_ADPCM; -------------------------------------------------- -- Process CODEC_Mulaw : -------------------------------------------------- procedure Pump_Mulaw(In_Str, Out_Str : Audio_Stream) is type Audio_Byte_Array is array(Positive range <>) of Audio_Byte; type Audio_I16_Array is array(Positive range <>) of Audio_I16; Sign_Bit : constant Audio_Byte := 16#80#; -- Sign bit for a A-law byte Quant_Mask : constant Audio_Byte := 16#0F#; -- Quantization field mask Nsegs : constant Unsigned_16 := 8; -- Number of A-law segments Seg_Mask : constant Audio_Byte := 16#70#; -- Segment field mask. Seg_Shift : constant Natural := 4; -- Left shift for segment number Bias : constant Audio_I16 := 16#0084#; -- Bias for linear code Sample_Count : Positive; U_Val : Audio_Byte; -- Byte from input stream T : Unsigned_16; -- Temp Shft : Unsigned_8; -- Shift count begin loop Sample_Count := In_Items(In_Str.all,1); declare In_Samples : Audio_Byte_Array(1..Sample_Count); Out_Samples : Audio_I16_Array(In_Samples'Range); begin Audio_Byte_Array'Read(In_Str,In_Samples); for X in In_Samples'Range loop U_Val := not In_Samples(X); T := Shift_Left(Unsigned_16(U_Val and Quant_Mask),3) + Unsigned_16(Bias); Shft := Shift_Right(Unsigned_8(U_Val and Seg_Mask),Seg_Shift); if Shft > 0 then T := Shift_Left(T,Natural(Shft)); end if; if ( U_Val and Sign_Bit ) = Sign_Bit then Out_Samples(X) := Bias - Audio_I16(T); else Out_Samples(X) := Audio_I16(T) - Bias; end if; end loop; Audio_I16_Array'Write(Out_Str,Out_Samples); exception when Ada.IO_Exceptions.End_Error => exit; end; end loop; end Pump_Mulaw; -------------------------------------------------- -- Pump Alaw 8-Bit Samples : -------------------------------------------------- procedure Pump_Alaw_8(In_Str, Out_Str : Audio_Stream) is type Audio_Byte_Array is array(Positive range <>) of Audio_Byte; type Audio_I16_Array is array(Positive range <>) of Audio_I16; Sign_Bit : constant Audio_Byte := 16#80#; -- Sign bit for a A-law byte Quant_Mask : constant Audio_Byte := 16#000F#; -- Quantization field mask Nsegs : constant Unsigned_16 := 8; -- Number of A-law segments Seg_Mask : constant Audio_byte := 16#70#; -- Segment field mask. Seg_Shift : constant Natural := 4; -- Left shift for segment number (t >> 4) in C Sample_Count : Positive; A_Val : Audio_Byte; -- A value T : Unsigned_16; -- temp Seg : Natural; -- segment begin loop Sample_Count := In_Items(In_Str.all,1); declare In_Samples : Audio_Byte_Array(1..Sample_Count); Out_Samples : Audio_I16_Array(In_Samples'Range); begin Audio_Byte_Array'Read(In_Str,In_Samples); for X in In_Samples'Range loop A_Val := In_Samples(X) xor Audio_Byte(16#55#); T := Shift_Left(Unsigned_16(A_Val and Quant_Mask),4); Seg := Natural(Shift_Right(Unsigned_16(A_Val and Seg_Mask),Seg_Shift)); case Seg is when 0 => T := T + 8; when 1 => T := T + 16#0108#; when others => T := T + 16#0108#; if Seg > 1 then T := Shift_Left(T,Seg-1); end if; end case; if ( A_Val and Sign_Bit ) /= 0 then Out_Samples(X) := -Audio_I16(T); else Out_Samples(X) := Audio_I16(T); end if; end loop; Audio_I16_Array'Write(Out_Str,Out_Samples); exception when Ada.IO_Exceptions.End_Error => exit; end; end loop; end Pump_Alaw_8; -------------------------------------------------- -- Pump Signed 8-bit Samples to Output : -------------------------------------------------- procedure Pump_PCM_8(In_Str, Out_Str : Audio_Stream) is type Audio_Signed_Array is array(Positive range <>) of Audio_Signed; type Audio_Byte_Array is array(Positive range <>) of Audio_Byte; Sample_Count : Positive; -- Sample Count begin loop Sample_Count := In_Items(In_Str.all,1); declare In_Samples : Audio_Signed_Array(1..Sample_Count); Out_Samples : Audio_Byte_Array(In_Samples'Range); begin Audio_Signed_Array'Read(In_Str,In_Samples); for X in In_Samples'Range loop Out_Samples(X) := Audio_Byte( 128 + Integer_16( In_Samples(X) ) ); end loop; Audio_Byte_Array'Write(Out_Str,Out_Samples); exception when Ada.IO_Exceptions.End_Error => exit; end; end loop; end Pump_PCM_8; -------------------------------------------------- -- Pump Unsigned 8-bit Samples to Output : -------------------------------------------------- procedure Pump_PCM_U8(In_Str, Out_Str : Audio_Stream) is type Audio_Signed_Array is array(Positive range <>) of Audio_Signed; type Audio_Byte_Array is array(Positive range <>) of Audio_Byte; Sample_Count : Positive; -- Sample count begin loop -- Process groups of samples Sample_Count := In_Items(In_Str.all,1); declare Samples : Audio_Byte_Array(1..Sample_Count); begin Audio_Byte_Array'Read(In_Str,Samples); Audio_Byte_Array'Write(Out_Str,Samples); exception when Ada.IO_Exceptions.End_Error => exit; end; end loop; end Pump_PCM_U8; -------------------------------------------------- -- Pump Signed 16-bit Samples to Output : -------------------------------------------------- procedure Pump_PCM_16(In_Str, Out_Str : Audio_Stream) is type Audio_I16_Array is array(Positive range <>) of Audio_I16; Sample_Count : Positive; begin loop Sample_Count := In_Items(In_Str.all,2); declare Samples : Audio_I16_Array(1..Sample_Count); begin Audio_I16_Array'Read(In_Str,Samples); Audio_I16_Array'Write(Out_Str,Samples); exception when Ada.IO_Exceptions.End_Error => exit; end; end loop; end Pump_PCM_16; -------------------------------------------------- -- Pump Signed 24-bit Samples to Output : -------------------------------------------------- procedure Pump_PCM_24(In_Str, Out_Str : Audio_Stream) is Sample : Audio_I24; begin loop begin Audio_I24'Read(In_Str,Sample); exception when Ada.IO_Exceptions.End_Error => exit; end; Audio_I24'Write(Out_Str,Sample); end loop; end Pump_PCM_24; -------------------------------------------------- -- Pump Signed 32-bit Samples to Output : -------------------------------------------------- procedure Pump_PCM_32(In_Str, Out_Str : Audio_Stream) is Sample : Audio_I32; begin loop begin Audio_I32'Read(In_Str,Sample); exception when Ada.IO_Exceptions.End_Error => exit; end; Audio_I32'Write(Out_Str,Sample); end loop; end Pump_PCM_32; -------------------------------------------------- -- Pump the Input Stream to the Output Stream : -------------------------------------------------- procedure Pump(In_Str, Out_Str : Audio_Stream) is Chans : Audio_Channels; -- # of audio channels Samp_Rate : Audio_Sample_Rate; -- Sample rate in samples / second Samp_Size : Audio_Sample_Size; -- Sample size in bits Samp_Type : Audio_Sample_Type; -- Sample Data Format begin -- Determine the input sample parameters : Chans := Channels(In_Str.all); Samp_Rate := Sample_Rate(In_Str.all); Samp_Size := Sample_Size(In_Str.all); Samp_Type := Sample_Type(In_Str.all); -- Configure the output device parameters : Set_Channels(Out_Str.all,Chans); Set_Sample_Rate(Out_Str.all,Samp_Rate); -- Choose the CODEC for the input Sample Format : case Samp_Type is when CODEC_Linear_U8 => Set_Sample_Size(Out_Str.all,Samp_Size); Pump_PCM_U8(In_Str,Out_Str); when CODEC_Linear_8 => -- Linear 8-bit samples Set_Sample_Size(Out_Str.all,Samp_Size); Pump_PCM_8(In_Str,Out_Str); when CODEC_Linear_16 => -- Linear 16-bit samples Set_Sample_Size(Out_Str.all,Samp_Size); Pump_PCM_16(In_Str,Out_Str); when CODEC_Linear_24 => Set_Sample_Size(Out_Str.all,Samp_Size); Pump_PCM_24(In_Str,Out_Str); when CODEC_Linear_32 => Set_Sample_Size(Out_Str.all,Samp_Size); Pump_PCM_32(In_str,Out_Str); when CODEC_Mulaw => Set_Sample_Size(Out_Str.all,16); Pump_Mulaw(In_Str,Out_Str); when CODEC_Alaw_8 => Set_Sample_Size(Out_Str.all,16); Pump_Alaw_8(In_Str,Out_Str); when CODEC_MS_ADPCM => Set_Sample_Size(Out_Str.all,16); Pump_MS_ADPCM(In_Str,Out_Str); when CODEC_IMA_ADPCM => Set_Sample_Size(Out_Str.all,16); Pump_IMA_ADPCM(In_Str,Out_Str); when others => raise Unsupported_Format; end case; end Pump; end WC.Streams.Codec;