OGGVorbisPlayer.Mod 108 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587
  1. (** AUTHOR "Christian Wassmer, chwassme@student.ethz.ch";
  2. PURPOSE "an audio-player for Ogg/Vorbis-radiostations and -files";
  3. DATE "Avril 2004" *)
  4. MODULE OGGVorbisPlayer;
  5. IMPORT
  6. SYSTEM, Strings, KernelLog, Streams, Files, Commands, SoundDevices, BIT, Math,
  7. OGGUtilities, Modules, Kernel,
  8. TCP, WebHTTP, WebHTTPClient;
  9. CONST
  10. (* Debugging Set *)
  11. Trace = 1;
  12. Error = 2;
  13. Codec = 3;
  14. Debug = {Error};
  15. (* oggstream-types, are also recognition-pattern for calling the correct decoder *)
  16. Vorbis = "vorbis";
  17. CodebookSynchPattern = 564342H;
  18. (* return codes *)
  19. Ok = 0;
  20. ErrorIdentification = 1;
  21. ErrorSetup = 2;
  22. ErrorDataPacket = 3;
  23. PacketTooBig = 4;
  24. InvalidSerialNumber = 5;
  25. UnexpectedEOS = 6;
  26. OggStreamNotFound = 7;
  27. NoDecoderFound = 8;
  28. LogicalOggStreamFinished = 8;
  29. ErrorCapturePattern = 9;
  30. TooManyLogicalOggStreams = 10;
  31. NoDataPacket = 11;
  32. InvalidCodebookNumber = 12;
  33. ChannelNotUsed = 13;
  34. PacketUndecodable = 14;
  35. ErrorWindowDecode = 15;
  36. (* maximum ogg-page-size, as defined in the specs *)
  37. MaxPageSize = 65307;
  38. (* length of all header field of an Ogg-page *)
  39. BaseHeaderLength = 27;
  40. (* 'vorbis' as example, others seems to be also of the same length*)
  41. OggStreamTypeLength = 6;
  42. (* constants for sound output *)
  43. MaxChannels* = 6;
  44. DefaultSamplingResolution = 16;
  45. (* data structure constants *)
  46. MaxNrOfSegments = 255;
  47. MaxLogicalStreams = 8;
  48. MaxVendorLength = 64;
  49. MaxCommentLength = 256;
  50. MaxNumberOfCodebooks = 256;
  51. MaxNumberOfMultiplicands = 65536;
  52. MaxNumberOfFloors = 64;
  53. MaxNumberOfResidues = 64;
  54. MaxNumberOfMappings = 64;
  55. MaxNumberOfModes = 64;
  56. Floor0BookListSize = 16;
  57. Floor1PartitionClassListSize = 32;
  58. Floor1ClassSize = 16;
  59. Floor1SubclassSize = 16;
  60. Floor1XListSize = 256; (* >= 32 * 7 + 7 *)
  61. ResidueCascadeSize = 64;
  62. ResidueBookSize = 64;
  63. MappingMagnitudeSize = 256;
  64. MappingMuxSize = 256;
  65. MappingSubmapFloorSize = 16;
  66. (* floor1Y: 0..288 = 32 * (3 bit "+ 1") *)
  67. Floor1Final = 288;
  68. (* used for partword01, partword2 and decodemap (residues) *)
  69. PartwordSize = 8;
  70. NrOfBlocksizes = 8;
  71. InverseDBLookupSize = 256;
  72. (* some marker constants *)
  73. ResidueBookUnused = -1;
  74. UnusedCodebookEntry = -2;
  75. (* returned by AbstractFloorType::DecodePacket() if the floor is unused *)
  76. SerialNumberUnset = -4;
  77. VAR
  78. frameCnt: LONGINT;
  79. OggS: ARRAY 4 OF CHAR;
  80. nrOfPages: LONGINT;
  81. FloorRanges: ARRAY 4 OF LONGINT;
  82. InverseDBLookup: ARRAY InverseDBLookupSize OF LONGINT;
  83. (** state of the player *);
  84. stopped*, playing*: BOOLEAN;
  85. TYPE
  86. BitReader = OBJECT
  87. VAR
  88. r: Streams.Reader;
  89. bsBuff, bsLive: LONGINT;
  90. bytesRead: LONGINT;
  91. PROCEDURE &Init*(r: Streams.Reader);
  92. BEGIN
  93. SELF.r := r;
  94. bsLive := 0
  95. END Init;
  96. (* is stream still available *)
  97. PROCEDURE IsOk() : BOOLEAN;
  98. BEGIN
  99. RETURN r.res = Streams.Ok
  100. END IsOk;
  101. (* get the number of bytes read *)
  102. PROCEDURE GetBytesRead(): LONGINT;
  103. BEGIN
  104. RETURN SELF.bytesRead
  105. END GetBytesRead;
  106. (* read a number of bits (lsb first) from the reader (max: 32)
  107. note: if n is 32 (bigger is not allowed) then the last bit will be interpreted as the sign
  108. and may give wrong results, otherwise the sign-bit of the returned longint will not be affected anyway *)
  109. PROCEDURE GetBits(n: LONGINT): LONGINT;
  110. VAR r, factor: LONGINT;
  111. BEGIN
  112. r := 0; factor := 1;
  113. WHILE (n > 0) DO
  114. r := r + factor * GetBit();
  115. factor := factor * 2;
  116. DEC(n)
  117. END;
  118. RETURN r
  119. END GetBits;
  120. (* get the next bit from the stream (lsb first) *)
  121. PROCEDURE GetBit(): LONGINT;
  122. VAR res: LONGINT;
  123. BEGIN
  124. IF (bsLive = 0) THEN
  125. bsBuff := ORD(r.Get());
  126. IF (r.res = Streams.Ok) THEN bsLive := 8
  127. ELSE StreamEOF()
  128. END;
  129. INC(bytesRead)
  130. END;
  131. DEC(bsLive);
  132. res := bsBuff MOD 2;
  133. bsBuff := bsBuff DIV 2;
  134. RETURN res;
  135. END GetBit;
  136. (* get a hugeint *)
  137. PROCEDURE GetHugeInt(): HUGEINT;
  138. VAR
  139. huge: HUGEINT;
  140. BEGIN
  141. huge := GetBits(16);
  142. huge := huge + 10000H * GetBits(16);
  143. huge := huge + 10000H * GetBits(16);
  144. huge := huge + 10000H * GetBits(16);
  145. RETURN huge
  146. END GetHugeInt;
  147. (* get a char *)
  148. PROCEDURE GetChar(): CHAR;
  149. BEGIN
  150. RETURN CHR(GetBits(8))
  151. END GetChar;
  152. PROCEDURE StreamEOF;
  153. BEGIN
  154. KernelLog.String("unexpected end of stream"); KernelLog.Ln;
  155. RETURN
  156. END StreamEOF;
  157. END BitReader;
  158. (* read from a buffer, returning various sized integers *)
  159. BufferReader = OBJECT
  160. VAR
  161. bsBuff, bsLive, pos, len: LONGINT;
  162. PROCEDURE &Init*;
  163. BEGIN
  164. bsLive := 0; pos := 0; len := 0
  165. END Init;
  166. (* print the state of it *)
  167. PROCEDURE Print;
  168. BEGIN
  169. OGGUtilities.String("*** state of BufferReader ***");
  170. OGGUtilities.Var("bsLive", bsLive);
  171. OGGUtilities.Var("len", len);
  172. OGGUtilities.Var("pos", pos);
  173. OGGUtilities.String("*** --- ***")
  174. END Print;
  175. PROCEDURE SetLen(len: LONGINT);
  176. BEGIN
  177. SELF.len := len
  178. END SetLen;
  179. PROCEDURE GetLen(): LONGINT;
  180. BEGIN
  181. RETURN SELF.len
  182. END GetLen;
  183. (* is buffer still available *)
  184. PROCEDURE IsOk(VAR buf: ARRAY OF CHAR) : BOOLEAN;
  185. BEGIN
  186. RETURN ((LEN(buf) # pos) & (len # pos));
  187. END IsOk;
  188. (* get the current position in the buffer *)
  189. PROCEDURE GetPos(): LONGINT;
  190. BEGIN
  191. RETURN pos
  192. END GetPos;
  193. PROCEDURE GetBitCount(): LONGINT;
  194. BEGIN
  195. RETURN (pos - 1) * 8 + (8 - bsLive)
  196. END GetBitCount;
  197. (* get the current byte from the buffer as a longint *)
  198. PROCEDURE GetCurByte(VAR buf: ARRAY OF CHAR): LONGINT;
  199. BEGIN
  200. RETURN ORD(buf[pos])
  201. END GetCurByte;
  202. (* get the next bit from the buffer (lsb first) *)
  203. PROCEDURE GetBit(VAR buf: ARRAY OF CHAR): LONGINT;
  204. VAR res: LONGINT;
  205. BEGIN
  206. IF ((LEN(buf) # pos) & (len # pos) & (bsLive = 0)) THEN
  207. bsBuff := ORD(buf[pos]);
  208. bsLive := 8;
  209. INC(pos)
  210. END;
  211. DEC(bsLive);
  212. res := bsBuff MOD 2;
  213. bsBuff := bsBuff DIV 2;
  214. RETURN res
  215. END GetBit;
  216. (* read a number of bits (lsb first) from the buffer (max: 32)
  217. note: if n is 32 (bigger is not allowed) then the last bit will be interpreted as the sign (by the processor)
  218. and may give wrong results, otherwise the sign-bit of the returned longint will not be affected anyway *)
  219. PROCEDURE GetBits(VAR buf: ARRAY OF CHAR; n: LONGINT): LONGINT;
  220. VAR r, factor: LONGINT;
  221. BEGIN
  222. r := 0;
  223. factor := 1;
  224. WHILE (n > 0) DO
  225. r := r + factor * GetBit(buf);
  226. factor := factor * 2;
  227. DEC(n)
  228. END;
  229. RETURN r
  230. END GetBits;
  231. (* get a hugeint *)
  232. PROCEDURE GetHugeInt(VAR buf: ARRAY OF CHAR): HUGEINT;
  233. VAR
  234. huge: HUGEINT;
  235. BEGIN
  236. huge := GetBits(buf, 16);
  237. huge := huge + 10000H * GetBits(buf, 16);
  238. huge := huge + 10000H * GetBits(buf, 16);
  239. huge := huge + 10000H * GetBits(buf, 16);
  240. RETURN huge
  241. END GetHugeInt;
  242. (* get a 32 bit unsigned integer *)
  243. PROCEDURE Get32UnsignedBits (VAR buf: ARRAY OF CHAR): HUGEINT;
  244. VAR
  245. res: HUGEINT;
  246. tmp: LONGINT;
  247. BEGIN
  248. tmp := 1;
  249. res := GetBits(buf, 31) + GetBit(buf) * LSH(tmp, 31);
  250. RETURN res;
  251. END Get32UnsignedBits;
  252. (* get the next char *)
  253. PROCEDURE GetChar (VAR buf: ARRAY OF CHAR): CHAR;
  254. BEGIN
  255. RETURN CHR(GetBits(buf, 8))
  256. END GetChar;
  257. END BufferReader;
  258. OggPageHeader = RECORD
  259. headerTypeFlag, pageSegments,pageSize,headerLength, streamSerialNo: LONGINT;
  260. pageNo, checksum, absGranulePos: HUGEINT;
  261. segTable: ARRAY MaxNrOfSegments OF LONGINT
  262. END;
  263. OggPage = RECORD
  264. buf: ARRAY MaxPageSize OF CHAR;
  265. header: OggPageHeader
  266. END;
  267. (* not really a stream, more a structure to keep stream-serialnumber, decoder and it's type together *)
  268. LogicalOggStream = OBJECT
  269. VAR
  270. serialNumber*: LONGINT;
  271. decoder*: Decoder;
  272. soundOutput: SoundOutput;
  273. type*: ARRAY OggStreamTypeLength OF CHAR;
  274. finished*: BOOLEAN;
  275. (* init a new LogicalOggStream, type must have a length of 6 *)
  276. PROCEDURE &Init*(dec: Decoder; soundOutput: SoundOutput; type: ARRAY OF CHAR);
  277. VAR i: LONGINT;
  278. BEGIN
  279. IF (Trace IN Debug) THEN
  280. OGGUtilities.String("@ LogicalOggStream::Init()")
  281. END;
  282. serialNumber := SerialNumberUnset;
  283. SELF.decoder := dec;
  284. SELF.soundOutput := soundOutput;
  285. IF (LEN(type)- 1 # OggStreamTypeLength) THEN
  286. KernelLog.String("ASSERTION failed - type-string isn't 0X terminated"); KernelLog.Ln
  287. END;
  288. ASSERT(LEN(type) - 1= OggStreamTypeLength); (* -1: string is 0X terminated *)
  289. FOR i:=0 TO OggStreamTypeLength-1 DO SELF.type[i] := type[i] END;
  290. finished := FALSE
  291. END Init;
  292. END LogicalOggStream;
  293. OggStreamReader* = OBJECT
  294. VAR
  295. bitReader: BitReader;
  296. page: OggPage;
  297. streams: ARRAY MaxLogicalStreams OF LogicalOggStream;
  298. nrOfStreams*: LONGINT;
  299. (* init the OggStreamReader *)
  300. PROCEDURE &Init*(reader: Streams.Reader);
  301. BEGIN
  302. IF (Trace IN Debug) THEN
  303. OGGUtilities.String("@ Init()");
  304. END;
  305. NEW(SELF.bitReader, reader);
  306. nrOfStreams := 0;
  307. stopped := FALSE;
  308. playing := FALSE;
  309. END Init;
  310. (** register an ogg-stream decoder of a given oggstream-type, type must have a length of 6*)
  311. PROCEDURE RegisterDecoder*(dec: Decoder; soundOutput: SoundOutput; type: ARRAY OF CHAR): LONGINT;
  312. VAR
  313. logOggStream: LogicalOggStream;
  314. BEGIN
  315. IF (Trace IN Debug) THEN
  316. OGGUtilities.String("@ RegisterDecoder()");
  317. END;
  318. IF nrOfStreams < MaxLogicalStreams THEN
  319. NEW(logOggStream, dec, soundOutput, type);
  320. streams[nrOfStreams] := logOggStream;
  321. INC(nrOfStreams);
  322. RETURN Ok
  323. ELSE
  324. IF (Error IN Debug) THEN
  325. OGGUtilities.Var("no more logical streams allowed, maximum", MaxLogicalStreams);
  326. END;
  327. RETURN TooManyLogicalOggStreams
  328. END
  329. END RegisterDecoder;
  330. (** unregister an logical ogg-stream , usually used when it's finished *)
  331. PROCEDURE UnregisterLogicalOggStream*(stream: LogicalOggStream);
  332. VAR
  333. i: LONGINT;
  334. found: BOOLEAN;
  335. BEGIN
  336. i := 0; found := FALSE;
  337. WHILE ((i # nrOfStreams) & (~found)) DO
  338. IF streams[i] = stream THEN
  339. found := TRUE;
  340. streams[i] := NIL
  341. ELSE
  342. INC(i)
  343. END;
  344. END;
  345. (* shift the remaining streams into the generated gap *)
  346. IF found THEN
  347. DEC(nrOfStreams);
  348. WHILE (i # nrOfStreams) DO
  349. streams[i] := streams[i+1]; INC(i)
  350. END
  351. END
  352. END UnregisterLogicalOggStream;
  353. (* dispatches a whole ogg-page to the correspondant Decoder by calling DecodePage() *)
  354. PROCEDURE Dispatch(VAR oggStream: LogicalOggStream);
  355. VAR
  356. type: ARRAY OggStreamTypeLength OF CHAR;
  357. firstPage: BOOLEAN;
  358. pos, i: LONGINT;
  359. BEGIN
  360. IF (Trace IN Debug) THEN
  361. OGGUtilities.String("@ Dispatch()")
  362. END;
  363. firstPage := (((page.header.headerTypeFlag DIV 2) MOD 2) = 1);
  364. (* determine packet type and get correct LogicalOggStream *)
  365. pos := page.header.headerLength + 1; (* set current position to start packet identification string *)
  366. IF firstPage THEN
  367. i := 0;
  368. pos := 1(* page.header.headerLength + 1 *); (* set current position to start packet identification string *)
  369. WHILE (i # OggStreamTypeLength) DO (* get type-string *)
  370. type[i] := page.buf[pos + i];
  371. INC(i)
  372. END;
  373. oggStream := GetLogicalOggStreamByType(type); (* find it's LogicalOggStream *)
  374. (* and update it's serial-number *)
  375. IF oggStream # NIL THEN oggStream.serialNumber := page.header.streamSerialNo END
  376. ELSE oggStream := GetLogicalOggStreamBySerialNr(page.header.streamSerialNo)
  377. END;
  378. END Dispatch;
  379. PROCEDURE DecodePage(VAR oggStream: LogicalOggStream): LONGINT;
  380. VAR
  381. res, seg, pos, len, i: LONGINT;
  382. decodingSuccess: BOOLEAN;
  383. BEGIN
  384. IF (Trace IN Debug) THEN
  385. OGGUtilities.String("@ DecodePage()");
  386. END;
  387. decodingSuccess := TRUE;
  388. len := 0; i := 0; pos := 1 + OggStreamTypeLength;
  389. (* while there are more lacing-values *)
  390. WHILE (i # page.header.pageSegments) DO
  391. seg := page.header.segTable[i];
  392. INC(len,seg);
  393. (* new packets are indicated by a number unequal to 255 *)
  394. IF (seg # 255) THEN
  395. res := oggStream.decoder(page.buf, pos, len, FALSE, oggStream.soundOutput);
  396. INC(pos,len);
  397. len := 0
  398. END;
  399. IF res # Ok THEN RETURN res END;
  400. INC(i)
  401. END;
  402. IF (seg = 255) THEN
  403. res := oggStream.decoder(page.buf, pos, len, TRUE, oggStream.soundOutput)
  404. END;
  405. RETURN res
  406. END DecodePage;
  407. (* get a LogicalOggStream by serial-number *)
  408. PROCEDURE GetLogicalOggStreamBySerialNr(serialNr: LONGINT): LogicalOggStream;
  409. VAR
  410. i: LONGINT;
  411. BEGIN
  412. IF (Trace IN Debug) THEN
  413. OGGUtilities.String("@ GetLogicalOggStreamBySerialNr()")
  414. END;
  415. i := 0;
  416. WHILE (i # nrOfStreams) DO
  417. IF streams[i].serialNumber = serialNr THEN RETURN streams[i] END;
  418. INC(i);
  419. END;
  420. IF (Error IN Debug) THEN
  421. OGGUtilities.String("no oggStream (by serialnr) found !!!")
  422. END;
  423. RETURN NIL
  424. END GetLogicalOggStreamBySerialNr;
  425. (* get a LogicalOggStream by type-string *)
  426. PROCEDURE GetLogicalOggStreamByType(type: ARRAY OF CHAR): LogicalOggStream;
  427. VAR
  428. i, j: LONGINT;
  429. oggStream: LogicalOggStream;
  430. found: BOOLEAN;
  431. BEGIN
  432. IF (Trace IN Debug) THEN
  433. OGGUtilities.String("@ GetLogicalOggStreamBySerialType()")
  434. END;
  435. found := FALSE; i := 0;
  436. WHILE (~found) & (i # nrOfStreams) DO
  437. oggStream := streams[i]; j := 0;
  438. WHILE (j # OggStreamTypeLength) & (oggStream.type[j] = type[j]) DO INC(j) END;
  439. found := (j = OggStreamTypeLength);
  440. INC(i)
  441. END;
  442. IF ~found THEN
  443. IF (Error IN Debug) THEN
  444. OGGUtilities.String("no oggStream (by type) found !!!")
  445. END;
  446. RETURN NIL
  447. ELSE
  448. RETURN oggStream
  449. END
  450. END GetLogicalOggStreamByType;
  451. PROCEDURE Stop*;
  452. VAR i: LONGINT;
  453. BEGIN
  454. FOR i := 0 TO LEN(streams) - 1 DO
  455. IF streams[i] # NIL THEN
  456. streams[i].soundOutput.CloseSoundChannel()
  457. END
  458. END
  459. END Stop;
  460. (** start playing an ogg-stream *)
  461. PROCEDURE Start*(): LONGINT;
  462. VAR
  463. retCode: LONGINT;
  464. lastPage: BOOLEAN;
  465. oggStream: LogicalOggStream;
  466. BEGIN
  467. IF (Trace IN Debug) THEN
  468. OGGUtilities.String("@ Start()");
  469. END;
  470. (* start a loop for all logical ogg-stream header packets *)
  471. LOOP
  472. (* if playback is stopped from outside ... *)
  473. IF stopped THEN
  474. KernelLog.String("playback stopped"); KernelLog.Ln;
  475. stopped := FALSE;
  476. playing := FALSE;
  477. RETURN retCode;
  478. END;
  479. retCode := NextPage(); (* (try to) read the next ogg-page *)
  480. IF retCode = Ok THEN
  481. (* get the right LogicalOggStream *)
  482. Dispatch(oggStream);
  483. (* if a LogicalOggStream found, call it's Decode()-procedure *)
  484. IF (oggStream # NIL) & (~oggStream.finished) THEN
  485. lastPage := (((page.header.headerTypeFlag DIV 4) MOD 2) = 1);
  486. IF lastPage THEN oggStream.finished := TRUE END;
  487. (* try to decode it *)
  488. retCode := DecodePage(oggStream);
  489. (* if it is finished then unregister it *)
  490. IF oggStream.finished THEN
  491. UnregisterLogicalOggStream(oggStream);
  492. oggStream.soundOutput.CloseSoundChannel();
  493. retCode := LogicalOggStreamFinished
  494. ELSE
  495. retCode := Ok
  496. END
  497. ELSIF oggStream = NIL THEN retCode := NoDecoderFound
  498. END;
  499. IF retCode # Ok THEN
  500. (* if no logical ogg-stream is left, the physical ogg-stream is finished correctly *)
  501. IF nrOfStreams = 0 THEN RETURN Ok ELSE RETURN retCode END
  502. END
  503. ELSE
  504. RETURN retCode
  505. END;
  506. IF ~bitReader.IsOk() THEN
  507. RETURN UnexpectedEOS
  508. END
  509. END; (* LOOP *)
  510. RETURN Ok
  511. END Start;
  512. (* reads the next page of the stream buffering its content *)
  513. PROCEDURE NextPage(): LONGINT;
  514. VAR
  515. res, i: LONGINT;
  516. ch: CHAR;
  517. BEGIN
  518. (* look for the capture pattern *)
  519. i := 0;
  520. ch := bitReader.GetChar();
  521. WHILE (i # 4) & (ch = OggS[i]) DO
  522. ch := bitReader.GetChar();
  523. INC(i)
  524. END;
  525. IF (i#4) THEN RETURN ErrorCapturePattern ELSE res := Ok END;
  526. (* continue with the header, step-by-step *)
  527. (* stream structure version already done (read one step ahead in previous loop *)
  528. page.header.headerTypeFlag := bitReader.GetBits(8);
  529. page.header.absGranulePos := bitReader.GetHugeInt();
  530. page.header.streamSerialNo := bitReader.GetBits(32);
  531. page.header.pageNo := bitReader.GetBits(32);
  532. page.header.checksum := bitReader.GetBits(32);
  533. page.header.pageSegments := bitReader.GetBits(8);
  534. page.header.headerLength := page.header.pageSegments + BaseHeaderLength;
  535. (* calculate page size and save segment sizes *)
  536. page.header.pageSize := 0;
  537. FOR i := 0 TO page.header.pageSegments-1 DO
  538. page.header.segTable[i] := (bitReader.GetBits(8)); (* SHORT(.) removed *)
  539. page.header.pageSize := page.header.pageSize + page.header.segTable[i];
  540. END;
  541. (* buffer whole page *)
  542. FOR i:=0 TO page.header.pageSize-1 DO
  543. ch := bitReader.GetChar();
  544. page.buf[i] := ch;
  545. END;
  546. INC(nrOfPages);
  547. RETURN res
  548. END NextPage;
  549. END OggStreamReader;
  550. (* simple data-container for decoding *)
  551. DecoderState = OBJECT
  552. VAR
  553. (* internal state *)
  554. bufferAllocated: BOOLEAN;
  555. (* some single information *)
  556. resSize, n, residueType, cacheSize, lastWindowFlag, nrOfSamples: LONGINT;
  557. preCached: BOOLEAN;
  558. (* information needed during decoding process *)
  559. codec: CodecSetup;
  560. mode: Mode;
  561. mapping: Mapping;
  562. win: Window;
  563. info: Info;
  564. resInfo: ResidueInfo;
  565. (* buffers for temporary and final (floor) data *)
  566. floor, rightCache, residues: ARRAY MaxChannels OF OGGUtilities.PCMBuffer;
  567. (* Residue *)
  568. residuePartitionProc: ARRAY 3 OF ResiduePartitionProc;
  569. doNotDecode, noResidue: ARRAY MaxChannels OF BOOLEAN;
  570. residueNumbers: ARRAY MaxChannels OF LONGINT; (* stores info of residue vector of each channel *)
  571. (* FloorType1 *)
  572. floor1Y: ARRAY Floor1Final OF LONGINT;
  573. floor1Step2Flag: ARRAY Floor1Final OF BOOLEAN;
  574. PROCEDURE &Init*(channels: LONGINT);
  575. BEGIN
  576. bufferAllocated := FALSE;
  577. NEW(codec);
  578. NEW(resInfo);
  579. residuePartitionProc[0] := ResiduePartitionProc0;
  580. residuePartitionProc[1] := ResiduePartitionProc1;
  581. residuePartitionProc[2] := ResiduePartitionProc2
  582. END Init;
  583. PROCEDURE AllocateBuffers(channels: LONGINT);
  584. VAR i: LONGINT;
  585. BEGIN
  586. FOR i := 0 TO channels - 1 DO
  587. NEW(residues[i]);
  588. NEW(floor[i]);
  589. NEW(rightCache[i])
  590. END;
  591. bufferAllocated := TRUE
  592. END AllocateBuffers;
  593. END DecoderState;
  594. (** contains information about current window sizes during decode process *)
  595. Window = OBJECT
  596. VAR
  597. small, long: LONGINT;
  598. center*, leftStart*, leftEnd*, leftSize*, rightStart*, rightEnd*, rightSize*: LONGINT;
  599. lookupsLeft*, lookupsRight*: ARRAY 2 OF Slope;
  600. PROCEDURE &Init*(small, long: LONGINT);
  601. BEGIN
  602. SELF.small := small DIV 2;
  603. SELF.long := long DIV 2;
  604. NEW(lookupsLeft[0], SELF.small, SlopeLeft);
  605. NEW(lookupsLeft[1], SELF.long, SlopeLeft);
  606. NEW(lookupsRight[0], SELF.small, SlopeRight);
  607. NEW(lookupsRight[1], SELF.long, SlopeRight)
  608. END Init;
  609. (* return the correct lookup-table index for blocksize n *)
  610. PROCEDURE GetLookupTable(n: LONGINT): LONGINT;
  611. BEGIN
  612. IF n = small THEN
  613. RETURN 0
  614. ELSIF n = long THEN
  615. RETURN 1
  616. END
  617. END GetLookupTable;
  618. PROCEDURE ApplyWindow(VAR data: ARRAY OF HUGEINT; VAR decState: DecoderState);
  619. VAR i, rIdx, lIdx, n: LONGINT;
  620. BEGIN
  621. lIdx := GetLookupTable(leftSize);
  622. rIdx := GetLookupTable(rightSize);
  623. n := decState.n;
  624. IF (decState.mode.windowType = 0) THEN
  625. FOR i := 0 TO leftStart - 1 DO
  626. (* no data from this area *)
  627. data[i] := 0
  628. END;
  629. FOR i := leftStart TO leftEnd - 1 DO
  630. (* increasing window *)
  631. data[i] := OGGUtilities.MultHugeFP(data[i], lookupsLeft[lIdx].data[i - leftStart])
  632. END;
  633. (* in between window is equal 1 => do nothing *)
  634. FOR i := rightStart TO rightEnd - 1 DO
  635. (* descending window *)
  636. data[i] := OGGUtilities.MultHugeFP(data[i], lookupsRight[rIdx].data[i - rightStart])
  637. END;
  638. FOR i := rightEnd TO n - 1 DO
  639. (* no data from this area *)
  640. data[i] := 0
  641. END
  642. ELSE
  643. IF (Error IN Debug) THEN
  644. KernelLog.String("ERROR @ VorbisCodec::Window::ApplyWindows() - undefined windowType");
  645. KernelLog.Ln
  646. END
  647. END;
  648. END ApplyWindow;
  649. PROCEDURE Print;
  650. BEGIN
  651. OGGUtilities.String("### Window ###");
  652. OGGUtilities.Var("center", center);
  653. OGGUtilities.Var("leftStart", leftStart);
  654. OGGUtilities.Var("leftEnd", leftEnd);
  655. OGGUtilities.Var("leftSize", leftSize);
  656. OGGUtilities.Var("rightStart", rightStart);
  657. OGGUtilities.Var("rightEnd", rightEnd);
  658. OGGUtilities.Var("rightSize", rightSize);
  659. OGGUtilities.String("### END ")
  660. END Print;
  661. END Window;
  662. Slope = OBJECT
  663. VAR data: ARRAY OGGUtilities.MaxBlocksize OF LONGINT;
  664. length: LONGINT;
  665. PROCEDURE &Init*(length: LONGINT; slope: SlopeFunction);
  666. VAR i: LONGINT;
  667. tmp: REAL;
  668. BEGIN
  669. SELF.length := length;
  670. FOR i := 0 TO length - 1 DO
  671. tmp := slope(i, length);
  672. data[i] := OGGUtilities.ScaleUp(tmp);
  673. END
  674. END Init;
  675. PROCEDURE Print;
  676. BEGIN
  677. PrintLen(length);
  678. END Print;
  679. PROCEDURE PrintLen(len: LONGINT);
  680. BEGIN
  681. OGGUtilities.String("### SLOPE ###");
  682. OGGUtilities.Var("length", length);
  683. OGGUtilities.ArrayLen("data", data, len);
  684. OGGUtilities.String("### END (slope) ###");
  685. END PrintLen;
  686. END Slope;
  687. AbstractFloorType = OBJECT
  688. (** no common fields yet *)
  689. (** abstract method *)
  690. PROCEDURE DecodeHeader(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  691. VAR info: Info; VAR codec: CodecSetup): BOOLEAN;
  692. BEGIN
  693. HALT(301)
  694. END DecodeHeader;
  695. (** abstract method *)
  696. PROCEDURE DecodePacket(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR; VAR decState: DecoderState): LONGINT;
  697. BEGIN
  698. HALT(301)
  699. END DecodePacket;
  700. (** abstract method *)
  701. PROCEDURE ComputeCurve(VAR decState: DecoderState; ch: LONGINT);
  702. BEGIN
  703. HALT(301)
  704. END ComputeCurve;
  705. (** abstract method *)
  706. PROCEDURE Print;
  707. BEGIN
  708. HALT(301)
  709. END Print;
  710. END AbstractFloorType;
  711. (*
  712. (* FloorType0 is no longer supported by Xiph.Org and therefore nearly deprecated *)
  713. FloorType0 = OBJECT(AbstractFloorType)
  714. VAR
  715. order, rate, barkMapSize, amplitudeBits, amplitudeOffset, numberOfBooks: LONGINT;
  716. bookList: ARRAY Floor0BookListSize OF LONGINT;
  717. (** print to the logfile *)
  718. PROCEDURE Print;
  719. BEGIN
  720. (*
  721. OGGUtilities.String("### FloorType0 ###");
  722. OGGUtilities.Var("order", order);
  723. OGGUtilities.Var("rate", rate);
  724. OGGUtilities.Var("barkMapSize", barkMapSize);
  725. OGGUtilities.Var("amplitudeBits", amplitudeBits);
  726. OGGUtilities.Var("amplitudeOffset", amplitudeOffset);
  727. OGGUtilities.Var("numberOfBooks", numberOfBooks);
  728. OGGUtilities.Array("bookList", bookList);
  729. OGGUtilities.String("### END (FloorType0) ###"); OGGUtilities.String("")
  730. *)
  731. END Print;
  732. (** decode floor0-description from codec setup header*)
  733. PROCEDURE DecodeHeader(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  734. VAR info: Info; VAR codec: CodecSetup): BOOLEAN;
  735. BEGIN
  736. (*
  737. order := bufReader.GetBits(buf, 8);
  738. rate := bufReader.GetBits(buf, 16);
  739. barkMapSize := bufReader.GetBits(buf, 16);
  740. amplitudeBits := bufReader.GetBits(buf, 6);
  741. amplitudeOffset := bufReader.GetBits(buf, 8);
  742. numberOfBooks := bufReader.GetBits(buf, 4) + 1;
  743. FOR i := 0 TO numberOfBooks - 1 DO
  744. bookList[i] := bufReader.GetBits(buf, 8);
  745. IF (bookList[i] > info.codec.codebookCnt) THEN
  746. IF (Error IN Debug) THEN
  747. OGGUtilities.String("error@VorbisCodec::Floor0::DecodeHeader() - invalid codebook number (too big)")
  748. END;
  749. RETURN FALSE
  750. END
  751. END;
  752. *)
  753. RETURN TRUE
  754. END DecodeHeader;
  755. PROCEDURE DecodePacket(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR; VAR decState: DecoderState): LONGINT;
  756. (* VAR
  757. amplitude, booknumber, lookupOffset: LONGINT;
  758. lastFP: HUGEINT;
  759. codebook: Codebook; *)
  760. BEGIN
  761. (*
  762. IF (Trace IN Debug) THEN
  763. OGGUtilities.String("@VorbisCodec::FloorType0::DecodePacket()")
  764. END;
  765. amplitude := bufReader.GetBits(buf, amplitudeBits);
  766. IF (amplitude > 0) THEN
  767. booknumber := bufReader.GetBits(buf, OGGUtilities.ILog(numberOfBooks));
  768. codebook := decState.codec.codebooks[booknumber];
  769. decState.coeffVectorFP.Init;
  770. IF (booknumber >= decState.codec.codebookCnt) THEN
  771. IF (Error IN Debug) THEN
  772. OGGUtilities.String("error@VorbisCodec::Floor0::DecodePacket() - invalid codebook number")
  773. END;
  774. RETURN InvalidCodebookNumber
  775. END;
  776. lastFP := 0; (* lastval from docu [8] eliminated (seems strange) *)
  777. REPEAT
  778. lookupOffset := codebook.GetCodeword(bufReader, buf);
  779. codebook.GetVectorVQ(decState.tempVectorFP, lookupOffset);
  780. decState.tempVectorFP.Increase(lastFP);
  781. lastFP := decState.tempVectorFP.GetLast();
  782. decState.coeffVectorFP.Concatenate(decState.tempVectorFP);
  783. decState.tempVectorFP.Init;
  784. UNTIL (decState.coeffVectorFP.GetLen() >= order)
  785. ELSE
  786. RETURN ChannelNotUsed
  787. END;
  788. *)
  789. RETURN Ok
  790. END DecodePacket;
  791. PROCEDURE ComputeCurve(VAR decState: DecoderState; ch: LONGINT);
  792. (*
  793. VAR
  794. n, i, linearFloorValue, iterationCond: LONGINT;
  795. BEGIN
  796. IF (Trace IN Debug) THEN
  797. OGGUtilities.String("@FloorType0::ComputeCurve()")
  798. END;
  799. n := decState.codec.blocksizes[decState.mode.blockflag] DIV 2;
  800. (* calculate barkmap *)
  801. FOR i := 0 TO n-1 DO
  802. decState.barkMap[i] := Bark((rate * i) / (2 * n)) * barkMapSize DIV Bark(rate DIV 2);
  803. IF (barkMapSize - 1 < decState.barkMap[i]) THEN decState.barkMap[i] := barkMapSize - 1 END
  804. END;
  805. decState.barkMap[n] := -1;
  806. i := 0;
  807. LOOP
  808. IF (order MOD 2 = 1) THEN (* if order is odd *)
  809. (* TO DO: calculate p and q like this *)
  810. ELSE
  811. (* TO DO: calculate p and q like that *)
  812. END;
  813. (* TO DO: calculate linearFloorValue *)
  814. iterationCond := decState.barkMap[i];
  815. LOOP
  816. (* TO DO: output element i = linearFloorValue *)
  817. INC(i);
  818. IF (decState.barkMap[i] # iterationCond) THEN EXIT END (* else continue inner loop *)
  819. END;
  820. IF (i >= n) THEN EXIT END; (* else continue outer loop *)
  821. END
  822. *)
  823. END ComputeCurve;
  824. (* calculate a bark value *)
  825. PROCEDURE Bark(x: REAL): LONGINT;
  826. (*
  827. VAR res: REAL;
  828. BEGIN
  829. res := 13.1 * Math.arctan(0.00074 * x);
  830. res := res + 2.24 * Math.arctan(0.0000000158 * x * x);
  831. res := res + 0.0001 * x;
  832. RETURN ENTIER(res)
  833. *)
  834. END Bark;
  835. END FloorType0;
  836. *)
  837. FloorType1 = OBJECT(AbstractFloorType)
  838. VAR
  839. partitions*, multiplier*, rangebits*, maxClass*, values*: LONGINT;
  840. partitionClassList*: ARRAY Floor1PartitionClassListSize OF LONGINT;
  841. classDimensions*, classSubclasses*, classMasterbooks*: ARRAY Floor1ClassSize OF LONGINT;
  842. subclassBooks*: ARRAY Floor1ClassSize, Floor1SubclassSize OF LONGINT;
  843. xList*, xListSortPtr: ARRAY Floor1XListSize OF LONGINT;
  844. xListSize*, confNr*: LONGINT;
  845. PROCEDURE &Init*;
  846. VAR i: LONGINT;
  847. BEGIN
  848. FOR i := 0 TO Floor1XListSize - 1 DO
  849. xListSortPtr[i] := i
  850. END
  851. END Init;
  852. (** print to the logfile *)
  853. PROCEDURE Print;
  854. VAR i: LONGINT;
  855. BEGIN
  856. OGGUtilities.String("### FloorType1 ###");
  857. OGGUtilities.Var("partitions", partitions);
  858. OGGUtilities.Var("multiplier", multiplier);
  859. OGGUtilities.Var("rangebits", rangebits);
  860. OGGUtilities.Var("maxClass", maxClass);
  861. OGGUtilities.Var("values", values);
  862. OGGUtilities.Var("xListSize", xListSize);
  863. OGGUtilities.Array("partitionsClassList", partitionClassList);
  864. OGGUtilities.Array("classDimensions", classDimensions);
  865. OGGUtilities.Array("classSubclasses", classSubclasses);
  866. OGGUtilities.Array("classMasterbooks", classMasterbooks);
  867. OGGUtilities.Array("xList", xList);
  868. FOR i := 0 TO Floor1ClassSize - 1 DO
  869. OGGUtilities.Var("subclassBookNr", i);
  870. OGGUtilities.Array("subclassBook", subclassBooks[i])
  871. END;
  872. OGGUtilities.String("### END (FloorType1) ###"); OGGUtilities.String("")
  873. END Print;
  874. PROCEDURE ComputeCurve(VAR decState: DecoderState; ch: LONGINT);
  875. VAR
  876. i: LONGINT;
  877. range, lowNeighborOff, highNeighborOff, predicted, val, highroom, lowroom, room: LONGINT; (* step 1 variables *)
  878. n, hx, hy, lx, ly: LONGINT; (* step 2 variables *)
  879. BEGIN
  880. IF (Trace IN Debug) THEN
  881. OGGUtilities.String("@VorbisCodec::FloorType1::ComputeCurve()")
  882. END;
  883. (* step 1: amplitude value synthesis *)
  884. range := FloorRanges[multiplier-1];
  885. decState.floor1Step2Flag[0] := TRUE;
  886. decState.floor1Step2Flag[1] := TRUE;
  887. FOR i := 2 TO values - 1 DO
  888. lowNeighborOff := OGGUtilities.LowNeighbor(xList, i);
  889. highNeighborOff := OGGUtilities.HighNeighbor(xList, i);
  890. predicted := OGGUtilities.RenderPoint(xList[lowNeighborOff], decState.floor1Y[lowNeighborOff],
  891. xList[highNeighborOff], decState.floor1Y[highNeighborOff], xList[i]);
  892. val := decState.floor1Y[i];
  893. highroom := range - predicted;
  894. lowroom := predicted;
  895. IF (highroom < lowroom) THEN
  896. room := highroom*2
  897. ELSE
  898. room := lowroom*2
  899. END;
  900. IF (val # 0) THEN
  901. decState.floor1Step2Flag[lowNeighborOff] := TRUE;
  902. decState.floor1Step2Flag[highNeighborOff] := TRUE;
  903. decState.floor1Step2Flag[i] := TRUE;
  904. IF (val >= room) THEN
  905. IF (highroom > lowroom) THEN
  906. decState.floor1Y[i] := val - lowroom + predicted
  907. ELSE
  908. decState.floor1Y[i] := predicted - val + highroom - 1;
  909. END
  910. ELSE (* val < room *)
  911. IF (val MOD 2 = 1) THEN (* val is odd *)
  912. decState.floor1Y[i] := predicted - ((val + 1) DIV 2)
  913. ELSE (* val is even *)
  914. decState.floor1Y[i] := predicted + (val DIV 2)
  915. END
  916. END
  917. ELSE (* val = 0 *)
  918. decState.floor1Step2Flag[i] := FALSE;
  919. decState.floor1Y[i] := predicted
  920. END
  921. END;
  922. (* step 2: curve synthesis *)
  923. (* render the lines *)
  924. hx := 0; lx := 0;
  925. ly := decState.floor1Y[xListSortPtr[0]] * multiplier;
  926. FOR i := 1 TO values - 1 DO
  927. IF (decState.floor1Step2Flag[xListSortPtr[i]]) THEN
  928. hy := decState.floor1Y[xListSortPtr[i]] * multiplier;
  929. hx := xList[xListSortPtr[i]];
  930. OGGUtilities.RenderLine(lx, ly, hx, hy, decState.floor[ch].data);
  931. lx := hx;
  932. ly := hy
  933. END
  934. END;
  935. n := decState.n DIV 2;
  936. IF (hx < n) THEN
  937. OGGUtilities.RenderLine(hx, hy, n, hy, decState.floor[ch].data)
  938. END;
  939. IF (hx > n) THEN
  940. (* truncate floor-vector to n elements *)
  941. FOR i := n TO hx - 1 DO
  942. decState.floor[ch].data[i] := 0
  943. END
  944. END;
  945. (* inverse dB lookup and DotProduct with Residue *)
  946. FOR i := 0 TO n- 1 DO
  947. decState.floor[ch].data[i] := InverseDBLookup[decState.floor[ch].data[i]]
  948. END;
  949. END ComputeCurve;
  950. PROCEDURE DecodePacket(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR; VAR decState: DecoderState): LONGINT;
  951. VAR
  952. range, book, i, j, class, cdim, cbits, csub, cval, offset, nonzero: LONGINT;
  953. codebook: Codebook;
  954. BEGIN
  955. IF (Trace IN Debug) THEN
  956. OGGUtilities.String("@VorbisCodec::FloorType1::DecodePacket()")
  957. END;
  958. nonzero := bufReader.GetBits(buf, 1);
  959. IF (nonzero = 1) THEN
  960. range := FloorRanges[multiplier-1];
  961. decState.floor1Y[0] := bufReader.GetBits(buf, OGGUtilities.ILog(range-1));
  962. decState.floor1Y[1] := bufReader.GetBits(buf, OGGUtilities.ILog(range-1));
  963. offset := 2;
  964. FOR i := 0 TO partitions-1 DO
  965. class := partitionClassList[i];
  966. cdim := classDimensions[class];
  967. cbits := classSubclasses[class];
  968. csub := LSH(LONG(LONG(1)), cbits) - 1;
  969. cval := 0;
  970. IF (cbits > 0) THEN
  971. book := classMasterbooks[class];
  972. codebook := decState.codec.codebooks[book];
  973. cval := codebook.GetCodeword(bufReader, buf)
  974. END;
  975. FOR j := 0 TO cdim-1 DO
  976. book := subclassBooks[class, BIT.LAND(cval, csub)];
  977. cval := LSH(cval, -cbits); (* right shift cval by cbits *)
  978. IF (book >= 0) THEN
  979. codebook := decState.codec.codebooks[book];
  980. decState.floor1Y[j + offset] := codebook.GetCodeword(bufReader, buf)
  981. ELSE
  982. decState.floor1Y[j + offset] := 0
  983. END
  984. END; (* cdim *)
  985. INC(offset, cdim)
  986. END; (* partitions *)
  987. ELSE (* nonzero = 0 *)
  988. (* channel contains no audio energy in this frame *)
  989. IF (Trace IN Debug) THEN
  990. OGGUtilities.String("VorbisCodec::Floor1::DecodePacket() - RETURN ChannelNotUsed")
  991. END;
  992. RETURN ChannelNotUsed
  993. END;
  994. IF (Trace IN Debug) THEN
  995. OGGUtilities.String("VorbisCodec::Floor1::DecodePacket() - RETURN Ok")
  996. END;
  997. (* check if there happened an end-of-packet (and therefore an end-of-stream) situation *)
  998. IF bufReader.IsOk(buf) THEN RETURN Ok ELSE RETURN ChannelNotUsed END
  999. END DecodePacket;
  1000. (* decode floor1-description from codec setup header *)
  1001. PROCEDURE DecodeHeader(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  1002. VAR info: Info; VAR codec: CodecSetup): BOOLEAN;
  1003. VAR i, j, k: LONGINT;
  1004. BEGIN
  1005. partitions := bufReader.GetBits(buf, 5);
  1006. maxClass := -1;
  1007. FOR i := 0 TO partitions - 1 DO
  1008. partitionClassList[i] := bufReader.GetBits(buf, 4);
  1009. IF (partitionClassList[i] > maxClass) THEN maxClass := partitionClassList[i] END
  1010. END;
  1011. FOR i := 0 TO maxClass DO
  1012. classDimensions[i] := bufReader.GetBits(buf, 3) + 1;
  1013. classSubclasses[i] := bufReader.GetBits(buf, 2);
  1014. IF (classSubclasses[i] # 0) THEN
  1015. classMasterbooks[i] := bufReader.GetBits(buf, 8);
  1016. IF (classMasterbooks[i] > codec.codebookCnt) THEN
  1017. IF (Error IN Debug) THEN
  1018. OGGUtilities.String("error@VorbisCodec::Floor1::DecodeHeader() - invalid master-codebook number (too big)")
  1019. END;
  1020. RETURN FALSE
  1021. END
  1022. END;
  1023. FOR j := 0 TO (LSH(LONG(LONG(1)),classSubclasses[i])) - 1 DO
  1024. subclassBooks[i, j] := bufReader.GetBits(buf, 8) - 1;
  1025. IF (subclassBooks[i, j] > codec.codebookCnt) THEN
  1026. IF (Error IN Debug) THEN
  1027. OGGUtilities.String("error@VorbisCodec::Floor1::DecodeHeader() - invalid subclass-codebook number (too big)")
  1028. END;
  1029. RETURN FALSE
  1030. END
  1031. END
  1032. END;
  1033. multiplier := bufReader.GetBits(buf, 2) + 1;
  1034. rangebits := bufReader.GetBits(buf, 4);
  1035. (* version of jOrbis' *)
  1036. values := 0;
  1037. k := 0;
  1038. FOR j := 0 TO partitions - 1 DO
  1039. INC(values, classDimensions[partitionClassList[j]]);
  1040. WHILE (k < values) DO
  1041. xList[k + 2] := bufReader.GetBits(buf, rangebits);
  1042. INC(k)
  1043. END
  1044. END;
  1045. INC(values, 2);
  1046. xList[0] := 0;
  1047. xList[1] := LSH(LONG(LONG(1)), rangebits);
  1048. (* sort xList => do not apply, xList is used unsorted only: xListSortPtr *)
  1049. xListSize := 2;
  1050. FOR i := 0 TO partitions - 1 DO
  1051. INC(xListSize, classDimensions[partitionClassList[i]])
  1052. END;
  1053. OGGUtilities.EasySortRemember(xList, xListSortPtr, xListSize);
  1054. RETURN TRUE
  1055. END DecodeHeader;
  1056. END FloorType1;
  1057. (* container for values needed by ResiduePartitionProc *)
  1058. ResidueInfo = OBJECT
  1059. VAR
  1060. partitionSize, outputVectorNr, offset, codebookNr, ch: LONGINT;
  1061. PROCEDURE Init(partitionSize, outputVectorNr, offset, codebookNr, ch: LONGINT);
  1062. BEGIN
  1063. SELF.partitionSize := partitionSize;
  1064. SELF.outputVectorNr := outputVectorNr;
  1065. SELF.offset := offset;
  1066. SELF.codebookNr := codebookNr;
  1067. SELF.ch := ch
  1068. END Init;
  1069. END ResidueInfo;
  1070. Residue = OBJECT
  1071. VAR
  1072. begin, end, partitionSize, classifications, classbook: LONGINT;
  1073. cascades: ARRAY ResidueCascadeSize OF LONGINT;
  1074. books: ARRAY ResidueBookSize, 8 OF LONGINT;
  1075. nr: LONGINT;
  1076. decodemap, partword2: ARRAY 1024, PartwordSize OF LONGINT;
  1077. partword01: ARRAY MaxChannels, 1024, PartwordSize OF LONGINT;
  1078. (** print to the logfile *)
  1079. PROCEDURE Print;
  1080. VAR i: LONGINT;
  1081. BEGIN
  1082. OGGUtilities.String("### Residue ###");
  1083. OGGUtilities.Var("begin", begin);
  1084. OGGUtilities.Var("end", end);
  1085. OGGUtilities.Var("partitionSize", partitionSize);
  1086. OGGUtilities.Var("classifications", classifications);
  1087. OGGUtilities.Var("classbook", classbook);
  1088. OGGUtilities.Array("cascades", cascades);
  1089. FOR i := 0 TO ResidueBookSize - 1 DO
  1090. OGGUtilities.Var("books[i]", i);
  1091. OGGUtilities.Array("book", books[i])
  1092. END;
  1093. OGGUtilities.String("### END (Residue) ###"); OGGUtilities.String("")
  1094. END Print;
  1095. (* decode residue configuration from codec setup header (for all three residue types the same *)
  1096. PROCEDURE DecodeHeader(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  1097. VAR info: Info; VAR codec: CodecSetup): BOOLEAN;
  1098. VAR i, j, k, highBits, lowBits, bitFlag, val, mult, deco, partvals, dim: LONGINT;
  1099. tmpSet: SET;
  1100. BEGIN
  1101. begin := bufReader.GetBits(buf, 24);
  1102. end := bufReader.GetBits(buf, 24);
  1103. partitionSize := bufReader.GetBits(buf, 24) + 1;
  1104. classifications := bufReader.GetBits(buf, 6) + 1;
  1105. classbook := bufReader.GetBits(buf, 8);
  1106. IF (classbook > codec.codebookCnt) THEN
  1107. IF (Error IN Debug) THEN
  1108. OGGUtilities.String("error@VorbisCodec::Residue::DecodeHeader() - invalid class-codebook number (too big)")
  1109. END;
  1110. RETURN FALSE
  1111. END;
  1112. FOR i := 0 TO classifications - 1 DO
  1113. highBits := 0;
  1114. lowBits := bufReader.GetBits(buf, 3);
  1115. bitFlag := bufReader.GetBits(buf, 1);
  1116. IF (bitFlag = 1) THEN highBits := bufReader.GetBits(buf, 5) END;
  1117. cascades[i] := highBits * 8 + lowBits
  1118. END;
  1119. FOR i := 0 TO classifications - 1 DO
  1120. FOR j := 0 TO 7 DO
  1121. tmpSet := SYSTEM.VAL(SET, cascades[i]);
  1122. IF (j IN tmpSet) THEN
  1123. books[i, j] := bufReader.GetBits(buf, 8);
  1124. IF (books[i, j] > codec.codebookCnt) THEN
  1125. IF (Error IN Debug) THEN
  1126. OGGUtilities.String("error@VorbisCodec::Residue::DecodeHeader() - invalid codebook number (too big)")
  1127. END;
  1128. RETURN FALSE
  1129. END
  1130. ELSE
  1131. books[i, j] := ResidueBookUnused
  1132. END
  1133. END;
  1134. END;
  1135. (* decodemap *)
  1136. dim := codec.codebooks[classbook].dimensions;
  1137. partvals := OGGUtilities.Power(classifications, dim);
  1138. FOR j := 0 TO partvals - 1 DO
  1139. val := j;
  1140. mult := partvals DIV classifications;
  1141. FOR k := 0 TO dim - 1 DO
  1142. deco := val DIV mult;
  1143. val := val - deco * mult;
  1144. mult := mult DIV classifications;
  1145. decodemap[j, k] := deco;
  1146. END
  1147. END;
  1148. RETURN TRUE
  1149. END DecodeHeader;
  1150. (* decode residue vectors filling residue-array, residueNumbers will serve as an index into that array *)
  1151. PROCEDURE DecodePacket(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  1152. VAR decState: DecoderState; ch: LONGINT);
  1153. VAR
  1154. i, j, k, l, s, t: LONGINT;
  1155. samplesPerPartition, partitionsPerWord, n, partvals, offset, temp, vqclass, vqbook: LONGINT;
  1156. codebook: Codebook;
  1157. dim, used: LONGINT;
  1158. BEGIN
  1159. (* decodemap, macht jOrbis so. vielleicht funktionierts ja so ... *)
  1160. dim := decState.codec.codebooks[classbook].dimensions;
  1161. partvals := OGGUtilities.Power(classifications, dim);
  1162. FOR i := 0 TO ch - 1 DO
  1163. decState.residues[i].ZeroBuffer()
  1164. END;
  1165. IF decState.residueType # 2 THEN (* residue-type 0 or 1 *)
  1166. used := 0;
  1167. FOR t := 0 TO ch - 1 DO
  1168. IF ~decState.doNotDecode[t] THEN
  1169. INC(used)
  1170. END
  1171. END;
  1172. IF (used = 0) THEN
  1173. RETURN
  1174. ELSE
  1175. samplesPerPartition := partitionSize;
  1176. partitionsPerWord := decState.codec.codebooks[classbook].dimensions;
  1177. n := end - begin;
  1178. partvals := n DIV samplesPerPartition;
  1179. codebook := decState.codec.codebooks[classbook];
  1180. FOR s := 0 TO 7 DO
  1181. i := 0;
  1182. l := 0;
  1183. WHILE (i < partvals) DO
  1184. IF (s = 0) THEN
  1185. FOR j := 0 TO ch - 1 DO
  1186. temp := codebook.GetCodeword(bufReader, buf);
  1187. FOR t := 0 TO PartwordSize - 1 DO
  1188. partword01[j, l, t] := decodemap[temp, t];
  1189. END
  1190. END (* for ch *)
  1191. END; (* if s = 0 *)
  1192. k := 0;
  1193. WHILE ((k < partitionsPerWord) & (i < partvals)) DO
  1194. FOR j := 0 TO ch - 1 DO
  1195. IF ~decState.doNotDecode[j] THEN
  1196. offset := begin + i * samplesPerPartition;
  1197. vqclass := partword01[j, l, k];
  1198. vqbook := books[vqclass, s];
  1199. IF (vqbook # ResidueBookUnused) THEN
  1200. decState.resInfo.Init(samplesPerPartition, j, offset, vqbook, ch);
  1201. decState.residuePartitionProc[decState.residueType](bufReader, buf, decState)
  1202. END
  1203. END
  1204. END; (* for ch *)
  1205. INC(i);
  1206. INC(k);
  1207. END;
  1208. INC(l);
  1209. END (* while *)
  1210. END (* for s *)
  1211. END (* if doNotDecode *)
  1212. ELSE (* residue-type 2 *)
  1213. t := 0;
  1214. WHILE ((t # ch) & decState.doNotDecode[t]) DO
  1215. INC(t);
  1216. END;
  1217. IF (t = ch) THEN
  1218. (* no residue-vector need to be decoded *)
  1219. RETURN
  1220. END;
  1221. samplesPerPartition := partitionSize;
  1222. partitionsPerWord := decState.codec.codebooks[classbook].dimensions;
  1223. n := end - begin;
  1224. partvals := n DIV samplesPerPartition;
  1225. FOR s := 0 TO 7 DO (* s = pass *)
  1226. i := 0;
  1227. l := 0;
  1228. WHILE (i < partvals) DO
  1229. IF s = 0 THEN
  1230. codebook := decState.codec.codebooks[classbook];
  1231. temp := codebook.GetCodeword(bufReader, buf);
  1232. (* neue version mit decodemap *)
  1233. partword2[l] := decodemap[temp];
  1234. END; (* s = 0 *)
  1235. k := 0;
  1236. WHILE (k < partitionsPerWord) & (i < partvals) DO
  1237. offset := begin + i * samplesPerPartition;
  1238. vqclass := partword2[l, k];
  1239. vqbook := books[vqclass, s];
  1240. IF (vqbook # ResidueBookUnused) THEN
  1241. decState.resInfo.Init(samplesPerPartition, -1, offset, vqbook, ch);
  1242. decState.residuePartitionProc[decState.residueType](bufReader, buf, decState);
  1243. END;
  1244. INC(k);
  1245. INC(i)
  1246. END; (* while *)
  1247. INC(l)
  1248. END; (* while *)
  1249. END (* for s *)
  1250. END; (* if residueType *)
  1251. END DecodePacket;
  1252. END Residue;
  1253. Mapping = OBJECT
  1254. VAR
  1255. submaps*, couplingSteps*: LONGINT;
  1256. magnitude*, angle*: ARRAY MappingMagnitudeSize OF LONGINT;
  1257. mux*: ARRAY MappingMuxSize OF LONGINT;
  1258. submapFloor*, submapResidue*: ARRAY MappingSubmapFloorSize OF LONGINT;
  1259. nr*: LONGINT;
  1260. (** print to the logfile *)
  1261. PROCEDURE Print;
  1262. BEGIN
  1263. OGGUtilities.String("### Mapping ###");
  1264. OGGUtilities.Var("nr", nr);
  1265. OGGUtilities.Var("submaps", submaps);
  1266. OGGUtilities.Var("couplingSteps", couplingSteps);
  1267. OGGUtilities.Array("magnitude", magnitude);
  1268. OGGUtilities.Array("angle", angle);
  1269. OGGUtilities.Array("mux", mux);
  1270. OGGUtilities.Array("submapFloor", submapFloor);
  1271. OGGUtilities.Array("submapResidue", submapResidue);
  1272. OGGUtilities.String("### END (Mapping) ###"); OGGUtilities.String("")
  1273. END Print;
  1274. (* decode mapping configuration from codec setup header *)
  1275. PROCEDURE DecodeHeader(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  1276. VAR info: Info; VAR codec: CodecSetup): BOOLEAN;
  1277. VAR tmp, i: LONGINT;
  1278. BEGIN
  1279. IF (bufReader.GetBits(buf, 1) = 1) THEN
  1280. submaps := bufReader.GetBits(buf, 4) + 1
  1281. ELSE
  1282. submaps := 1
  1283. END;
  1284. IF (bufReader.GetBits(buf, 1) = 1) THEN
  1285. (* square polar channel mapping is in use *)
  1286. couplingSteps := bufReader.GetBits(buf, 8) + 1;
  1287. FOR i := 0 TO couplingSteps - 1 DO
  1288. magnitude[i] := bufReader.GetBits(buf, OGGUtilities.ILog(info.channels - 1));
  1289. angle[i] := bufReader.GetBits(buf, OGGUtilities.ILog(info.channels - 1));
  1290. IF (magnitude[i] = angle[i]) THEN
  1291. IF ((angle[i] > info.channels - 1) OR (magnitude[i] > info.channels - 1)) THEN
  1292. IF (Error IN Debug) THEN
  1293. OGGUtilities.String("error@VorbisCodec::Mapping::DecodeHeader() - invalid angle-magnitude-channels constelation")
  1294. END;
  1295. RETURN FALSE
  1296. END
  1297. END
  1298. END
  1299. ELSE
  1300. couplingSteps := 0
  1301. END;
  1302. IF (bufReader.GetBits(buf, 2) # 0) THEN
  1303. IF (Error IN Debug) THEN
  1304. OGGUtilities.String("error@VorbisCodec::Mapping::DecodeHeader() - reserved field wrongly in use")
  1305. END;
  1306. RETURN FALSE
  1307. END;
  1308. IF (submaps > 1) THEN
  1309. (* read channel multiplex settings *)
  1310. FOR i := 0 TO info.channels - 1 DO
  1311. mux[i] := bufReader.GetBits(buf, 4);
  1312. IF (mux[i] > submaps - 1) THEN
  1313. IF (Error IN Debug) THEN
  1314. OGGUtilities.String("error@VorbisCodec::Mapping::DecodeHeader() - current mux value is greater than submap-1")
  1315. END;
  1316. RETURN FALSE
  1317. END
  1318. END
  1319. END;
  1320. FOR i := 0 TO submaps - 1 DO
  1321. (* read the floor and residue numbers for use in decoding that supmap *)
  1322. tmp := bufReader.GetBits(buf, 8);
  1323. submapFloor[i] := bufReader.GetBits(buf, 8);
  1324. IF (submapFloor[i] > codec.floorCnt) THEN
  1325. IF (Error IN Debug) THEN
  1326. OGGUtilities.String("error@VorbisCodec::Mapping::DecodeHeader() - invalid floor number (too big)")
  1327. END;
  1328. RETURN FALSE
  1329. END;
  1330. submapResidue[i] := bufReader.GetBits(buf, 8);
  1331. IF (submapResidue[i] > codec.residueCnt) THEN
  1332. IF (Error IN Debug) THEN
  1333. OGGUtilities.String("error@VorbisCodec::Mapping::DecodeHeader() - invalid residue number (too big)")
  1334. END;
  1335. RETURN FALSE
  1336. END
  1337. END;
  1338. RETURN TRUE
  1339. END DecodeHeader;
  1340. END Mapping;
  1341. Mode = OBJECT
  1342. VAR blockflag*, windowType*, transformType*, mapping*: LONGINT;
  1343. (** print to the logfile *)
  1344. PROCEDURE Print;
  1345. BEGIN
  1346. OGGUtilities.String("### Mode ###");
  1347. OGGUtilities.Var("blockflag", blockflag);
  1348. OGGUtilities.Var("windowType", windowType);
  1349. OGGUtilities.Var("transformType", transformType);
  1350. OGGUtilities.Var("mapping", mapping);
  1351. OGGUtilities.String("### END (Mode) ###"); OGGUtilities.String("")
  1352. END Print;
  1353. (* decode mode configurations from codec setup header *)
  1354. PROCEDURE DecodeHeader(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  1355. VAR info: Info; VAR codec: CodecSetup): BOOLEAN;
  1356. BEGIN
  1357. blockflag := bufReader.GetBits(buf, 1);
  1358. windowType := bufReader.GetBits(buf, 16);
  1359. transformType := bufReader.GetBits(buf, 16);
  1360. mapping := bufReader.GetBits(buf, 8);
  1361. IF (mapping > codec.mappingCnt) THEN
  1362. IF (Error IN Debug) THEN
  1363. OGGUtilities.String("error@VorbisCodec::Mode::DecodeHeader() - illegal mapping number (too big)")
  1364. END;
  1365. RETURN FALSE
  1366. END;
  1367. IF ((windowType # 0) OR (transformType # 0)) THEN
  1368. IF (Error IN Debug) THEN
  1369. OGGUtilities.String("error@VorbisCodec::Mode::DecodeHeader() - illegal window- and/or transform-type")
  1370. END;
  1371. RETURN FALSE
  1372. END;
  1373. RETURN TRUE
  1374. END DecodeHeader;
  1375. END Mode;
  1376. Codebook = OBJECT
  1377. VAR
  1378. entries*, dimensions*, lookupType*, valueBits*, lookupValues*: LONGINT;
  1379. sequenceP*: BOOLEAN;
  1380. minimumValueFP*, deltaValueFP*: HUGEINT; (* fixed-point values *)
  1381. codewordLengths*: OGGUtilities.IntList;
  1382. multiplicandsFP, valuelistFP*: ARRAY MaxNumberOfMultiplicands OF HUGEINT;
  1383. huffmanTree*: OGGUtilities.HuffmanTree;
  1384. valid*: BOOLEAN;
  1385. cbNumber-: LONGINT;
  1386. PROCEDURE &Init*;
  1387. BEGIN
  1388. NEW(codewordLengths, NIL);
  1389. END Init;
  1390. (* print to the logfile *)
  1391. PROCEDURE Print;
  1392. BEGIN
  1393. OGGUtilities.String("### Codebook ###");
  1394. OGGUtilities.Var("cbNumber", cbNumber);
  1395. OGGUtilities.VarH("minimumValueFP", minimumValueFP);
  1396. OGGUtilities.VarH("deltaValueFP", deltaValueFP);
  1397. OGGUtilities.Var("entries", entries);
  1398. OGGUtilities.Var("dimensions", dimensions);
  1399. OGGUtilities.Var("lookupType", lookupType);
  1400. OGGUtilities.Var("valueBits", valueBits);
  1401. OGGUtilities.Var("lookupValues", lookupValues);
  1402. OGGUtilities.ArrayHugeLen("valuelist", valuelistFP, dimensions * entries);
  1403. OGGUtilities.ArrayHugeLen("multiplicands", multiplicandsFP, 32);
  1404. OGGUtilities.String("codewordLengths: ..."); codewordLengths.Print;
  1405. OGGUtilities.String("### END (Codebook) ###"); OGGUtilities.String("")
  1406. END Print;
  1407. (* decode codebooks from codec setup header *)
  1408. PROCEDURE DecodeHeader(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR; nr: LONGINT): BOOLEAN;
  1409. VAR
  1410. curEntry, curLength, number, i, j, k, sparsecount, indexDiv, index: LONGINT;
  1411. valFP, lastFP: HUGEINT;
  1412. newEntry: OGGUtilities.IntElement;
  1413. ordered, sparse, flag: BOOLEAN;
  1414. codewords: OGGUtilities.IntList;
  1415. BEGIN
  1416. IF (Trace IN Debug) THEN
  1417. OGGUtilities.String("@VorbisCodec::Codebook::DecodeHeader()")
  1418. END;
  1419. SELF.cbNumber := nr;
  1420. (* every codebook starts with a synch-pattern *)
  1421. IF (~(bufReader.GetBits(buf, 24) = CodebookSynchPattern)) THEN
  1422. IF (Error IN Debug) THEN
  1423. OGGUtilities.String("@VorbisCodec::Codebook::DecodeHeader() - error with synch-pattern of codebook")
  1424. END;
  1425. RETURN FALSE
  1426. END;
  1427. dimensions := bufReader.GetBits(buf, 16);
  1428. entries := bufReader.GetBits(buf, 24);
  1429. ordered := (bufReader.GetBit(buf) = 1);
  1430. IF ~ordered THEN
  1431. (* codeword-list not length-ordered, read each codeword one-by-one *)
  1432. sparse := (bufReader.GetBit(buf) = 1);
  1433. FOR i := 0 TO entries - 1 DO
  1434. IF sparse THEN
  1435. flag := (bufReader.GetBit(buf) = 1);
  1436. IF flag THEN
  1437. curLength := bufReader.GetBits(buf, 5) + 1
  1438. ELSE
  1439. curLength := UnusedCodebookEntry
  1440. END; (* IF flag set *)
  1441. ELSE
  1442. curLength := bufReader.GetBits(buf, 5) + 1;
  1443. END; (* IF sparse set *)
  1444. (* generate new entry and add it to codeword-lengths *)
  1445. IF (curLength > 31) THEN
  1446. KernelLog.String("ASSERTION failed - codeword too long"); KernelLog.Ln
  1447. END;
  1448. (* codewords mustn't be longer than a (positive) LONGINT *)
  1449. ASSERT (curLength <= 31);
  1450. NEW(newEntry, curLength);
  1451. codewordLengths.Append(newEntry)
  1452. END; (* FOR entries *)
  1453. ELSE
  1454. (* codeword-list is in ascending length order, read a number of codewords per length *)
  1455. (* and a total of 'entries' codewords *)
  1456. curEntry := 0;
  1457. curLength := bufReader.GetBits(buf, 5) + 1;
  1458. LOOP
  1459. number := bufReader.GetBits(buf, OGGUtilities.ILog(entries - curEntry));
  1460. IF (curLength > 31) THEN
  1461. KernelLog.String("ASSERTION failed - codeword too long"); KernelLog.Ln
  1462. END;
  1463. (* codewords mustn't be longer than a (positive) LONGINT *)
  1464. ASSERT (curLength <= 31);
  1465. FOR i := curEntry TO (curEntry + number - 1) DO
  1466. NEW(newEntry, curLength);
  1467. codewordLengths.Append(newEntry);
  1468. END;
  1469. curEntry := number + curEntry;
  1470. INC(curLength);
  1471. IF (curEntry > entries) THEN
  1472. IF (Error IN Debug) THEN
  1473. OGGUtilities.String("error@VorbisCodec::Codebook::DecodeHeader() - decoding-error (more codebook-entries than expected)");
  1474. RETURN FALSE
  1475. END
  1476. ELSIF curEntry = entries THEN
  1477. EXIT
  1478. (* ELSE
  1479. continue loop *)
  1480. END;
  1481. END; (* LOOP *)
  1482. END;
  1483. (* build a huffman-tree from the codewordLengths *)
  1484. NEW(huffmanTree);
  1485. sparsecount := CountValidCodewords(codewordLengths);
  1486. IF (huffmanTree.IsValidLengthList(codewordLengths, UnusedCodebookEntry)) THEN
  1487. MakeCodewords(codewordLengths, sparsecount, codewords);
  1488. huffmanTree.BuildTree(codewordLengths, codewords, UnusedCodebookEntry);
  1489. valid := TRUE
  1490. ELSIF (~huffmanTree.HasUsedEntries(codewordLengths, UnusedCodebookEntry)) THEN
  1491. valid := FALSE;
  1492. ELSE
  1493. valid := FALSE;
  1494. IF (Error IN Debug) THEN
  1495. OGGUtilities.w.String("error@VorbisCodec::Codebook::DecodeHeader() - invalid huffmanTree");
  1496. IF (huffmanTree.IsOverspecified(codewordLengths, UnusedCodebookEntry)) THEN
  1497. OGGUtilities.w.String(" (overspecified)")
  1498. ELSIF (huffmanTree.IsUnderspecified(codewordLengths, UnusedCodebookEntry)) THEN
  1499. OGGUtilities.w.String(" (underspecified)")
  1500. END;
  1501. OGGUtilities.String("");
  1502. END;
  1503. RETURN FALSE
  1504. END;
  1505. (* prepare for vector-lookup *)
  1506. lookupType := bufReader.GetBits(buf, 4);
  1507. IF (lookupType > 2) THEN
  1508. IF (Error IN Debug) THEN
  1509. OGGUtilities.String("error@VorbisCodec::Codebook::DecodeHeader() - decoding-error (invalid codebook-lookupType)")
  1510. END;
  1511. ELSIF (lookupType # 0) THEN
  1512. (* neue Version, a la jOrbis *)
  1513. minimumValueFP := OGGUtilities.Float32Unpack(bufReader.GetBits(buf, 32));
  1514. deltaValueFP := OGGUtilities.Float32Unpack(bufReader.GetBits(buf, 32));
  1515. valueBits := bufReader.GetBits(buf, 4) + 1;
  1516. sequenceP := (bufReader.GetBit(buf) = 1);
  1517. IF (lookupType = 1) THEN
  1518. lookupValues := OGGUtilities.Lookup1Values(entries, dimensions)
  1519. ELSIF (lookupType = 2) THEN
  1520. lookupValues := entries * dimensions
  1521. END;
  1522. IF (lookupValues > MaxNumberOfMultiplicands) THEN
  1523. KernelLog.String("ASSERTION failed - MaxNumberrOfMultiplicands too small"); KernelLog.Ln
  1524. END;
  1525. ASSERT (lookupValues <= MaxNumberOfMultiplicands);
  1526. FOR i := 0 TO lookupValues - 1 DO
  1527. multiplicandsFP[i] := OGGUtilities.ScaleUpHugeInt(bufReader.GetBits(buf, valueBits));
  1528. END;
  1529. IF (lookupType = 1) THEN
  1530. FOR j := 0 TO entries - 1 DO
  1531. lastFP := 0;
  1532. indexDiv := 1;
  1533. FOR k := 0 TO dimensions - 1 DO
  1534. index := (j DIV indexDiv) MOD lookupValues;
  1535. valFP := multiplicandsFP[index];
  1536. (* we need the absolute value *)
  1537. IF valFP < 0 THEN
  1538. valFP := -1 * valFP
  1539. END;
  1540. valFP := OGGUtilities.MultFP(valFP, deltaValueFP);
  1541. valFP := valFP + minimumValueFP + lastFP;
  1542. IF sequenceP THEN lastFP := valFP END;
  1543. valuelistFP[j * dimensions + k] := valFP;
  1544. indexDiv := indexDiv * lookupValues
  1545. END
  1546. END
  1547. ELSIF (lookupType = 2) THEN
  1548. FOR j := 0 TO entries - 1 DO
  1549. lastFP := 0;
  1550. FOR k := 0 TO dimensions - 1 DO
  1551. valFP := multiplicandsFP[j * dimensions + k];
  1552. (* we need the absolute value *)
  1553. IF valFP < 0 THEN
  1554. valFP := -1 * valFP
  1555. END;
  1556. valFP := OGGUtilities.MultFP(valFP, deltaValueFP);
  1557. valFP := valFP + minimumValueFP + lastFP;
  1558. IF sequenceP THEN lastFP := valFP END;
  1559. valuelistFP[j * dimensions + k] := valFP
  1560. END
  1561. END
  1562. END
  1563. END;
  1564. RETURN TRUE
  1565. END DecodeHeader;
  1566. (* read the next codeword from the buffer *)
  1567. PROCEDURE GetCodeword(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR): LONGINT;
  1568. VAR
  1569. bit: LONGINT;
  1570. hNode: OGGUtilities.HuffmanNode;
  1571. BEGIN
  1572. hNode := huffmanTree.start;
  1573. REPEAT
  1574. bit := bufReader.GetBits(buf, 1);
  1575. huffmanTree.GoLeftOrRight(hNode, bit)
  1576. UNTIL (hNode.IsLeaf());
  1577. RETURN hNode.GetValue();
  1578. END GetCodeword;
  1579. (* build the list of codewods from a list of lengths (algorithm from Tremor-source code) *)
  1580. PROCEDURE MakeCodewords(VAR list: OGGUtilities.IntList; sparsecount: LONGINT; VAR res: OGGUtilities.IntList);
  1581. VAR
  1582. i: HUGEINT; j, count, length, entry, tmp: LONGINT;
  1583. marker: ARRAY OGGUtilities.MaxCodewordLength OF LONGINT;
  1584. cur, curRes: OGGUtilities.IntElement;
  1585. BEGIN
  1586. NEW(res, NIL);
  1587. count := 0;
  1588. cur := list.start(OGGUtilities.IntElement);
  1589. FOR i := 0 TO list.length - 1 DO
  1590. length := cur.long;
  1591. IF (length # UnusedCodebookEntry) THEN
  1592. entry := marker[length];
  1593. tmp := LSH(entry, -1*length); (* <=> entry >> length in C *)
  1594. IF ((length < 32) & (tmp # 0)) THEN
  1595. IF (Error IN Debug) THEN
  1596. OGGUtilities.String("error@OGGUtilities::HuffmanTree::MakeCodewords() - lengths must specify an overpopulated tree");
  1597. END;
  1598. RETURN
  1599. END;
  1600. (* update ourself *)
  1601. NEW(curRes, entry);
  1602. res.Append(curRes);
  1603. INC(count);
  1604. (* look to see if the next shorter marker points to the node above. if so, update it and repeat *)
  1605. LOOP
  1606. FOR j := length TO 1 BY -1 DO
  1607. IF ((marker[j] MOD 2) = 1) THEN
  1608. IF (j = 1) THEN
  1609. INC(marker[1])
  1610. ELSE
  1611. marker[j] := LSH(marker[j-1], 1) (* <=> marker[j-1] << 1 *)
  1612. END;
  1613. EXIT
  1614. END;
  1615. INC(marker[j]);
  1616. END;
  1617. EXIT (* exit the loop anyway *)
  1618. END; (* LOOP *)
  1619. (* prune the tree; implicit invariant says alle the longer markers were dangling from our just-taken node.
  1620. dangle them from our *new* node *)
  1621. LOOP
  1622. FOR j := length+1 TO OGGUtilities.MaxCodewordLength-1 DO
  1623. IF (LSH(marker[j], -1) = entry) THEN
  1624. entry := marker[j];
  1625. marker[j] := LSH(marker[j-1], 1)
  1626. ELSE
  1627. EXIT
  1628. END
  1629. END;
  1630. EXIT
  1631. END; (* LOOP *)
  1632. ELSE
  1633. IF (sparsecount = 0) THEN INC(count) END
  1634. END; (* IF length > 0 *)
  1635. IF (cur.next # NIL) THEN cur := cur.next(OGGUtilities.IntElement) END
  1636. END(* FOR i=0..n-1 *)
  1637. END MakeCodewords;
  1638. (* count the number of valid codewords *)
  1639. PROCEDURE CountValidCodewords(VAR list: OGGUtilities.IntList): LONGINT;
  1640. VAR
  1641. cur: OGGUtilities.IntElement;
  1642. cnt: LONGINT;
  1643. BEGIN
  1644. cur := list.start(OGGUtilities.IntElement);
  1645. cnt := 0;
  1646. WHILE (cur # NIL) DO
  1647. IF (cur.long # UnusedCodebookEntry) THEN INC(cnt) END;
  1648. IF (cur.next = NIL) THEN cur := NIL ELSE cur := cur.next(OGGUtilities.IntElement) END
  1649. END;
  1650. RETURN cnt
  1651. END CountValidCodewords;
  1652. END Codebook;
  1653. CodecSetup = OBJECT
  1654. VAR
  1655. codebookCnt*, floorCnt*, residueCnt*, mappingCnt*, modeCnt*: LONGINT;
  1656. codebooks*: ARRAY MaxNumberOfCodebooks OF Codebook;
  1657. floorTypes*: ARRAY MaxNumberOfFloors OF LONGINT;
  1658. floorConf*: ARRAY MaxNumberOfFloors OF AbstractFloorType;
  1659. residueTypes*: ARRAY MaxNumberOfResidues OF LONGINT;
  1660. residues*: ARRAY MaxNumberOfResidues OF Residue;
  1661. mappings*: ARRAY MaxNumberOfMappings OF Mapping;
  1662. modes*: ARRAY MaxNumberOfModes OF Mode;
  1663. (** print all elements of the codec setup *)
  1664. PROCEDURE Print;
  1665. VAR i: LONGINT;
  1666. BEGIN
  1667. OGGUtilities.String("***** CodecSetup *****");
  1668. OGGUtilities.Var("codebookCnt", codebookCnt);
  1669. FOR i := 0 TO codebookCnt - 1 DO
  1670. OGGUtilities.Var("codebookNr", i); (* invalid codebooks are NIL *)
  1671. IF (codebooks[i] # NIL) THEN codebooks[i].Print END
  1672. END;
  1673. OGGUtilities.Array("floorTypes", floorTypes);
  1674. OGGUtilities.Var("floorCnt", floorCnt);
  1675. FOR i := 0 TO floorCnt - 1 DO OGGUtilities.Var("floorConfNr", i); floorConf[i].Print END;
  1676. OGGUtilities.Array("residueTypes", residueTypes);
  1677. OGGUtilities.Var("residueCnt", residueCnt);
  1678. FOR i := 0 TO residueCnt - 1 DO OGGUtilities.Var("residueNr", i); residues[i].Print END;
  1679. OGGUtilities.Var("mappingCnt", mappingCnt);
  1680. FOR i := 0 TO mappingCnt - 1 DO OGGUtilities.Var("mappingNr", i); mappings[i].Print END;
  1681. OGGUtilities.Var("modeCnt", modeCnt);
  1682. FOR i := 0 TO modeCnt - 1 DO OGGUtilities.Var("modeNr", i); modes[i].Print END;
  1683. OGGUtilities.String("***** END (CodecSetup) *****");
  1684. END Print;
  1685. END CodecSetup;
  1686. CommentListElement = OBJECT (OGGUtilities.ListElement)
  1687. VAR
  1688. length*: HUGEINT;
  1689. text*: ARRAY MaxCommentLength OF CHAR;
  1690. PROCEDURE Print;
  1691. BEGIN
  1692. KernelLog.String(text); KernelLog.Ln
  1693. END Print;
  1694. END CommentListElement;
  1695. CommentList = OBJECT (OGGUtilities.List)
  1696. VAR
  1697. vendorLength*: HUGEINT;
  1698. vendorString*: ARRAY MaxVendorLength OF CHAR;
  1699. (* other comment fields are already defined in OGGUtilities.List *)
  1700. PROCEDURE Print*;
  1701. VAR cur: CommentListElement;
  1702. BEGIN
  1703. IF cur = NIL THEN
  1704. cur := NIL
  1705. ELSE
  1706. cur := start(CommentListElement)
  1707. END;
  1708. WHILE cur # NIL DO
  1709. cur.Print();
  1710. IF cur.next = NIL THEN
  1711. cur := NIL
  1712. ELSE
  1713. cur := cur.next(CommentListElement)
  1714. END
  1715. END
  1716. END Print;
  1717. END CommentList;
  1718. Info = OBJECT
  1719. VAR
  1720. version, sampleRate: HUGEINT;
  1721. channels, bitrateMax, bitrateNom, bitrateMin: LONGINT;
  1722. blocksizes: ARRAY 2 OF LONGINT;
  1723. comment: CommentList;
  1724. PROCEDURE &Init*;
  1725. BEGIN
  1726. NEW(comment, NIL)
  1727. END Init;
  1728. PROCEDURE Print;
  1729. BEGIN
  1730. OGGUtilities.VarH("version",version);
  1731. OGGUtilities.VarH("sampleRate",sampleRate);
  1732. OGGUtilities.Var("channels",channels);
  1733. OGGUtilities.Var("bitrateMax",bitrateMax);
  1734. OGGUtilities.Var("bitrateNom",bitrateNom);
  1735. OGGUtilities.Var("bitrateMin",bitrateMin);
  1736. OGGUtilities.Var("blocksize0",blocksizes[0]);
  1737. OGGUtilities.Var("blocksize1",blocksizes[1])
  1738. END Print;
  1739. END Info;
  1740. (* buffer for the inverse MDCT *)
  1741. MdctBufferT = ARRAY OGGUtilities.MaxBlocksize DIV 2 OF HUGEINT;
  1742. MdctBuffer = POINTER TO MdctBufferT;
  1743. (** does nothing except printing arguments of Decode()-procedure *)
  1744. DumpDecoder* = OBJECT
  1745. VAR
  1746. packetNr-: LONGINT;
  1747. PROCEDURE &Init*;
  1748. BEGIN
  1749. packetNr := 0;
  1750. END Init;
  1751. PROCEDURE Decode*(VAR buf: ARRAY OF CHAR; pos, len: LONGINT; continuedPacket: BOOLEAN; VAR soundOutput: SoundOutput): BOOLEAN;
  1752. BEGIN
  1753. INC(packetNr);
  1754. IF (Trace IN Debug) THEN
  1755. OGGUtilities.String("@DumpDecoder::Decode()"); OGGUtilities.w.Ln;
  1756. END;
  1757. RETURN TRUE;
  1758. END Decode;
  1759. END DumpDecoder;
  1760. MdctObject = OBJECT
  1761. VAR
  1762. n, log2n: LONGINT;
  1763. bitrev: ARRAY OGGUtilities.MaxBlocksize DIV 4 OF LONGINT;
  1764. trig: ARRAY OGGUtilities.MaxBlocksize + (OGGUtilities.MaxBlocksize DIV 4) OF LONGINT;
  1765. x, w: MdctBuffer;
  1766. PROCEDURE &Init*(n: LONGINT);
  1767. VAR ae, ao, be, bo, ce, co, i, j, acc, mask, msb, notAcc: LONGINT;
  1768. float: LONGREAL;
  1769. BEGIN
  1770. NEW(x);
  1771. NEW(w);
  1772. SELF.n := n;
  1773. log2n := OGGUtilities.Log2n(n);
  1774. ae := 0;
  1775. ao := 1;
  1776. be := ae + n DIV 2;
  1777. bo := be + 1;
  1778. ce := be + n DIV 2;
  1779. co := ce + 1;
  1780. FOR i := 0 TO n DIV 4 - 1 DO
  1781. float := Math.cos((Math.pi / n) * 4 * i);
  1782. trig[ae + i * 2] := OGGUtilities.ScaleUp(float);
  1783. float := - Math.sin((Math.pi / n) * 4 * i);
  1784. trig[ao + i * 2] := OGGUtilities.ScaleUp(float);
  1785. float := Math.cos((Math.pi / (2 * n)) * (2 * i + 1));
  1786. trig[be + i * 2] := OGGUtilities.ScaleUp(float);
  1787. float := Math.sin((Math.pi / (2 * n)) * (2 * i + 1));
  1788. trig[bo + i * 2] := OGGUtilities.ScaleUp(float);
  1789. END;
  1790. FOR i := 0 TO n DIV 8 - 1 DO
  1791. float := Math.cos((Math.pi / n) * (4 * i + 2));
  1792. trig[ce + i * 2] := OGGUtilities.ScaleUp(float);
  1793. float := - Math.sin((Math.pi / n) * (4 * i + 2));
  1794. trig[co + i * 2] := OGGUtilities.ScaleUp(float);
  1795. END;
  1796. mask := LSH(LONG(LONG(1)), log2n - 1) - 1;
  1797. msb := LSH(LONG(LONG(1)), log2n - 2);
  1798. FOR i := 0 TO n DIV 8 - 1 DO
  1799. acc := 0;
  1800. j := 0;
  1801. WHILE (LSH(msb, -j) # 0) DO
  1802. IF ((BIT.LAND(LSH(msb, -j), i)) # 0) THEN
  1803. acc := BIT.LOR(acc, LSH(LONG(LONG(1)), j))
  1804. END;
  1805. INC(j)
  1806. END;
  1807. notAcc := BIT.LXOR(acc, -1); (* !acc, bitwise not *)
  1808. bitrev[i * 2] := BIT.LAND(notAcc, mask);
  1809. bitrev[i * 2 + 1] := acc
  1810. END
  1811. END Init;
  1812. (** performs the inverse MDCT *)
  1813. PROCEDURE Backward(VAR data: ARRAY OF HUGEINT);
  1814. VAR n2, n4, n8, inO, xO, a, i, xx, b, o1, o2, o3, o4: LONGINT;
  1815. temp1, temp2: HUGEINT;
  1816. BEGIN
  1817. n2 := n DIV 2;
  1818. n4 := n DIV 4;
  1819. n8 := n DIV 8;
  1820. (* step 1 and rotation *)
  1821. inO := 1;
  1822. xO := 0;
  1823. a := n2;
  1824. FOR i := 0 TO n8 - 1 DO
  1825. DEC(a, 2);
  1826. x[xO] := OGGUtilities.MultHugeFP(-data[inO + 2], trig[a + 1]);
  1827. DEC(x[xO], OGGUtilities.MultHugeFP(data[inO], trig[a]));
  1828. INC(xO);
  1829. x[xO] := OGGUtilities.MultHugeFP(data[inO], trig[a + 1]);
  1830. DEC(x[xO], OGGUtilities.MultHugeFP(data[inO + 2], trig[a]));
  1831. INC(xO);
  1832. INC(inO, 4);
  1833. END;
  1834. inO := n2 - 4;
  1835. FOR i := 0 TO n8 - 1 DO
  1836. DEC(a, 2);
  1837. x[xO] := OGGUtilities.MultHugeFP(data[inO], trig[a + 1]);
  1838. INC(x[xO], OGGUtilities.MultHugeFP(data[inO + 2], trig[a]));
  1839. INC(xO);
  1840. x[xO] := OGGUtilities.MultHugeFP(data[inO], trig[a]);
  1841. DEC(x[xO], OGGUtilities.MultHugeFP(data[inO + 2], trig[a + 1]));
  1842. INC(xO);
  1843. DEC(inO, 4);
  1844. END;
  1845. (* steps 2 to 7 *)
  1846. Kernel(n, n2, n4, n8);
  1847. xx := 0;
  1848. (* step 8 *)
  1849. b := n2;
  1850. o1 := n4;
  1851. o2 := o1 - 1;
  1852. o3 := n4 + n2;
  1853. o4 := o3 - 1;
  1854. FOR i := 0 TO n4 - 1 DO
  1855. temp1 := OGGUtilities.MultHugeFP(x[xx], trig[b + 1]);
  1856. DEC(temp1, OGGUtilities.MultHugeFP(x[xx + 1], trig[b]));
  1857. temp2 := OGGUtilities.MultHugeFP(x[xx], trig[b]);
  1858. INC(temp2, OGGUtilities.MultHugeFP(x[xx + 1], trig[b + 1]));
  1859. temp2 := -temp2;
  1860. data[o1] := -temp1;
  1861. data[o2] := temp1;
  1862. data[o3] := temp2;
  1863. data[o4] := temp2;
  1864. INC(o1);
  1865. DEC(o2);
  1866. INC(o3);
  1867. DEC(o4);
  1868. INC(xx, 2);
  1869. INC(b, 2)
  1870. END
  1871. END Backward;
  1872. (* Mdct-Kernel: xxx is an out-parameter *)
  1873. PROCEDURE Kernel(n, n2, n4, n8: LONGINT);
  1874. BEGIN
  1875. KernelStep1(n2, n4);
  1876. KernelStep2(n2);
  1877. KernelStep3(n2, n8);
  1878. END Kernel;
  1879. PROCEDURE Swap(VAR a,b: MdctBuffer);
  1880. VAR tmp: MdctBuffer;
  1881. BEGIN
  1882. tmp := a;
  1883. a := b;
  1884. b := tmp
  1885. END Swap;
  1886. (* step 2 *)
  1887. PROCEDURE KernelStep1(n2, n4: LONGINT);
  1888. VAR xA, xB, w2, a, i: LONGINT;
  1889. x0, x1: HUGEINT;
  1890. BEGIN
  1891. xA := n4;
  1892. xB := 0;
  1893. w2 := n4;
  1894. a := n2;
  1895. i := 0;
  1896. WHILE (i < n4) DO
  1897. x0 := x[xA] - x[xB];
  1898. w[w2 + i] := x[xA] + x[xB];
  1899. INC(xA);
  1900. INC(xB);
  1901. x1 := x[xA] - x[xB];
  1902. DEC(a, 4);
  1903. w[i] := OGGUtilities.MultHugeFP(x0, trig[a]);
  1904. INC(w[i], OGGUtilities.MultHugeFP(x1, trig[a + 1]));
  1905. INC(i);
  1906. w[i] := OGGUtilities.MultHugeFP(x1, trig[a]);
  1907. DEC(w[i], OGGUtilities.MultHugeFP(x0, trig[a + 1]));
  1908. w[w2 + i] := x[xA] + x[xB];
  1909. INC(xA);
  1910. INC(xB);
  1911. INC(i)
  1912. END;
  1913. END KernelStep1;
  1914. (* step 3 *)
  1915. PROCEDURE KernelStep2(n2: LONGINT);
  1916. VAR i, s, r, w1, w2, k0, k1, a, wbase, sEnd: LONGINT;
  1917. wA, wB, aev, aov: HUGEINT;
  1918. BEGIN
  1919. FOR i := 0 TO log2n - 3 - 1 DO
  1920. k0 := LSH(n, -(i + 2));
  1921. k1 := LSH(LONG(LONG(1)), i + 3);
  1922. wbase := n2 - 2;
  1923. a := 0;
  1924. FOR r := 0 TO (k0 DIV 4) - 1 DO
  1925. w1 := wbase;
  1926. w2 := w1 - (k0 DIV 2);
  1927. aev := trig[a];
  1928. aov := trig[a + 1];
  1929. DEC(wbase, 2);
  1930. INC(k0);
  1931. sEnd := LSH((LONG(LONG(2))), i);
  1932. FOR s := 0 TO sEnd - 1 DO
  1933. wB := w[w1] - w[w2];
  1934. x[w1] := w[w1] + w[w2];
  1935. INC(w1);
  1936. INC(w2);
  1937. wA := w[w1] - w[w2];
  1938. x[w1] := w[w1] + w[w2];
  1939. x[w2] := OGGUtilities.MultHugeFP(wA, aev);
  1940. DEC(x[w2], OGGUtilities.MultHugeFP(wB, aov));
  1941. x[w2 - 1] := OGGUtilities.MultHugeFP(wB, aev);
  1942. INC(x[w2 - 1], OGGUtilities.MultHugeFP(wA, aov));
  1943. DEC(w1, k0);
  1944. DEC(w2, k0)
  1945. END;
  1946. DEC(k0);
  1947. INC(a, k1)
  1948. END;
  1949. Swap(x, w)
  1950. END;
  1951. END KernelStep2;
  1952. (* step 4, 5, 6, 7 *)
  1953. PROCEDURE KernelStep3(n2, n8: LONGINT);
  1954. VAR c, bit, x1, x2, t1, t2, i: LONGINT;
  1955. wa, wb, wc, wd, wace, waco, wbce, wbco: HUGEINT;
  1956. BEGIN
  1957. c := n;
  1958. bit := 0;
  1959. x1 := 0;
  1960. x2 := n2 - 1;
  1961. FOR i := 0 TO n8 -1 DO
  1962. t1 := bitrev[bit];
  1963. INC(bit);
  1964. t2 := bitrev[bit];
  1965. INC(bit);
  1966. wa := w[t1] - w[t2 + 1];
  1967. wb := w[t1 - 1] + w[t2];
  1968. wc := w[t1] + w[t2 + 1];
  1969. wd := w[t1 - 1] - w[t2];
  1970. wace := OGGUtilities.MultHugeFP(wa, trig[c]);
  1971. wbce := OGGUtilities.MultHugeFP(wb, trig[c]);
  1972. INC(c);
  1973. waco := OGGUtilities.MultHugeFP(wa, trig[c]);
  1974. wbco := OGGUtilities.MultHugeFP(wb, trig[c]);
  1975. INC(c);
  1976. x[x1] := (wc + waco + wbce) DIV 2;
  1977. INC(x1);
  1978. x[x2] := (-wd + wbco - wace) DIV 2;
  1979. DEC(x2);
  1980. x[x1] := (wd + wbco - wace) DIV 2;
  1981. INC(x1);
  1982. x[x2] := (wc - waco - wbce) DIV 2;
  1983. DEC(x2)
  1984. END;
  1985. END KernelStep3;
  1986. END MdctObject;
  1987. (** structure for holding all necessary information for last step in the decode-process like #channels ... *)
  1988. SoundOutput = OBJECT
  1989. VAR
  1990. output: OGGUtilities.BufferPool;
  1991. nrOfBuffers, nrOfChannels, samplingRate, samplingResolution, volume: LONGINT;
  1992. minAmplitude, maxAmplitude: LONGINT;
  1993. initSoundChannelDone*: BOOLEAN;
  1994. channel: SoundDevices.Channel;
  1995. driver: SoundDevices.Driver;
  1996. PROCEDURE &Init*(nrOfBuffers, volume: LONGINT);
  1997. BEGIN
  1998. SELF.volume := volume;
  1999. SELF.nrOfBuffers := nrOfBuffers;
  2000. initSoundChannelDone := FALSE;
  2001. NEW(output, nrOfBuffers)
  2002. END Init;
  2003. PROCEDURE CloseSoundChannel*;
  2004. BEGIN
  2005. IF (Trace IN Debug) THEN
  2006. OGGUtilities.String("@SoundOutput::CloseSoundChannel()")
  2007. END;
  2008. IF channel # NIL THEN channel.Close() END
  2009. END CloseSoundChannel;
  2010. PROCEDURE InitSoundChannel*(nrOfChannels, samplingRate, samplingResolution: LONGINT);
  2011. VAR i, res: LONGINT;
  2012. buffer: SoundDevices.Buffer;
  2013. BEGIN
  2014. IF (Trace IN Debug) THEN
  2015. OGGUtilities.String("@SoundOutput::InitSoundChannel()")
  2016. END;
  2017. SELF.samplingRate := samplingRate;
  2018. SELF.samplingResolution := samplingResolution;
  2019. SELF.nrOfChannels := nrOfChannels;
  2020. SetMinMaxAmplitudes();
  2021. (* allocate sound-buffers *)
  2022. FOR i := 0 TO nrOfBuffers - 1 DO
  2023. NEW(buffer);
  2024. (* factor 2 because samplingResolution of 16 results in two 8-bit numbers *)
  2025. NEW(buffer.data, 2 * OGGUtilities.MaxBlocksize);
  2026. buffer.len := 2 * OGGUtilities.MaxBlocksize;
  2027. output.Append(buffer);
  2028. END;
  2029. driver := SoundDevices.GetDefaultDevice();
  2030. driver.OpenPlayChannel(channel, samplingRate, samplingResolution, nrOfChannels, SoundDevices.FormatPCM, res);
  2031. IF (volume < 0) THEN volume := 255 ELSIF (volume > 255) THEN volume := 255 END;
  2032. channel.SetVolume(volume);
  2033. IF (channel # NIL) THEN
  2034. channel.RegisterBufferListener(BufferListener);
  2035. channel.Start
  2036. END;
  2037. initSoundChannelDone := TRUE;
  2038. IF (Trace IN Debug) THEN
  2039. OGGUtilities.String("@END - SoundOutput::Init...()")
  2040. END
  2041. END InitSoundChannel;
  2042. PROCEDURE Output*(VAR input: ARRAY OF OGGUtilities.PCMBuffer; nrOfSamples: LONGINT);
  2043. VAR buffer: SoundDevices.Buffer;
  2044. i, ch, current, bufferPos: LONGINT;
  2045. BEGIN
  2046. IF (Trace IN Debug) THEN
  2047. OGGUtilities.String("@SoundOutput::Output()")
  2048. END;
  2049. buffer := output.Remove();
  2050. (* adjust buffer.len: samplingResolution of 16 results in twice as many 8-bit chars *)
  2051. buffer.len := nrOfSamples * nrOfChannels * (samplingResolution DIV 8);
  2052. bufferPos := 0;
  2053. FOR i := 0 TO nrOfSamples - 1 DO
  2054. FOR ch := 0 TO nrOfChannels - 1 DO
  2055. IF input[ch].data[i] # 0 THEN
  2056. current := GetSample(input[ch].data[i]);
  2057. ELSE
  2058. current := 0;
  2059. END;
  2060. IF (samplingResolution = 8) THEN
  2061. buffer.data[bufferPos] := CHR(current);
  2062. INC(bufferPos);
  2063. ELSIF (samplingResolution = 16) THEN
  2064. buffer.data[bufferPos] := CHR(current MOD 256);
  2065. buffer.data[bufferPos + 1] := CHR(current DIV 256);
  2066. INC(bufferPos, 2);
  2067. ELSE
  2068. (* no other samplingRate supported yet *)
  2069. END (* samplingRate *)
  2070. END (* nrOfChannels *)
  2071. END; (* nrOfSamples *)
  2072. channel.QueueBuffer(buffer);
  2073. channel.Start;
  2074. IF (Trace IN Debug) THEN
  2075. OGGUtilities.String("finished - SoundOutput::Output()")
  2076. END
  2077. END Output;
  2078. PROCEDURE SetMinMaxAmplitudes;
  2079. BEGIN
  2080. (* so far, only resolutions of 8 resp. 16 bits are supported *)
  2081. IF (samplingResolution = 8) THEN
  2082. maxAmplitude := 127;
  2083. minAmplitude := -128
  2084. ELSIF (samplingResolution = 16) THEN
  2085. maxAmplitude := 32767;
  2086. minAmplitude := -32768
  2087. END
  2088. END SetMinMaxAmplitudes;
  2089. (* calculate the current sample:
  2090. - scales down the fixpoint-number
  2091. - upsizes with the max amplitude
  2092. - does the clipping
  2093. *)
  2094. PROCEDURE GetSample(sample: HUGEINT): LONGINT;
  2095. VAR retSample: LONGINT;
  2096. BEGIN
  2097. (* can do a normal multiplication here *)
  2098. sample := sample * maxAmplitude;
  2099. retSample := OGGUtilities.ScaleDownRoundedHuge(sample);
  2100. IF retSample > maxAmplitude THEN
  2101. RETURN maxAmplitude
  2102. END;
  2103. IF retSample < minAmplitude THEN
  2104. RETURN minAmplitude
  2105. END;
  2106. RETURN retSample
  2107. END GetSample;
  2108. PROCEDURE BufferListener(buffer: SoundDevices.Buffer);
  2109. BEGIN
  2110. output.Append(buffer);
  2111. END BufferListener;
  2112. END SoundOutput;
  2113. (** writes a raw pcm-date to a file *)
  2114. TYPE FileOutput = OBJECT(SoundOutput)
  2115. VAR
  2116. filename-: ARRAY 64 OF CHAR;
  2117. filenameSet: BOOLEAN;
  2118. file: Files.File;
  2119. writer: Files.Writer;
  2120. frameCnt: LONGINT;
  2121. PROCEDURE &Init*(nrOfBuffers, volume: LONGINT);
  2122. BEGIN
  2123. filenameSet := FALSE;
  2124. file := NIL;
  2125. frameCnt := 0;
  2126. filename := ""
  2127. END Init;
  2128. PROCEDURE SetFilename*(VAR filename: ARRAY OF CHAR);
  2129. BEGIN
  2130. Strings.Append(SELF.filename, filename);
  2131. filenameSet := TRUE
  2132. END SetFilename;
  2133. PROCEDURE CloseSoundChannel*;
  2134. BEGIN
  2135. (* close file *)
  2136. IF file # NIL THEN
  2137. writer.Update;
  2138. Files.Register(file)
  2139. END
  2140. END CloseSoundChannel;
  2141. PROCEDURE InitSoundChannel*(localNrOfChannels, samplingRate, localSamplingResolution: LONGINT);
  2142. BEGIN
  2143. nrOfChannels := localNrOfChannels;
  2144. samplingResolution := localSamplingResolution;
  2145. SetMinMaxAmplitudes();
  2146. (* open a file *)
  2147. IF filenameSet THEN
  2148. file := Files.New(filename);
  2149. Files.OpenWriter(writer, file, 0);
  2150. END;
  2151. initSoundChannelDone := TRUE
  2152. END InitSoundChannel;
  2153. PROCEDURE Output*(VAR input: ARRAY OF OGGUtilities.PCMBuffer; nrOfSamples: LONGINT);
  2154. VAR i, ch, current: LONGINT;
  2155. BEGIN
  2156. INC(frameCnt);
  2157. IF file # NIL THEN
  2158. FOR i := 0 TO nrOfSamples - 1 DO
  2159. FOR ch := nrOfChannels - 1 TO 0 BY -1 DO
  2160. current := GetSample(input[ch].data[i]);
  2161. IF samplingResolution = 8 THEN
  2162. writer.Char(CHR(current))
  2163. ELSIF samplingResolution = 16 THEN
  2164. writer.RawInt(SHORT(current))
  2165. END
  2166. END
  2167. END
  2168. ELSE
  2169. KernelLog.String("could not write frame# "); KernelLog.Int(frameCnt, 0); KernelLog.Ln
  2170. END;
  2171. writer.Update
  2172. END Output;
  2173. END FileOutput;
  2174. VorbisDecoder* = OBJECT
  2175. VAR
  2176. buf: ARRAY MaxPageSize OF CHAR; (* why not this size? *)
  2177. pos, packetCnt: LONGINT;
  2178. appendPacket, firstDataPacket: BOOLEAN;
  2179. info: Info;
  2180. soundOutput: SoundOutput;
  2181. bufReader: BufferReader;
  2182. decState: DecoderState;
  2183. nrOfSamplesPlayed: LONGINT;
  2184. mdct: ARRAY 2 OF MdctObject; (* for each of the two blocksizes one Mdct *)
  2185. PROCEDURE &Init*;
  2186. BEGIN
  2187. pos := 0; packetCnt := 0;
  2188. firstDataPacket := TRUE;
  2189. frameCnt := 0;
  2190. NEW(info);
  2191. NEW(bufReader);
  2192. NEW(decState, info.channels)
  2193. END Init;
  2194. PROCEDURE ResetDecoder;
  2195. BEGIN
  2196. SELF.pos := 0
  2197. END ResetDecoder;
  2198. PROCEDURE Decode*(VAR buf: ARRAY OF CHAR; pos,len: LONGINT; continuedPacket:
  2199. BOOLEAN; VAR soundOutput: SoundOutput): LONGINT;
  2200. VAR
  2201. i, typeLen: LONGINT;
  2202. BEGIN
  2203. IF (Trace IN Debug) THEN
  2204. OGGUtilities.String("@Decode()"); OGGUtilities.w.Ln;
  2205. END;
  2206. (* adjust pos ('vorbis'-string appears only in the three header packets
  2207. or if it's a spanned packet over several pages and first byte with packet type will be used) *)
  2208. typeLen := OggStreamTypeLength + 1;
  2209. IF packetCnt > 2 THEN
  2210. DEC(pos, typeLen)
  2211. ELSIF packetCnt <= 2 THEN
  2212. IF ~appendPacket THEN
  2213. DEC(len, typeLen)
  2214. ELSE
  2215. DEC(pos, typeLen)
  2216. END
  2217. END;
  2218. (* reset BufferReader if it's a new packet *)
  2219. IF (~appendPacket) THEN bufReader.Init() END;
  2220. (* save buf to SELF.buf *)
  2221. i := 0;
  2222. WHILE (i # len) DO
  2223. SELF.buf[SELF.pos + i] := buf[pos + i]; INC(i)
  2224. END;
  2225. INC(SELF.pos, len);
  2226. (* current position is equal to the length of the logical packet *)
  2227. bufReader.SetLen(SELF.pos);
  2228. (* start decoding (if packet is not going to be continued) *)
  2229. IF ~continuedPacket THEN
  2230. appendPacket := FALSE;
  2231. RETURN StartDecode(soundOutput)
  2232. ELSE
  2233. appendPacket := TRUE;
  2234. RETURN Ok
  2235. END
  2236. END Decode;
  2237. (* start the decoding proccess *)
  2238. PROCEDURE StartDecode(VAR soundOutput: SoundOutput): LONGINT;
  2239. VAR res: LONGINT;
  2240. BEGIN
  2241. IF (Trace IN Debug) THEN
  2242. OGGUtilities.String("@StartDecode()")
  2243. END;
  2244. INC(packetCnt);
  2245. (* identification header *)
  2246. IF (packetCnt = 1) THEN
  2247. res := DecodeIdentificationHeader();
  2248. IF (Codec IN Debug) THEN info.Print END
  2249. (* comment header *)
  2250. ELSIF (packetCnt = 2) THEN
  2251. res := DecodeCommentHeader();
  2252. IF (Codec IN Debug) THEN info.comment.Print END
  2253. (* setup header *)
  2254. ELSIF (packetCnt = 3) THEN
  2255. res := DecodeSetupHeader(decState.codec);
  2256. decState.info := info;
  2257. IF ((info.bitrateMin > 0) & (info.bitrateMax > 0)) THEN
  2258. KernelLog.String("bitrates (min/avg/max): ");
  2259. KernelLog.Int(info.bitrateMin, 0);
  2260. KernelLog.String(" / ");
  2261. KernelLog.Int(info.bitrateNom, 0);
  2262. KernelLog.String(" / ");
  2263. KernelLog.Int(info.bitrateMax, 0);
  2264. KernelLog.String(" bps")
  2265. ELSE
  2266. KernelLog.String("average bitrate: ");
  2267. KernelLog.Int(info.bitrateNom, 0);
  2268. KernelLog.String(" bps")
  2269. END;
  2270. KernelLog.Ln;
  2271. IF (Codec IN Debug) THEN decState.codec.Print END
  2272. (* regular data packet *)
  2273. ELSE
  2274. IF ~decState.bufferAllocated THEN decState.AllocateBuffers(info.channels) END;
  2275. DecodeDataPacket(res);
  2276. IF ~soundOutput.initSoundChannelDone THEN
  2277. soundOutput.InitSoundChannel(decState.info.channels, SHORT(decState.info.sampleRate), DefaultSamplingResolution)
  2278. END;
  2279. IF ~firstDataPacket THEN
  2280. soundOutput.Output(decState.floor, decState.nrOfSamples);
  2281. INC(nrOfSamplesPlayed, decState.nrOfSamples);
  2282. ELSE
  2283. firstDataPacket := FALSE
  2284. END;
  2285. res := Ok
  2286. END;
  2287. ResetDecoder();
  2288. RETURN res
  2289. END StartDecode;
  2290. PROCEDURE DecodeIdentificationHeader(): LONGINT;
  2291. VAR
  2292. tmp: LONGINT;
  2293. set: SET;
  2294. BEGIN
  2295. (* version *)
  2296. info.version := bufReader.GetBits(buf, 32);
  2297. IF (info.version # 0) THEN RETURN ErrorIdentification END;
  2298. (* bitrate and samplerate *)
  2299. info.channels := bufReader.GetBits(buf, 8);
  2300. IF (info.channels > MaxChannels) THEN
  2301. KernelLog.String("ASSERTION failed - too much channels"); KernelLog.Ln
  2302. END;
  2303. ASSERT(info.channels <= MaxChannels);
  2304. info.sampleRate := bufReader.GetBits(buf, 32);
  2305. info.bitrateMax := bufReader.GetBits(buf, 32);
  2306. info.bitrateNom := bufReader.GetBits(buf, 32);
  2307. info.bitrateMin := bufReader.GetBits(buf, 32);
  2308. (* blocksizes *)
  2309. tmp := bufReader.GetBits(buf, 4);
  2310. info.blocksizes[0] := LSH(LONG(LONG(1)), tmp); (* blocksize0 := 2^tmp *)
  2311. tmp := bufReader.GetBits(buf, 4);
  2312. info.blocksizes[1] := LSH(LONG(LONG(1)), tmp); (* blocksize1 := 2^tmp *)
  2313. IF (info.blocksizes[0] > info.blocksizes[1]) THEN RETURN ErrorIdentification END;
  2314. (* framing bit *)
  2315. set := SYSTEM.VAL(SET,bufReader.GetBit(buf));
  2316. IF (set = {}) THEN RETURN ErrorIdentification END;
  2317. RETURN Ok
  2318. END DecodeIdentificationHeader;
  2319. PROCEDURE DecodeCommentHeader(): LONGINT;
  2320. VAR
  2321. i, j: HUGEINT;
  2322. commentElement: CommentListElement;
  2323. BEGIN
  2324. info.comment.vendorLength := bufReader.Get32UnsignedBits(buf);
  2325. IF (info.comment.vendorLength > MaxVendorLength) THEN
  2326. KernelLog.String("ASSERTION failed - vendorLength exceeds MaxVendorLength"); KernelLog.Ln
  2327. END;
  2328. ASSERT(info.comment.vendorLength <= MaxVendorLength);
  2329. i := 0;
  2330. FOR i := 0 TO info.comment.vendorLength-1 DO
  2331. info.comment.vendorString[i] := bufReader.GetChar(buf);
  2332. END;
  2333. info.comment.length := bufReader.Get32UnsignedBits(buf);
  2334. FOR i := 0 TO info.comment.length-1 DO
  2335. NEW(commentElement);
  2336. commentElement.length := bufReader.Get32UnsignedBits(buf);
  2337. FOR j := 0 TO commentElement.length-1 DO
  2338. commentElement.text[j] := bufReader.GetChar(buf);
  2339. END;
  2340. info.comment.Append(commentElement);
  2341. END;
  2342. info.comment.Print();
  2343. RETURN Ok
  2344. END DecodeCommentHeader;
  2345. PROCEDURE DecodeSetupHeader(VAR codec: CodecSetup): LONGINT;
  2346. VAR
  2347. tmp, i, timeCnt: LONGINT;
  2348. codebook: Codebook;
  2349. floor1: FloorType1;
  2350. residue: Residue;
  2351. mapping: Mapping;
  2352. mode: Mode;
  2353. BEGIN
  2354. (* read codebooks *)
  2355. codec.codebookCnt := bufReader.GetBits(buf, 8) + 1;
  2356. FOR i := 0 TO codec.codebookCnt - 1 DO
  2357. NEW(codebook);
  2358. IF ~codebook.DecodeHeader(bufReader, buf, i) THEN
  2359. IF (Error IN Debug) THEN
  2360. OGGUtilities.Var("#codebooks", codec.codebookCnt);
  2361. OGGUtilities.Var("error@VorbisCodec::Codebook::DecodeHeader() - error decoding codebookNr", i)
  2362. END;
  2363. RETURN ErrorSetup
  2364. END;
  2365. codec.codebooks[i] := codebook;
  2366. END;
  2367. (* time domain transforms *)
  2368. timeCnt := bufReader.GetBits(buf, 6) + 1;
  2369. FOR i := 0 TO timeCnt-1 DO
  2370. tmp := bufReader.GetBits(buf, 16);
  2371. IF (tmp # 0) THEN
  2372. IF (Error IN Debug) THEN
  2373. OGGUtilities.String("error@DecodeSetupHeader() - time domain transformation error (see Vorbis documentation for further details")
  2374. END;
  2375. RETURN ErrorSetup
  2376. END
  2377. END;
  2378. (* floor decode *)
  2379. codec.floorCnt := bufReader.GetBits(buf, 6) + 1;
  2380. FOR i := 0 TO codec.floorCnt - 1 DO
  2381. codec.floorTypes[i] := bufReader.GetBits(buf, 16);
  2382. IF codec.floorTypes[i] # 1 THEN
  2383. KernelLog.String("ASSERTTION failed - FloorType0 not yet implemented")
  2384. END;
  2385. (* see FloorType0 for reason *)
  2386. ASSERT(codec.floorTypes[i] = 1);
  2387. (*
  2388. IF (codec.floorTypes[i] = 0) THEN
  2389. NEW(floor0);
  2390. IF ~floor0.DecodeHeader(bufReader, buf, info) THEN
  2391. IF (Error IN Debug) THEN
  2392. OGGUtilities.String("error@DecodeSetupHeader() - error decoding floor0-header")
  2393. END;
  2394. RETURN ErrorSetup
  2395. END;
  2396. codec.floorConf[i] := floor0
  2397. *)
  2398. IF (codec.floorTypes[i] = 1) THEN
  2399. NEW(floor1);
  2400. IF ~floor1.DecodeHeader(bufReader, buf, info, codec) THEN
  2401. IF (Error IN Debug) THEN
  2402. OGGUtilities.String("error@DecodeSetupHeader() - error decoding floor type 1")
  2403. END;
  2404. RETURN ErrorSetup
  2405. END;
  2406. floor1.confNr := i;
  2407. codec.floorConf[i] := floor1
  2408. ELSE
  2409. IF (Error IN Debug) THEN
  2410. OGGUtilities.String("error@DecodeSetupHeader() - invalid floor type")
  2411. END;
  2412. RETURN ErrorSetup
  2413. END;
  2414. END;
  2415. (* residue decode *)
  2416. codec.residueCnt := bufReader.GetBits(buf, 6) + 1;
  2417. FOR i := 0 TO codec.residueCnt - 1 DO
  2418. codec.residueTypes[i] := bufReader.GetBits(buf, 16);
  2419. NEW(residue);
  2420. IF (codec.residueTypes[i] > 2) THEN
  2421. IF (Error IN Debug) THEN
  2422. OGGUtilities.String("error@DecodeSetupHeader() - invalid residue type")
  2423. END;
  2424. RETURN ErrorSetup
  2425. END;
  2426. NEW(residue);
  2427. IF ~residue.DecodeHeader(bufReader, buf, info, codec) THEN
  2428. IF (Error IN Debug) THEN
  2429. OGGUtilities.String("error@DecodeSetupHeader() - error decoding residue header")
  2430. END;
  2431. RETURN ErrorSetup;
  2432. END;
  2433. residue.nr := i;
  2434. codec.residues[i] := residue;
  2435. END;
  2436. (* mapping decode *)
  2437. codec.mappingCnt := bufReader.GetBits(buf, 6) + 1;
  2438. FOR i := 0 TO codec.mappingCnt - 1 DO
  2439. tmp := bufReader.GetBits(buf, 16);
  2440. IF (tmp # 0) THEN
  2441. IF (Error IN Debug) THEN
  2442. OGGUtilities.String("error@DecodeSetupHeader() - invalid mapping type")
  2443. END;
  2444. RETURN ErrorSetup;
  2445. END;
  2446. NEW(mapping);
  2447. IF ~mapping.DecodeHeader(bufReader, buf, info, codec) THEN
  2448. IF (Error IN Debug) THEN
  2449. OGGUtilities.String("error@DecodeSetupHeader() - error decoding mapping info")
  2450. END;
  2451. RETURN ErrorSetup
  2452. END;
  2453. mapping.nr := i;
  2454. codec.mappings[i] := mapping
  2455. END;
  2456. (* mode decode *)
  2457. codec.modeCnt := bufReader.GetBits(buf, 6) + 1;
  2458. FOR i := 0 TO codec.modeCnt - 1 DO
  2459. NEW(mode);
  2460. IF ~mode.DecodeHeader(bufReader, buf, info, codec) THEN
  2461. IF (Error IN Debug) THEN
  2462. OGGUtilities.String("error@DecodeSetupHeader() - error decoding mode info")
  2463. END;
  2464. RETURN ErrorSetup
  2465. END;
  2466. codec.modes[i] := mode
  2467. END;
  2468. (* check framing *)
  2469. tmp := bufReader.GetBits(buf, 1);
  2470. IF (tmp = 0) THEN
  2471. IF (Error IN Debug) THEN
  2472. OGGUtilities.String("error@DecodeSetupHeader() - framing-bit not set at the end of the codec-header")
  2473. END;
  2474. RETURN ErrorSetup
  2475. END;
  2476. RETURN Ok
  2477. END DecodeSetupHeader;
  2478. PROCEDURE DecodeDataPacket(res: LONGINT);
  2479. BEGIN
  2480. IF (Trace IN Debug) THEN OGGUtilities.String("@DecodeDataPacket()") END;
  2481. INC(frameCnt);
  2482. IF firstDataPacket THEN
  2483. (* do stuff that is required only once *)
  2484. NEW(mdct[0], info.blocksizes[0]);
  2485. NEW(mdct[1], info.blocksizes[1]);
  2486. NEW(decState.win, info.blocksizes[0], info.blocksizes[1])
  2487. END;
  2488. IF (bufReader.GetBits(buf, 1) # 0) THEN
  2489. (* it's not a vorbis data packet *)
  2490. IF (Error IN Debug) THEN
  2491. OGGUtilities.String("error@DecodeDataPacket() - wrong packet type (0 expected)")
  2492. END;
  2493. decState.nrOfSamples := 0;
  2494. res := NoDataPacket;
  2495. RETURN
  2496. END;
  2497. decState.nrOfSamples := WindowDecode(res);
  2498. IF res # Ok THEN RETURN END;
  2499. res := FloorCurveDecode();
  2500. NonzeroVectorPropagate();
  2501. ResidueDecode();
  2502. InverseCoupling();
  2503. DotProduct();
  2504. Mdct();
  2505. WindowData();
  2506. OverlapAdd();
  2507. CacheRightHandData();
  2508. res := Ok
  2509. END DecodeDataPacket;
  2510. (* cache the second half of the data and set the cache size correctly
  2511. (cached data starts at offset 0) *)
  2512. PROCEDURE CacheRightHandData;
  2513. VAR ch, i: LONGINT;
  2514. BEGIN
  2515. IF decState.preCached THEN
  2516. FOR ch := 0 TO decState.info.channels - 1 DO
  2517. FOR i := 0 TO decState.n DIV 2 - 1 DO
  2518. decState.rightCache[ch].data[i] := decState.residues[ch].data[i]
  2519. END
  2520. END
  2521. ELSE
  2522. FOR ch := 0 TO decState.info.channels - 1 DO
  2523. FOR i := decState.n DIV 2 TO decState.n - 1 DO
  2524. decState.rightCache[ch].data[i - decState.n DIV 2] := decState.floor[ch].data[i]
  2525. END
  2526. END
  2527. END;
  2528. decState.cacheSize := decState.n DIV 2
  2529. END CacheRightHandData;
  2530. (* overlap cached-data from previous frame with data from current frame
  2531. data starts at offset 0 *)
  2532. PROCEDURE OverlapAdd;
  2533. VAR ch, i, start: LONGINT;
  2534. BEGIN
  2535. FOR ch := 0 TO decState.info.channels - 1 DO
  2536. IF (decState.cacheSize = decState.n DIV 2) THEN
  2537. decState.preCached := FALSE;
  2538. (* previous frame had same size than current: just add cached data to current data *)
  2539. FOR i := 0 TO decState.n DIV 2 - 1 DO
  2540. INC(decState.floor[ch].data[i], decState.rightCache[ch].data[i]);
  2541. END
  2542. ELSIF (decState.cacheSize > decState.n DIV 2) THEN
  2543. (* previous frame was a LONG one: add current data to cached data and insert it as current data *)
  2544. start := (decState.cacheSize DIV 2) - (decState.n DIV 4);
  2545. decState.preCached := TRUE;
  2546. (* add floor data to cached data *)
  2547. FOR i := 0 TO decState.n DIV 2 - 1 DO
  2548. INC(decState.rightCache[ch].data[i + start], decState.floor[ch].data[i])
  2549. END;
  2550. (* pre-cache right floor-data *)
  2551. FOR i:= decState.n DIV 2 TO decState.n - 1 DO
  2552. decState.residues[ch].data[i - decState.n DIV 2] := decState.floor[ch].data[i]
  2553. END;
  2554. (* then copy all cached data to floor-data-vector *)
  2555. FOR i := 0 TO decState.cacheSize - 1 DO
  2556. decState.floor[ch].data[i] := decState.rightCache[ch].data[i]
  2557. END
  2558. ELSIF (decState.cacheSize < decState.n DIV 2) THEN
  2559. (* previous frame was a SHORT one: add cached data to current data *)
  2560. start := (decState.n DIV 4) - (decState.cacheSize DIV 2);
  2561. decState.preCached := FALSE;
  2562. FOR i := start TO start + decState.cacheSize - 1 DO
  2563. INC(decState.floor[ch].data[i], decState.rightCache[ch].data[i - start])
  2564. END;
  2565. (* now, data from [0..leftStart] is all zero, move data to offset 0 *)
  2566. FOR i := decState.win.leftStart TO decState.n DIV 2 - 1 DO
  2567. decState.floor[ch].data[i - decState.win.leftStart] := decState.floor[ch].data[i]
  2568. END
  2569. END
  2570. END
  2571. END OverlapAdd;
  2572. PROCEDURE WindowData;
  2573. VAR i: LONGINT;
  2574. BEGIN
  2575. FOR i := 0 TO decState.info.channels - 1 DO
  2576. decState.win.ApplyWindow(decState.floor[i].data, decState)
  2577. END
  2578. END WindowData;
  2579. PROCEDURE Mdct;
  2580. VAR i: LONGINT;
  2581. BEGIN
  2582. FOR i := 0 TO decState.info.channels - 1 DO
  2583. mdct[decState.mode.blockflag].Backward(decState.floor[i].data)
  2584. END
  2585. END Mdct;
  2586. PROCEDURE DotProduct;
  2587. VAR i, n, chptr: LONGINT;
  2588. residueVal, floorVal: HUGEINT;
  2589. BEGIN
  2590. (* multiply each element of the floor-vector with each element of the residue-vector *)
  2591. n := decState.n DIV 2;
  2592. FOR chptr := 0 TO decState.info.channels - 1 DO
  2593. IF ~decState.doNotDecode[chptr] THEN
  2594. FOR i := 0 TO n - 1 DO
  2595. residueVal := decState.residues[chptr].data[i];
  2596. floorVal := decState.floor[chptr].data[i];
  2597. (* arguments must be in this order *)
  2598. decState.floor[chptr].data[i] := OGGUtilities.MultDotProductFP(residueVal, floorVal);
  2599. END
  2600. ELSE
  2601. decState.floor[chptr].ZeroBuffer()
  2602. END
  2603. END
  2604. END DotProduct;
  2605. PROCEDURE InverseCoupling;
  2606. VAR
  2607. i, j, angIdx, magIdx: LONGINT;
  2608. newM, newA, m, a: HUGEINT; (* all fixed-point *)
  2609. BEGIN
  2610. IF (Trace IN Debug) THEN
  2611. OGGUtilities.String("@InverseCoupling()")
  2612. END;
  2613. FOR i := decState.mapping.couplingSteps - 1 TO 0 BY -1 DO
  2614. magIdx := decState.residueNumbers[decState.mapping.magnitude[i]];
  2615. angIdx := decState.residueNumbers[decState.mapping.angle[i]];
  2616. FOR j := 0 TO decState.n DIV 2 - 1 DO
  2617. m := decState.residues[magIdx].data[j];
  2618. a := decState.residues[angIdx].data[j];
  2619. IF (m > 0) THEN
  2620. IF (a > 0) THEN
  2621. newM := m; newA := m - a
  2622. ELSE
  2623. newA := m; newM := m + a
  2624. END
  2625. ELSE
  2626. IF (a > 0) THEN
  2627. newM := m; newA := m + a
  2628. ELSE
  2629. newA := m; newM := m - a
  2630. END
  2631. END;
  2632. decState.residues[magIdx].data[j] := newM;
  2633. decState.residues[angIdx].data[j] := newA;
  2634. END
  2635. END;
  2636. END InverseCoupling;
  2637. PROCEDURE ResidueDecode;
  2638. VAR i, j, residueNr, ch: LONGINT;
  2639. BEGIN
  2640. IF (Trace IN Debug) THEN
  2641. OGGUtilities.String("@ResidueDecode()")
  2642. END;
  2643. FOR i := 0 TO decState.mapping.submaps - 1 DO
  2644. ch := 0;
  2645. FOR j := 0 TO info.channels - 1 DO
  2646. (* if channel [j] is in submap [i] *)
  2647. IF (decState.mapping.mux[j] = i) THEN
  2648. decState.doNotDecode[j] := decState.noResidue[j];
  2649. INC(ch)
  2650. END
  2651. END;
  2652. residueNr := decState.mapping.submapResidue[i];
  2653. decState.residueType := decState.codec.residueTypes[residueNr];
  2654. decState.codec.residues[residueNr].DecodePacket(bufReader, buf, decState, ch);
  2655. ch := 0;
  2656. FOR j := 0 TO info.channels - 1 DO
  2657. (* if channel [j] is in submap [i] *)
  2658. IF (decState.mapping.mux[j] = i) THEN
  2659. decState.residueNumbers[j] := ch; (* used as an index for the residue-array *)
  2660. INC(ch);
  2661. END
  2662. END (* FOR info.channels *)
  2663. END (* FOR submaps *)
  2664. END ResidueDecode;
  2665. PROCEDURE NonzeroVectorPropagate;
  2666. VAR i, magnitude, angle: LONGINT;
  2667. BEGIN
  2668. IF (Trace IN Debug) THEN
  2669. OGGUtilities.String("@NonZeroVectorPropagate()")
  2670. END;
  2671. FOR i := 0 TO decState.mapping.couplingSteps - 1 DO
  2672. magnitude := decState.mapping.magnitude[i];
  2673. angle := decState.mapping.angle[i];
  2674. IF (~decState.noResidue[magnitude] OR ~decState.noResidue[angle]) THEN
  2675. decState.noResidue[magnitude] := FALSE;
  2676. decState.noResidue[angle] := FALSE
  2677. END
  2678. END
  2679. END NonzeroVectorPropagate;
  2680. PROCEDURE FloorCurveDecode(): LONGINT;
  2681. VAR
  2682. submapNumber, floorNumber, floorType, i, res: LONGINT;
  2683. floor: AbstractFloorType;
  2684. BEGIN
  2685. IF (Trace IN Debug) THEN
  2686. OGGUtilities.String("@FloorCurveDecode()")
  2687. END;
  2688. FOR i := 0 TO info.channels - 1 DO
  2689. submapNumber := decState.mapping.mux[i];
  2690. floorNumber := decState.mapping.submapFloor[submapNumber];
  2691. floorType := decState.codec.floorTypes[floorNumber];
  2692. floor := decState.codec.floorConf[floorNumber];
  2693. res := floor.DecodePacket(bufReader, buf, decState);
  2694. IF (res = Ok) THEN
  2695. floor.ComputeCurve(decState, i)
  2696. END;
  2697. decState.noResidue[i] := (res = ChannelNotUsed)
  2698. END;
  2699. RETURN res
  2700. END FloorCurveDecode;
  2701. (* calculate determining points of the window and return the amount of data to be returned *)
  2702. PROCEDURE WindowDecode(VAR res: LONGINT): LONGINT;
  2703. VAR modeNr, previousWindowFlag, nextWindowFlag, previousSize, currentSize: LONGINT;
  2704. BEGIN
  2705. IF (Trace IN Debug) THEN
  2706. OGGUtilities.String("@WindowDecode()")
  2707. END;
  2708. res := Ok;
  2709. modeNr := bufReader.GetBits(buf, OGGUtilities.ILog(decState.codec.modeCnt-1));
  2710. decState.mode := decState.codec.modes[modeNr];
  2711. decState.mapping := decState.codec.mappings[decState.mode.mapping];
  2712. decState.n := info.blocksizes[decState.mode.blockflag];
  2713. currentSize := decState.n;
  2714. (* if end-of-stream (=packet) then return an error *)
  2715. IF ~bufReader.IsOk(buf) THEN
  2716. res := ErrorWindowDecode;
  2717. RETURN 0
  2718. END;
  2719. IF (decState.mode.blockflag = 1) THEN
  2720. (* its a long window *)
  2721. previousWindowFlag := bufReader.GetBits(buf, 1);
  2722. nextWindowFlag := bufReader.GetBits(buf, 1)
  2723. ELSE
  2724. previousWindowFlag := 0;
  2725. nextWindowFlag := 0
  2726. END;
  2727. previousSize := decState.info.blocksizes[decState.lastWindowFlag];
  2728. decState.lastWindowFlag := decState.mode.blockflag;
  2729. decState.win.center := decState.n DIV 2;
  2730. IF ((decState.mode.blockflag = 1) & (previousWindowFlag = 0)) THEN
  2731. (* left side of window is a hybrid window for lapping with a short block *)
  2732. decState.win.leftStart := decState.n DIV 4 - info.blocksizes[0] DIV 4;
  2733. decState.win.leftEnd := decState.n DIV 4 + info.blocksizes[0] DIV 4;
  2734. decState.win.leftSize := info.blocksizes[0] DIV 2
  2735. ELSE
  2736. (* left side will have normal shape *)
  2737. decState.win.leftStart := 0;
  2738. decState.win.leftEnd := decState.win.center;
  2739. decState.win.leftSize := decState.n DIV 2
  2740. END;
  2741. IF ((decState.mode.blockflag = 1) & (nextWindowFlag = 0)) THEN
  2742. (* right side of window is a hybrid window for lapping with a short block *)
  2743. decState.win.rightStart := (decState.n * 3) DIV 4 - info.blocksizes[0] DIV 4;
  2744. decState.win.rightEnd := (decState.n * 3) DIV 4 + info.blocksizes[0] DIV 4;
  2745. decState.win.rightSize := info.blocksizes[0] DIV 2;
  2746. ELSE
  2747. (* right side will have normal shape *)
  2748. decState.win.rightStart := decState.win.center;
  2749. decState.win.rightEnd := decState.n;
  2750. decState.win.rightSize := decState.n DIV 2
  2751. END;
  2752. RETURN (previousSize + currentSize) DIV 4
  2753. END WindowDecode;
  2754. END VorbisDecoder;
  2755. (** DELEGATES *)
  2756. (* delegate for residue-type-specific packet decoding *)
  2757. ResiduePartitionProc = PROCEDURE {DELEGATE} (VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  2758. VAR decSate: DecoderState);
  2759. (* slope-function vorbis window-type 0 *)
  2760. SlopeFunction = PROCEDURE {DELEGATE} (x, n: LONGINT): REAL;
  2761. (** decodes len bytes from the buffer starting at pos to a valid soundOutput *)
  2762. Decoder* = PROCEDURE {DELEGATE} (VAR buf: ARRAY OF CHAR; pos, len: LONGINT; continuedPage: BOOLEAN;
  2763. VAR soundOutput: SoundOutput): LONGINT;
  2764. (* descending part of the window *)
  2765. PROCEDURE SlopeRight(x, n: LONGINT): REAL;
  2766. VAR res: REAL;
  2767. BEGIN
  2768. res := Math.sin( ((n - x - 0.5) / n) * (Math.pi / 2) );
  2769. res := Math.sin( res * res * Math.pi / 2);
  2770. RETURN res
  2771. END SlopeRight;
  2772. (* ascending part of the window *)
  2773. PROCEDURE SlopeLeft(x, n: LONGINT): REAL;
  2774. VAR res: REAL;
  2775. BEGIN
  2776. res := Math.sin( ((x + 0.5) / n) * (Math.pi / 2) );
  2777. res := Math.sin( res * res * Math.pi / 2);
  2778. RETURN res
  2779. END SlopeLeft;
  2780. (* for residue-type 0, used as a delegate *)
  2781. PROCEDURE ResiduePartitionProc0(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  2782. VAR decState: DecoderState);
  2783. VAR
  2784. step, i, j, o, offset, entry, outputVectorNr: LONGINT;
  2785. codebook: Codebook;
  2786. t: OGGUtilities.Vector;
  2787. resInfo: ResidueInfo;
  2788. BEGIN
  2789. resInfo := decState.resInfo;
  2790. NEW(t);
  2791. codebook := decState.codec.codebooks[resInfo.codebookNr];
  2792. offset := resInfo.offset;
  2793. outputVectorNr := resInfo.outputVectorNr;
  2794. step := resInfo.partitionSize DIV codebook.dimensions;
  2795. FOR i := 0 TO step - 1 DO
  2796. entry := codebook.GetCodeword(bufReader, buf);
  2797. t.Add(entry * codebook.dimensions)
  2798. END;
  2799. i := 0;
  2800. o := 0;
  2801. WHILE (i < codebook.dimensions) DO
  2802. FOR j := 0 TO step - 1 DO
  2803. INC(decState.residues[outputVectorNr].data[offset + o + j], codebook.valuelistFP[t.GetValueAt(j) + i])
  2804. END;
  2805. INC(o, step);
  2806. INC(i)
  2807. END
  2808. END ResiduePartitionProc0;
  2809. (* for residue-type 1, used as a delegate *)
  2810. PROCEDURE ResiduePartitionProc1(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  2811. VAR decState: DecoderState);
  2812. VAR
  2813. i, j, t, outputVectorNr, offset, entry: LONGINT;
  2814. codebook: Codebook;
  2815. resInfo: ResidueInfo;
  2816. BEGIN
  2817. resInfo := decState.resInfo;
  2818. codebook := decState.codec.codebooks[resInfo.codebookNr];
  2819. outputVectorNr := resInfo.outputVectorNr;
  2820. offset := resInfo.offset;
  2821. WHILE (i < resInfo.partitionSize) DO
  2822. entry := codebook.GetCodeword(bufReader, buf);
  2823. t := entry * codebook.dimensions;
  2824. j := 0;
  2825. WHILE (j < codebook.dimensions) DO
  2826. INC(decState.residues[outputVectorNr].data[offset + i], codebook.valuelistFP[t + j]);
  2827. INC(j);
  2828. INC(i)
  2829. END
  2830. END
  2831. END ResiduePartitionProc1;
  2832. (* for residue-type 2, used as a delegate *)
  2833. PROCEDURE ResiduePartitionProc2(VAR bufReader: BufferReader; VAR buf: ARRAY OF CHAR;
  2834. VAR decState: DecoderState);
  2835. VAR i, j, entry, chptr, t, ch, offset, n, dim: LONGINT;
  2836. cb: Codebook;
  2837. resInfo: ResidueInfo;
  2838. BEGIN
  2839. resInfo := decState.resInfo;
  2840. chptr := 0;
  2841. cb := decState.codec.codebooks[resInfo.codebookNr];
  2842. ch := resInfo.ch;
  2843. offset := resInfo.offset;
  2844. n := resInfo.partitionSize;
  2845. dim := cb.dimensions;
  2846. i := offset DIV resInfo.ch;
  2847. WHILE (i < (offset + n) DIV ch) DO
  2848. entry := cb.GetCodeword(bufReader, buf);
  2849. t := entry * dim;
  2850. FOR j := 0 TO dim - 1 DO
  2851. INC(decState.residues[chptr].data[i], cb.valuelistFP[t + j]);
  2852. INC(chptr);
  2853. IF (chptr = ch) THEN
  2854. chptr := 0;
  2855. INC(i)
  2856. END
  2857. END
  2858. END
  2859. END ResiduePartitionProc2;
  2860. (* lookup table for calculated floor values *)
  2861. PROCEDURE InitInverseDBLookup;
  2862. VAR InverseDBLookupReal: ARRAY 256 OF REAL;
  2863. i: LONGINT;
  2864. BEGIN
  2865. InverseDBLookupReal[0] := 0.00000010649863;
  2866. InverseDBLookupReal[1] := 0.00000011341951;
  2867. InverseDBLookupReal[2] := 0.00000012079015;
  2868. InverseDBLookupReal[3] := 0.00000012863978;
  2869. InverseDBLookupReal[4] := 0.00000013699951;
  2870. InverseDBLookupReal[5] := 0.00000014590251;
  2871. InverseDBLookupReal[6] := 0.00000015538408;
  2872. InverseDBLookupReal[7] := 0.00000016548181;
  2873. InverseDBLookupReal[8] := 0.00000017623575;
  2874. InverseDBLookupReal[9] := 0.00000018768855;
  2875. InverseDBLookupReal[10] := 0.00000019988561;
  2876. InverseDBLookupReal[11] := 0.0000002128753;
  2877. InverseDBLookupReal[12] := 0.00000022670913;
  2878. InverseDBLookupReal[13] := 0.00000024144197;
  2879. InverseDBLookupReal[14] := 0.00000025713223;
  2880. InverseDBLookupReal[15] := 0.00000027384213;
  2881. InverseDBLookupReal[16] := 0.00000029163793;
  2882. InverseDBLookupReal[17] := 0.00000031059021;
  2883. InverseDBLookupReal[18] := 0.00000033077411;
  2884. InverseDBLookupReal[19] := 0.00000035226968;
  2885. InverseDBLookupReal[20] := 0.00000037516214;
  2886. InverseDBLookupReal[21] := 0.00000039954229;
  2887. InverseDBLookupReal[22] := 0.0000004255068;
  2888. InverseDBLookupReal[23] := 0.00000045315863;
  2889. InverseDBLookupReal[24] := 0.00000048260743;
  2890. InverseDBLookupReal[25] := 0.00000051396998;
  2891. InverseDBLookupReal[26] := 0.00000054737065;
  2892. InverseDBLookupReal[27] := 0.00000058294187;
  2893. InverseDBLookupReal[28] := 0.00000062082472;
  2894. InverseDBLookupReal[29] := 0.00000066116941;
  2895. InverseDBLookupReal[30] := 0.00000070413592;
  2896. InverseDBLookupReal[31] := 0.00000074989464;
  2897. InverseDBLookupReal[32] := 0.00000079862701;
  2898. InverseDBLookupReal[33] := 0.0000008505263;
  2899. InverseDBLookupReal[34] := 0.00000090579828;
  2900. InverseDBLookupReal[35] := 0.00000096466216;
  2901. InverseDBLookupReal[36] := 0.0000010273513;
  2902. InverseDBLookupReal[37] := 0.0000010941144;
  2903. InverseDBLookupReal[38] := 0.0000011652161;
  2904. InverseDBLookupReal[39] := 0.0000012409384;
  2905. InverseDBLookupReal[40] := 0.0000013215816;
  2906. InverseDBLookupReal[41] := 0.0000014074654;
  2907. InverseDBLookupReal[42] := 0.0000014989305;
  2908. InverseDBLookupReal[43] := 0.0000015963394;
  2909. InverseDBLookupReal[44] := 0.0000017000785;
  2910. InverseDBLookupReal[45] := 0.0000018105592;
  2911. InverseDBLookupReal[46] := 0.0000019282195;
  2912. InverseDBLookupReal[47] := 0.0000020535261;
  2913. InverseDBLookupReal[48] := 0.0000021869758;
  2914. InverseDBLookupReal[49] := 0.0000023290978;
  2915. InverseDBLookupReal[50] := 0.0000024804557;
  2916. InverseDBLookupReal[51] := 0.0000026416497;
  2917. InverseDBLookupReal[52] := 0.000002813319;
  2918. InverseDBLookupReal[53] := 0.0000029961443;
  2919. InverseDBLookupReal[54] := 0.0000031908506;
  2920. InverseDBLookupReal[55] := 0.0000033982101;
  2921. InverseDBLookupReal[56] := 0.0000036190449;
  2922. InverseDBLookupReal[57] := 0.0000038542308;
  2923. InverseDBLookupReal[58] := 0.0000041047004;
  2924. InverseDBLookupReal[59] := 0.000004371447;
  2925. InverseDBLookupReal[60] := 0.0000046555282;
  2926. InverseDBLookupReal[61] := 0.0000049580707;
  2927. InverseDBLookupReal[62] := 0.000005280274;
  2928. InverseDBLookupReal[63] := 0.000005623416;
  2929. InverseDBLookupReal[64] := 0.0000059888572;
  2930. InverseDBLookupReal[65] := 0.0000063780469;
  2931. InverseDBLookupReal[66] := 0.0000067925283;
  2932. InverseDBLookupReal[67] := 0.0000072339451;
  2933. InverseDBLookupReal[68] := 0.0000077040476;
  2934. InverseDBLookupReal[69] := 0.0000082047;
  2935. InverseDBLookupReal[70] := 0.0000087378876;
  2936. InverseDBLookupReal[71] := 0.0000093057248;
  2937. InverseDBLookupReal[72] := 0.0000099104632;
  2938. InverseDBLookupReal[73] := 0.000010554501;
  2939. InverseDBLookupReal[74] := 0.000011240392;
  2940. InverseDBLookupReal[75] := 0.000011970856;
  2941. InverseDBLookupReal[76] := 0.000012748789;
  2942. InverseDBLookupReal[77] := 0.000013577278;
  2943. InverseDBLookupReal[78] := 0.000014459606;
  2944. InverseDBLookupReal[79] := 0.000015399272;
  2945. InverseDBLookupReal[80] := 0.000016400004;
  2946. InverseDBLookupReal[81] := 0.000017465768;
  2947. InverseDBLookupReal[82] := 0.000018600792;
  2948. InverseDBLookupReal[83] := 0.000019809576;
  2949. InverseDBLookupReal[84] := 0.000021096914;
  2950. InverseDBLookupReal[85] := 0.000022467911;
  2951. InverseDBLookupReal[86] := 0.000023928002;
  2952. InverseDBLookupReal[87] := 0.000025482978;
  2953. InverseDBLookupReal[88] := 0.000027139006;
  2954. InverseDBLookupReal[89] := 0.000028902651;
  2955. InverseDBLookupReal[90] := 0.000030780908;
  2956. InverseDBLookupReal[91] := 0.000032781225;
  2957. InverseDBLookupReal[92] := 0.000034911534;
  2958. InverseDBLookupReal[93] := 0.000037180282;
  2959. InverseDBLookupReal[94] := 0.000039596466;
  2960. InverseDBLookupReal[95] := 0.000042169667;
  2961. InverseDBLookupReal[96] := 0.00004491009;
  2962. InverseDBLookupReal[97] := 0.000047828601;
  2963. InverseDBLookupReal[98] := 0.000050936773;
  2964. InverseDBLookupReal[99] := 0.000054246931;
  2965. InverseDBLookupReal[100] := 0.000057772202;
  2966. InverseDBLookupReal[101] := 0.000061526565;
  2967. InverseDBLookupReal[102] := 0.000065524908;
  2968. InverseDBLookupReal[103] := 0.000069783085;
  2969. InverseDBLookupReal[104] := 0.000074317983;
  2970. InverseDBLookupReal[105] := 0.000079147585;
  2971. InverseDBLookupReal[106] := 0.00008429104;
  2972. InverseDBLookupReal[107] := 0.000089768747;
  2973. InverseDBLookupReal[108] := 0.000095602426;
  2974. InverseDBLookupReal[109] := 0.00010181521;
  2975. InverseDBLookupReal[110] := 0.00010843174;
  2976. InverseDBLookupReal[111] := 0.00011547824;
  2977. InverseDBLookupReal[112] := 0.00012298267;
  2978. InverseDBLookupReal[113] := 0.00013097477;
  2979. InverseDBLookupReal[114] := 0.00013948625;
  2980. InverseDBLookupReal[115] := 0.00014855085;
  2981. InverseDBLookupReal[116] := 0.00015820453;
  2982. InverseDBLookupReal[117] := 0.00016848555;
  2983. InverseDBLookupReal[118] := 0.00017943469;
  2984. InverseDBLookupReal[119] := 0.00019109536;
  2985. InverseDBLookupReal[120] := 0.00020351382;
  2986. InverseDBLookupReal[121] := 0.00021673929;
  2987. InverseDBLookupReal[122] := 0.00023082423;
  2988. InverseDBLookupReal[123] := 0.00024582449;
  2989. InverseDBLookupReal[124] := 0.00026179955;
  2990. InverseDBLookupReal[125] := 0.00027881276;
  2991. InverseDBLookupReal[126] := 0.00029693158;
  2992. InverseDBLookupReal[127] := 0.00031622787;
  2993. InverseDBLookupReal[128] := 0.00033677814;
  2994. InverseDBLookupReal[129] := 0.00035866388;
  2995. InverseDBLookupReal[130] := 0.00038197188;
  2996. InverseDBLookupReal[131] := 0.00040679456;
  2997. InverseDBLookupReal[132] := 0.00043323036;
  2998. InverseDBLookupReal[133] := 0.00046138411;
  2999. InverseDBLookupReal[134] := 0.00049136745;
  3000. InverseDBLookupReal[135] := 0.00052329927;
  3001. InverseDBLookupReal[136] := 0.00055730621;
  3002. InverseDBLookupReal[137] := 0.00059352311;
  3003. InverseDBLookupReal[138] := 0.00063209358;
  3004. InverseDBLookupReal[139] := 0.00067317058;
  3005. InverseDBLookupReal[140] := 0.000716917;
  3006. InverseDBLookupReal[141] := 0.0007635063;
  3007. InverseDBLookupReal[142] := 0.00081312324;
  3008. InverseDBLookupReal[143] := 0.00086596457;
  3009. InverseDBLookupReal[144] := 0.00092223983;
  3010. InverseDBLookupReal[145] := 0.00098217216;
  3011. InverseDBLookupReal[146] := 0.0010459992;
  3012. InverseDBLookupReal[147] := 0.0011139742;
  3013. InverseDBLookupReal[148] := 0.0011863665;
  3014. InverseDBLookupReal[149] := 0.0012634633;
  3015. InverseDBLookupReal[150] := 0.0013455702;
  3016. InverseDBLookupReal[151] := 0.0014330129;
  3017. InverseDBLookupReal[152] := 0.0015261382;
  3018. InverseDBLookupReal[153] := 0.0016253153;
  3019. InverseDBLookupReal[154] := 0.0017309374;
  3020. InverseDBLookupReal[155] := 0.0018434235;
  3021. InverseDBLookupReal[156] := 0.0019632195;
  3022. InverseDBLookupReal[157] := 0.0020908006;
  3023. InverseDBLookupReal[158] := 0.0022266726;
  3024. InverseDBLookupReal[159] := 0.0023713743;
  3025. InverseDBLookupReal[160] := 0.0025254795;
  3026. InverseDBLookupReal[161] := 0.0026895994;
  3027. InverseDBLookupReal[162] := 0.0028643847;
  3028. InverseDBLookupReal[163] := 0.0030505286;
  3029. InverseDBLookupReal[164] := 0.0032487691;
  3030. InverseDBLookupReal[165] := 0.0034598925;
  3031. InverseDBLookupReal[166] := 0.0036847358;
  3032. InverseDBLookupReal[167] := 0.0039241906;
  3033. InverseDBLookupReal[168] := 0.0041792066;
  3034. InverseDBLookupReal[169] := 0.004450795;
  3035. InverseDBLookupReal[170] := 0.0047400328;
  3036. InverseDBLookupReal[171] := 0.0050480668;
  3037. InverseDBLookupReal[172] := 0.0053761186;
  3038. InverseDBLookupReal[173] := 0.0057254891;
  3039. InverseDBLookupReal[174] := 0.0060975636;
  3040. InverseDBLookupReal[175] := 0.0064938176;
  3041. InverseDBLookupReal[176] := 0.0069158225;
  3042. InverseDBLookupReal[177] := 0.0073652516;
  3043. InverseDBLookupReal[178] := 0.0078438871;
  3044. InverseDBLookupReal[179] := 0.0083536271;
  3045. InverseDBLookupReal[180] := 0.0088964928;
  3046. InverseDBLookupReal[181] := 0.009474637;
  3047. InverseDBLookupReal[182] := 0.010090352;
  3048. InverseDBLookupReal[183] := 0.01074608;
  3049. InverseDBLookupReal[184] := 0.011444421;
  3050. InverseDBLookupReal[185] := 0.012188144;
  3051. InverseDBLookupReal[186] := 0.012980198;
  3052. InverseDBLookupReal[187] := 0.013823725;
  3053. InverseDBLookupReal[188] := 0.014722068;
  3054. InverseDBLookupReal[189] := 0.015678791;
  3055. InverseDBLookupReal[190] := 0.016697687;
  3056. InverseDBLookupReal[191] := 0.017782797;
  3057. InverseDBLookupReal[192] := 0.018938423;
  3058. InverseDBLookupReal[193] := 0.020169149;
  3059. InverseDBLookupReal[194] := 0.021479854;
  3060. InverseDBLookupReal[195] := 0.022875735;
  3061. InverseDBLookupReal[196] := 0.02436233;
  3062. InverseDBLookupReal[197] := 0.025945531;
  3063. InverseDBLookupReal[198] := 0.027631618;
  3064. InverseDBLookupReal[199] := 0.029427276;
  3065. InverseDBLookupReal[200] := 0.031339626;
  3066. InverseDBLookupReal[201] := 0.033376252;
  3067. InverseDBLookupReal[202] := 0.035545228;
  3068. InverseDBLookupReal[203] := 0.037855157;
  3069. InverseDBLookupReal[204] := 0.040315199;
  3070. InverseDBLookupReal[205] := 0.042935108;
  3071. InverseDBLookupReal[206] := 0.045725273;
  3072. InverseDBLookupReal[207] := 0.048696758;
  3073. InverseDBLookupReal[208] := 0.051861348;
  3074. InverseDBLookupReal[209] := 0.055231591;
  3075. InverseDBLookupReal[210] := 0.05882085;
  3076. InverseDBLookupReal[211] := 0.062643361;
  3077. InverseDBLookupReal[212] := 0.066714279;
  3078. InverseDBLookupReal[213] := 0.071049749;
  3079. InverseDBLookupReal[214] := 0.075666962;
  3080. InverseDBLookupReal[215] := 0.080584227;
  3081. InverseDBLookupReal[216] := 0.085821044;
  3082. InverseDBLookupReal[217] := 0.091398179;
  3083. InverseDBLookupReal[218] := 0.097337747;
  3084. InverseDBLookupReal[219] := 0.1036633;
  3085. InverseDBLookupReal[220] := 0.11039993;
  3086. InverseDBLookupReal[221] := 0.11757434;
  3087. InverseDBLookupReal[222] := 0.12521498;
  3088. InverseDBLookupReal[223] := 0.13335215;
  3089. InverseDBLookupReal[224] := 0.14201813;
  3090. InverseDBLookupReal[225] := 0.15124727;
  3091. InverseDBLookupReal[226] := 0.16107617;
  3092. InverseDBLookupReal[227] := 0.1715438;
  3093. InverseDBLookupReal[228] := 0.18269168;
  3094. InverseDBLookupReal[229] := 0.19456402;
  3095. InverseDBLookupReal[230] := 0.20720788;
  3096. InverseDBLookupReal[231] := 0.22067342;
  3097. InverseDBLookupReal[232] := 0.23501402;
  3098. InverseDBLookupReal[233] := 0.25028656;
  3099. InverseDBLookupReal[234] := 0.26655159;
  3100. InverseDBLookupReal[235] := 0.28387361;
  3101. InverseDBLookupReal[236] := 0.30232132;
  3102. InverseDBLookupReal[237] := 0.32196786;
  3103. InverseDBLookupReal[238] := 0.34289114;
  3104. InverseDBLookupReal[239] := 0.36517414;
  3105. InverseDBLookupReal[240] := 0.38890521;
  3106. InverseDBLookupReal[241] := 0.41417847;
  3107. InverseDBLookupReal[242] := 0.44109412;
  3108. InverseDBLookupReal[243] := 0.4697589;
  3109. InverseDBLookupReal[244] := 0.50028648;
  3110. InverseDBLookupReal[245] := 0.53279791;
  3111. InverseDBLookupReal[246] := 0.56742212;
  3112. InverseDBLookupReal[247] := 0.6042964;
  3113. InverseDBLookupReal[248] := 0.64356699;
  3114. InverseDBLookupReal[249] := 0.68538959;
  3115. InverseDBLookupReal[250] := 0.72993007;
  3116. InverseDBLookupReal[251] := 0.77736504;
  3117. InverseDBLookupReal[252] := 0.8278826;
  3118. InverseDBLookupReal[253] := 0.88168307;
  3119. InverseDBLookupReal[254] := 0.9389798;
  3120. InverseDBLookupReal[255] := 1;
  3121. (* scale the values according to current scale factor*)
  3122. FOR i := 0 TO 255 DO
  3123. InverseDBLookup[i] := OGGUtilities.ScaleUp(InverseDBLookupReal[i])
  3124. END
  3125. END InitInverseDBLookup;
  3126. (** Tools *)
  3127. (** start playing an ogg-stream
  3128. = possible arguments are:
  3129. - ogg/vorbis-file
  3130. - URL of a ogg/vorbis radio-station ( *.ogg or *.m3u)
  3131. = no need to stop any old sources
  3132. *)
  3133. PROCEDURE PlayURL*(url: Strings.String): BOOLEAN;
  3134. VAR
  3135. isWebStream: BOOLEAN;
  3136. dec: VorbisDecoder;
  3137. ogg: OggStreamReader;
  3138. f: Files.File;
  3139. fr: Files.Reader;
  3140. r : Streams.Reader;
  3141. output: SoundOutput;
  3142. rh : WebHTTP.RequestHeader;
  3143. h : WebHTTP.ResponseHeader;
  3144. res, volume, nrOfBuffers: LONGINT;
  3145. con : TCP.Connection;
  3146. outputFilename: ARRAY 64 OF CHAR;
  3147. timer: Kernel.Timer;
  3148. BEGIN
  3149. IF playing THEN
  3150. (* if it's already playing sth, stop old song and start new one *)
  3151. stopped := TRUE;
  3152. NEW(timer);
  3153. timer.Sleep(1000);
  3154. END;
  3155. IF ~playing THEN
  3156. (* prepare playing *)
  3157. NEW(dec);
  3158. nrOfBuffers := 32;
  3159. volume := 55;
  3160. NEW(output, nrOfBuffers, volume);
  3161. IF IsWebStream(url) THEN
  3162. (* streaming from the internet *)
  3163. IF IsM3UPlaylist(url) THEN
  3164. GetURLFromM3U(url)
  3165. END;
  3166. (* if interpretation failed (it's still a m3u) for some reason exit *)
  3167. IF IsM3UPlaylist(url) THEN
  3168. KernelLog.String("can not interpret m3u-playlist - exiting"); KernelLog.Ln;
  3169. RETURN FALSE
  3170. END;
  3171. KernelLog.String("playing ogg-radio: "); KernelLog.String(url^); KernelLog.Ln;
  3172. isWebStream := TRUE;
  3173. rh.useragent := "Bluebottle OGG Player/0.1";
  3174. WebHTTPClient.Get(url^, rh, con, h, r, res);
  3175. IF res # 0 THEN
  3176. KernelLog.String("Could not open stream");
  3177. KernelLog.Ln;
  3178. RETURN FALSE
  3179. END
  3180. ELSE
  3181. (* playing from a local file *)
  3182. isWebStream := FALSE;
  3183. KernelLog.String("playing ogg-soundfile: "); KernelLog.String(url^); KernelLog.Ln;
  3184. IF (output IS FileOutput) THEN
  3185. Strings.Append(outputFilename, url^);
  3186. Strings.Append(outputFilename, ".pcm");
  3187. KernelLog.String(outputFilename); KernelLog.Ln;
  3188. output(FileOutput).SetFilename(outputFilename)
  3189. END;
  3190. f := Files.Old(url^);
  3191. Files.OpenReader(fr, f, 0);
  3192. r := fr;
  3193. IF r = NIL THEN
  3194. KernelLog.String("Could not open file");
  3195. KernelLog.Ln;
  3196. RETURN FALSE
  3197. END
  3198. END;
  3199. (* allocate an OggStreamReader ... *)
  3200. NEW(ogg, r);
  3201. (* ... and start playing *)
  3202. res:= ogg.RegisterDecoder(dec.Decode, output, Vorbis);
  3203. IF res = Ok THEN
  3204. playing := TRUE;
  3205. res := ogg.Start();
  3206. playing := FALSE;
  3207. stopped := FALSE
  3208. END;
  3209. ogg.Stop()
  3210. (* finished playing *)
  3211. ELSE
  3212. KernelLog.String("is already playing something"); KernelLog.Ln
  3213. END;
  3214. (* close tcp-connection if any *)
  3215. IF con # NIL THEN
  3216. KernelLog.String("closing connection"); KernelLog.Ln;
  3217. con.Close()
  3218. END;
  3219. RETURN TRUE;
  3220. END PlayURL;
  3221. (** start playing an ogg-stream
  3222. = possible arguments ("command line") are:
  3223. - ogg/vorbis-file
  3224. - URL of a ogg/vorbis radio-station ( *.ogg or *.m3u)
  3225. = no need to stop any old sources
  3226. *)
  3227. PROCEDURE Play*(context : Commands.Context);
  3228. VAR
  3229. url: ARRAY 256 OF CHAR;
  3230. tmpBool: BOOLEAN;
  3231. BEGIN
  3232. context.arg.String(url);
  3233. tmpBool := PlayURL(Strings.NewString(url));
  3234. END Play;
  3235. PROCEDURE StopURL*;
  3236. BEGIN
  3237. stopped := TRUE
  3238. END StopURL;
  3239. PROCEDURE Stop*(context : Commands.Context);
  3240. BEGIN
  3241. StopURL();
  3242. context.out.String("Player stopped."); context.out.Ln;
  3243. END Stop;
  3244. PROCEDURE IsWebStream(VAR url: Strings.String): BOOLEAN;
  3245. BEGIN
  3246. RETURN Strings.Pos("http://", url^) > -1
  3247. END IsWebStream;
  3248. PROCEDURE IsM3UPlaylist(VAR url: Strings.String): BOOLEAN;
  3249. BEGIN
  3250. RETURN Strings.Pos(".m3u", url^) > -1
  3251. END IsM3UPlaylist;
  3252. PROCEDURE GetURLFromM3U(VAR url: Strings.String);
  3253. VAR res: LONGINT;
  3254. rh : WebHTTP.RequestHeader;
  3255. h : WebHTTP.ResponseHeader;
  3256. con : TCP.Connection;
  3257. r : Streams.Reader;
  3258. BEGIN
  3259. WebHTTPClient.Get(url^, rh, con, h, r, res);
  3260. r.Token(url^)
  3261. END GetURLFromM3U;
  3262. PROCEDURE Cleanup;
  3263. VAR
  3264. timer: Kernel.Timer;
  3265. BEGIN
  3266. NEW(timer);
  3267. stopped := TRUE;
  3268. (* give some time to close the sound-channel properly *)
  3269. timer.Sleep(2000);
  3270. END Cleanup;
  3271. BEGIN
  3272. Modules.InstallTermHandler(Cleanup);
  3273. FloorRanges[0] := 256;
  3274. FloorRanges[1] := 128;
  3275. FloorRanges[2] := 86;
  3276. FloorRanges[3] := 64;
  3277. OggS[0] := "O";
  3278. OggS[1] := "g";
  3279. OggS[2] := "g";
  3280. OggS[3] := "S";
  3281. nrOfPages := 0;
  3282. stopped := FALSE;
  3283. playing := FALSE;
  3284. InitInverseDBLookup;
  3285. OGGUtilities.InitLogger;
  3286. END OGGVorbisPlayer.
  3287. SystemTools.Free WMOGGPlayer OGGVorbisPlayer OGGUtilities ~
  3288. MixerComponents.MasterIncVol ~
  3289. MixerComponents.MasterDecVol ~
  3290. OGGVorbisPlayer.Stop ~
  3291. #Free Audio
  3292. OGGVorbisPlayer.Play epoq.ogg ~
  3293. OGGVorbisPlayer.Play hydrate.ogg ~
  3294. OGGVorbisPlayer.Play mistoftime.ogg ~
  3295. OGGVorbisPlayer.Play lumme.ogg ~