SOSCODEC.ASM 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. ;****************************************************************************
  19. ;*
  20. ;* Copyright (c) 1994, HMI, INC. All Rights Reserved
  21. ;*
  22. ;*---------------------------------------------------------------------------
  23. ;*
  24. ;* FILE
  25. ;* soscodec.asm
  26. ;*
  27. ;* DESCRIPTION
  28. ;* HMI SOS ADPCM compression/decompression.
  29. ;*
  30. ;* PROGRAMMER
  31. ;* Nick Skrepetos
  32. ;* Denzil E. Long, Jr. (Fixed bugs, rewrote for watcom)
  33. ;* Bill Petro (Added stereo support)
  34. ;* DATE
  35. ;* Febuary 15, 1995
  36. ;*
  37. ;*---------------------------------------------------------------------------
  38. ;*
  39. ;* PUBLIC
  40. ;*
  41. ;****************************************************************************
  42. IDEAL
  43. P386
  44. MODEL USE32 FLAT
  45. LOCALS ??
  46. STRUC sCompInfo
  47. lpSource DD ? ;Compressed data pointer
  48. lpDest DD ? ;Uncompressed data pointer
  49. dwCompSize DD ? ;Compressed size
  50. dwUnCompSize DD ? ;Uncompressed size
  51. wBitSize DW ? ;Bit size for decompression
  52. wChannels DW ? ;number of channels
  53. dwSampleIndex DD ? ;Index into sample
  54. dwPredicted DD ? ;Next predicted value
  55. dwDifference DD ? ;Difference from last sample
  56. wCodeBuf DW ? ;Holds 2 nibbles for decompression
  57. wCode DW ? ;Current 4 bit code
  58. wStep DW ? ;Step value in table
  59. wIndex DW ? ;Index into step table
  60. dwSampleIndex2 DD ? ;Index into sample
  61. dwPredicted2 DD ? ;Next predicted value
  62. dwDifference2 DD ? ;Difference from last sample
  63. wCodeBuf2 DW ? ;Holds 2 nibbles for decompression
  64. wCode2 DW ? ;Current 4 bit code
  65. wStep2 DW ? ;Step value in table
  66. wIndex2 DW ? ;Index into step table
  67. ENDS sCompInfo
  68. DATASEG
  69. ;* Index table for stepping into step table
  70. wCODECIndexTab DW -1,-1,-1,-1,2,4,6,8
  71. DW -1,-1,-1,-1,2,4,6,8
  72. ;Lookup table of replacement values
  73. ;The actual sound value is replaced with an index to lookup in this table
  74. ;The index only takes up a nibble(4bits) and represents an int(16bits)
  75. ;Essentially:
  76. ;Get a value
  77. ;compare it with the value before it
  78. ;find closest value in table and store the index into the table
  79. ;if i'm going down then negitize it
  80. ;go to next byte.
  81. ;Theory for stereo:
  82. ;1)handle stereo and mono in two seperate loops. cleaner...
  83. ;start at byte 0 and skip every other byte(or word) both write and read
  84. ;when we get done set start byte to 1 and do it again
  85. ;This table essentialy round off to closes values in 3 distinct bands
  86. ; precalculated and optimized(i guess) for human hearing.
  87. wCODECStepTab DW 7,8,9,10,11,12,13,14
  88. DW 16,17,19,21,23,25,28,31
  89. DW 34,37,41,45,50,55,60,66
  90. DW 73,80,88,97,107,118,130,143
  91. DW 157,173,190,209,230,253,279,307
  92. DW 337,371,408,449,494,544,598,658
  93. DW 724,796,876,963,1060,1166,1282,1411
  94. DW 1552,1707,1878,2066,2272,2499,2749,3024
  95. DW 3327,3660,4026,4428,4871,5358,5894,6484
  96. DW 7132,7845,8630,9493,10442,11487,12635,13899
  97. DW 15289,16818,18500,20350,22385,24623,27086,29794
  98. DW 32767
  99. dwCODECByteIndex DD 0 ; this is when to stop compressing
  100. dwCODECBytesProcessed DD 0 ; this is how many so far compressed
  101. dwCODECTempStep DD 0 ; tempory storage for step value
  102. wCODECMask DW 0 ; Current mask
  103. CODESEG
  104. ;****************************************************************************
  105. ;*
  106. ;* NAME
  107. ;* sosCODECInitStream - Initialize compression stream.
  108. ;*
  109. ;* SYNOPSIS
  110. ;* sosCODECInitStream(CompInfo)
  111. ;*
  112. ;* void sosCODECInitStream(_SOS_COMPRESS_INFO *);
  113. ;*
  114. ;* FUNCTION
  115. ;* Initialize compression stream for compression and decompression.
  116. ;*
  117. ;* INPUTS
  118. ;* CompInfo - Compression information structure.
  119. ;*
  120. ;* RESULT
  121. ;* NONE
  122. ;*
  123. ;****************************************************************************
  124. GLOBAL C sosCODECInitStream:NEAR
  125. PROC sosCODECInitStream C NEAR
  126. ARG sSOSInfo:NEAR PTR
  127. mov eax,[sSOSInfo]
  128. mov [(sCompInfo eax).wIndex],0 ; starting index 0
  129. mov [(sCompInfo eax).wStep],7 ; start with a step of 7
  130. mov [(sCompInfo eax).dwPredicted],0 ; no predicted value
  131. mov [(sCompInfo eax).dwSampleIndex],0 ;start at head of index
  132. mov [(sCompInfo eax).wIndex2],0 ; starting index 0
  133. mov [(sCompInfo eax).wStep2],7 ; start with a step of 7
  134. mov [(sCompInfo eax).dwPredicted2],0 ; no predicted value
  135. mov [(sCompInfo eax).dwSampleIndex2],0 ;start at head of index
  136. ret
  137. ENDP sosCODECInitStream
  138. ;****************************************************************************
  139. ;*
  140. ;* NAME
  141. ;* sosCODECCompressData - Compress audio data.
  142. ;*
  143. ;* SYNOPSIS
  144. ;* Size = sosCODECCompressData(CompInfo, NumBytes)
  145. ;*
  146. ;* long sosCODECCompressData(_SOS_COMPRESS_INFO *, long);
  147. ;*
  148. ;* FUNCTION
  149. ;* Compress an audio data stream into 4:1 ADPCM. 16 bit data is
  150. ;* compressed 4:1, 8 bit data is compressed 2:1.
  151. ;*
  152. ;* INPUTS
  153. ;* CompInfo - Pointer to initialized compress information structure.
  154. ;* NumBytes - Number of bytes to compress.
  155. ;*
  156. ;* RESULT
  157. ;* Size - Size of compressed data.
  158. ;*
  159. ;****************************************************************************
  160. GLOBAL C sosCODECCompressData:NEAR
  161. PROC sosCODECCompressData C NEAR
  162. ARG sSOSInfo:NEAR PTR
  163. ARG wBytes:DWORD
  164. push esi
  165. push edi
  166. push ebx
  167. push ecx
  168. push edx
  169. ;*---------------------------------------------------------------------------
  170. ;* Initialize
  171. ;*---------------------------------------------------------------------------
  172. mov ebx,[sSOSInfo]
  173. mov eax,[wBytes]
  174. mov [dwCODECBytesProcessed],eax
  175. mov [(sCompInfo ebx).dwSampleIndex],0 ;start at head of index
  176. mov [(sCompInfo ebx).dwSampleIndex2],0 ;start at head of index
  177. ; Check for 16 bit decompression
  178. cmp [(sCompInfo ebx).wBitSize],16 ;16 bit requested?
  179. jne short ??skipByteDivide ;no so skip divide
  180. shr eax,1 ;divide size by 2
  181. ??skipByteDivide:
  182. mov [dwCODECByteIndex],eax
  183. mov esi,[(sCompInfo ebx).lpSource] ;ESI = source
  184. mov edi,[(sCompInfo ebx).lpDest] ;EDI = dest
  185. cmp [(sCompInfo ebx).wChannels],2 ;stereo check
  186. je ??mainloopl
  187. ;------------------------------------------------------------------------
  188. ; Mono start
  189. ;------------------------------------------------------------------------
  190. ??mainloop:
  191. cmp [(sCompInfo ebx).wBitSize],16 ;are we doing 16 bit
  192. jne short ??input8Bit ;no. goto 8 bit input
  193. movsx eax,[word ptr esi] ;Get 16bit sample
  194. add esi,2
  195. jmp short ??computeDiff ;skip 8 bit load
  196. ??input8Bit:
  197. mov ah,[esi] ;Get 8bit sample
  198. inc esi
  199. xor al,al ;zero out low byte
  200. xor ah,80h ;flip sign bit
  201. movsx eax,ax
  202. ??computeDiff:
  203. movsx ecx,[word ptr (sCompInfo ebx).dwPredicted]
  204. sub eax,ecx ;sample-predicted
  205. xor ecx,ecx ;clear ecx
  206. cmp eax,0 ;Diff > = 0
  207. jge ??positive
  208. neg eax ;else difference= -difference
  209. or ecx,8 ;set nibble sign bit in ecx
  210. ??positive:
  211. mov [(sCompInfo ebx).wCode],cx ;Store code
  212. movsx ecx,[(sCompInfo ebx).wStep] ;Get step value
  213. mov [dwCODECTempStep],ecx
  214. mov edx,4 ;mask value (i think)
  215. mov ecx,3 ;loop count
  216. ??quantizeLoop:
  217. cmp eax,[dwCODECTempStep] ;Diff < step ?
  218. jl short ??nextQLoop ;goto nextQloop
  219. ; OR in mask value into code and adjust difference.
  220. or [(sCompInfo ebx).wCode],dx ;else or mask into code
  221. sub eax,[dwCODECTempStep] ;difference-=tempstep
  222. ??nextQLoop:
  223. shr [dwCODECTempStep],1 ; TempStep>>=1
  224. shr edx,1 ; mask>>=1
  225. loop ??quantizeLoop ; back to quatize loop
  226. ;-----------------------------------------------------------------------------------------
  227. ; now i'v got the new diff and code is masked right
  228. ;-----------------------------------------------------------------------------------------
  229. ; store off new difference value
  230. mov [(sCompInfo ebx).dwDifference],eax
  231. ; determine if sample index is even or odd.
  232. ; this will determine if we need to get a new token or not.
  233. test [(sCompInfo ebx).dwSampleIndex],1 ; is it even? (starts at 0)
  234. jne short ??storeToken ; if so goto store token
  235. ; else its odd so get token
  236. xor eax,eax
  237. mov ax,[(sCompInfo ebx).wCode] ;ax=wCode
  238. and eax,0Fh ;and off high nibble
  239. mov [(sCompInfo ebx).wCodeBuf],ax ;wCodeBuf=ax
  240. jmp short ??calcDifference ;goto calcDifference
  241. ??storeToken:
  242. ; fetch new token
  243. xor eax,eax
  244. mov ax,[(sCompInfo ebx).wCode] ;ax=code
  245. shl eax,4 ;shift low nibble to high
  246. or ax,[(sCompInfo ebx).wCodeBuf] ;or in the stored nibble
  247. mov [edi],al ;*dest=al
  248. inc edi ;dest++
  249. ??calcDifference:
  250. mov [(sCompInfo ebx).dwDifference],0 ;dwDifference=0
  251. xor ecx,ecx ;ecx=0
  252. mov cx,[(sCompInfo ebx).wStep] ;cx=Step
  253. xor eax,eax ;eax=0
  254. mov ax,[(sCompInfo ebx).wCode] ;ax=wCode
  255. test eax,4 ;Check 0100
  256. je short ??no4
  257. add [(sCompInfo ebx).dwDifference],ecx ;difference+=step
  258. ??no4:
  259. test eax,2 ;Check 0010
  260. je short ??no2
  261. mov edx,ecx ;edx=wStep
  262. shr edx,1 ;edx>>1
  263. add [(sCompInfo ebx).dwDifference],edx ;Difference=wstep>>1
  264. ??no2:
  265. test eax,1 ;Check 0001
  266. je short ??no1
  267. mov edx,ecx ;edx=wStep
  268. shr edx,2 ;edx>>2
  269. add [(sCompInfo ebx).dwDifference],edx ;Difference=wstep>>2
  270. ??no1:
  271. mov edx,ecx
  272. shr edx,3
  273. add [(sCompInfo ebx).dwDifference],edx ;Difference=wstep>>3
  274. test eax,8 ;Check 1000
  275. je short ??no8
  276. neg [(sCompInfo ebx).dwDifference] ;Negate diff because sign bit was set
  277. ??no8:
  278. mov eax,[(sCompInfo ebx).dwPredicted]
  279. add eax,[(sCompInfo ebx).dwDifference] ;eax=Preditcted+Difference
  280. cmp eax,7FFFh
  281. jl short ??noOverflow
  282. mov eax,7FFFh ;if overflow store 7fff in diff
  283. ??noOverflow:
  284. cmp eax,0FFFF8000h
  285. jg short ??noUnderflow
  286. mov eax,0FFFF8000h ;if overflow 0FFFF8000 in diff
  287. ??noUnderflow:
  288. mov [(sCompInfo ebx).dwPredicted],eax ;store into predicted
  289. xor ecx,ecx
  290. mov cx,[(sCompInfo ebx).wCode] ;cx=Code
  291. xor eax,eax
  292. shl ecx,1 ;cx<<1
  293. mov ax,[wCODECIndexTab + ecx] ;ax=Indextab[ecx]
  294. add [(sCompInfo ebx).wIndex],ax ;wIndex+=ax
  295. cmp [(sCompInfo ebx).wIndex],8000h ; check if wIndex < 0
  296. jb short ??checkOverflow
  297. mov [(sCompInfo ebx).wIndex],0 ; reset index to zero
  298. jmp short ??adjustStep
  299. ??checkOverflow:
  300. cmp [(sCompInfo ebx).wIndex],88 ; check if wIndex > 88
  301. jbe short ??adjustStep
  302. mov [(sCompInfo ebx).wIndex],88 ; reset index to 88
  303. ??adjustStep:
  304. ; fetch wIndex so we can fetch new step value
  305. xor ecx,ecx
  306. mov cx,[(sCompInfo ebx).wIndex]
  307. xor eax,eax
  308. shl ecx,1
  309. mov ax,[wCODECStepTab + ecx]
  310. ; advance index and store step value
  311. add [(sCompInfo ebx).dwSampleIndex],1
  312. mov [(sCompInfo ebx).wStep],ax
  313. ; decrement bytes processed and loop back.
  314. dec [dwCODECByteIndex]
  315. jne ??mainloop ; }while !0
  316. jmp ??exitout
  317. ;-----------------------------------------------------------------------
  318. ;Stereo Left Side
  319. ;-----------------------------------------------------------------------
  320. ??mainloopl:
  321. ; determine bit size for input ;do{
  322. cmp [(sCompInfo ebx).wBitSize],16 ;are we doing 16 bit
  323. jne short ??input8Bitl ;no. goto 8 bit input **
  324. movsx eax,[word ptr esi] ;load next word from source
  325. add esi,4 ;inc source by 2 words **
  326. jmp short ??computeDiffl ;skip 8 bit load **
  327. ??input8Bitl:
  328. mov ah,[esi] ;Get 8 bit sample
  329. add esi,2 ;inc source by 2 bytes **
  330. xor al,al ;zero out low byte
  331. xor ah,80h ;flip sign bit
  332. movsx eax,ax ;sign extend into eax
  333. ??computeDiffl:
  334. ; compute difference
  335. movsx ecx,[word ptr (sCompInfo ebx).dwPredicted]
  336. ;load predicted (starts at 0)
  337. sub eax,ecx ;difference=sample-preditcted
  338. ; check if dwDifference > 0. ECX is the
  339. ; sign bit, it is initialized to positive.
  340. xor ecx,ecx ;clear ecx
  341. cmp eax,0 ;if(difference>=0)
  342. jge short ??positivel ;goto positive
  343. neg eax ;else difference= -difference
  344. or ecx,8 ;set nibble sign bit in ecx
  345. ??positivel:
  346. mov [(sCompInfo ebx).wCode],cx ;Store code from cx into struct
  347. ; set up to quantize difference. initialize
  348. ; wCODECTempStep = step value.
  349. movsx ecx,[(sCompInfo ebx).wStep] ;ecx=step value(starts at 7)
  350. mov [dwCODECTempStep],ecx ;tempstep=step
  351. mov edx,4 ;edx=4 mask value (i think)
  352. mov ecx,3 ;ecx is loop number so loop 3 times
  353. ??quantizeLoopl:
  354. ; check to see if difference > tempstep value.
  355. cmp eax,[dwCODECTempStep] ;if(difference < tempstep)
  356. jl short ??nextQLoopl ;goto nextQloop
  357. ; OR in mask value into code and adjust difference.
  358. or [(sCompInfo ebx).wCode],dx ;else or mask into code
  359. sub eax,[dwCODECTempStep] ;difference-=tempstep
  360. ??nextQLoopl:
  361. ; shift down tempstep and mask
  362. shr [dwCODECTempStep],1 ; TempStep>>=1
  363. shr edx,1 ; mask>>=1
  364. loop ??quantizeLoopl ; back to quatize loop
  365. ;------------------------------------------------------------------------------------------
  366. ; now i'v got the new diff and code is masked right
  367. ; store off new difference value
  368. mov [(sCompInfo ebx).dwDifference],eax
  369. ; determine if sample index is even or odd.
  370. ; this will determine if we need to get a new token or not.
  371. test [(sCompInfo ebx).dwSampleIndex],1 ; is it even? (starts at 0)
  372. jne short ??storeTokenl ; if so goto store token **
  373. ; else its odd so get token
  374. xor eax,eax
  375. mov ax,[(sCompInfo ebx).wCode] ;ax=wCode
  376. and eax,0Fh ;and off high nibble
  377. mov [(sCompInfo ebx).wCodeBuf],ax ;wCodeBuf=ax
  378. jmp short ??calcDifferencel ;goto calcDifference **
  379. ??storeTokenl:
  380. ; fetch new token
  381. xor eax,eax
  382. mov ax,[(sCompInfo ebx).wCode] ;ax=code
  383. shl eax,4 ;shift low nibble to hign nibble
  384. or ax,[(sCompInfo ebx).wCodeBuf] ;or in the stored nibble
  385. mov [edi],al ;*dest=al
  386. add edi,2 ;dest+=2 **
  387. ??calcDifferencel:
  388. mov [(sCompInfo ebx).dwDifference],0;dwDifference=0
  389. xor ecx,ecx ;ecx=0
  390. mov cx,[(sCompInfo ebx).wStep] ;cx=Step
  391. xor eax,eax ;eax=0
  392. mov ax,[(sCompInfo ebx).wCode] ;ax=wCode
  393. test eax,4 ;Check 0100
  394. je short ??no4l ; **
  395. add [(sCompInfo ebx).dwDifference],ecx ;difference+=step
  396. ??no4l:
  397. test eax,2 ;Check 0010
  398. je short ??no2l ; **
  399. mov edx,ecx ;edx=wStep
  400. shr edx,1 ;edx>>1
  401. add [(sCompInfo ebx).dwDifference],edx ;Difference=wstep>>1
  402. ??no2l:
  403. test eax,1 ;Check 0001
  404. je short ??no1l ; **
  405. mov edx,ecx ;edx=wStep
  406. shr edx,2 ;edx>>2
  407. add [(sCompInfo ebx).dwDifference],edx ;Difference=wstep>>2
  408. ??no1l:
  409. mov edx,ecx
  410. shr edx,3
  411. add [(sCompInfo ebx).dwDifference],edx ;Difference=wstep>>3
  412. test eax,8 ;Check 1000
  413. je short ??no8l
  414. ;Negate diff because sign bit was set
  415. neg [(sCompInfo ebx).dwDifference]
  416. ??no8l:
  417. mov eax,[(sCompInfo ebx).dwPredicted]
  418. add eax,[(sCompInfo ebx).dwDifference] ;eax=Preditcted+Difference
  419. cmp eax,7FFFh
  420. jl short ??noOverflowl
  421. mov eax,7FFFh ;if overflow store 7fff in diff
  422. ??noOverflowl:
  423. cmp eax,0FFFF8000h
  424. jg short ??noUnderflowl
  425. mov eax,0FFFF8000h ;if overflow 0FFFF8000 in diff
  426. ??noUnderflowl:
  427. mov [(sCompInfo ebx).dwPredicted],eax ;store into predicted
  428. xor ecx,ecx ;adjust index
  429. mov cx,[(sCompInfo ebx).wCode] ;cx=Code
  430. xor eax,eax
  431. shl ecx,1 ;cx<<1
  432. mov ax,[wCODECIndexTab + ecx] ;ax=Indextab[ecx]
  433. add [(sCompInfo ebx).wIndex],ax ;wIndex+=ax
  434. cmp [(sCompInfo ebx).wIndex],8000h ;check if wIndex < 0
  435. jb short ??checkOverflowl ; **
  436. mov [(sCompInfo ebx).wIndex],0 ; reset index to zero
  437. jmp short ??adjustStepl ; **
  438. ??checkOverflowl:
  439. ; check if wIndex > 88
  440. cmp [(sCompInfo ebx).wIndex],88
  441. jbe short ??adjustStepl ; **
  442. ; reset index to 88
  443. mov [(sCompInfo ebx).wIndex],88
  444. ??adjustStepl:
  445. ; fetch wIndex so we can fetch new step value
  446. xor ecx,ecx
  447. mov cx,[(sCompInfo ebx).wIndex]
  448. xor eax,eax
  449. shl ecx,1
  450. mov ax,[wCODECStepTab + ecx]
  451. ; advance index and store step value
  452. add [(sCompInfo ebx).dwSampleIndex],1
  453. mov [(sCompInfo ebx).wStep],ax
  454. ; decrement bytes processed and loop back.
  455. sub [dwCODECByteIndex],2 ; sub 2 for stereo **
  456. jne ??mainloopl ; }while !0 **
  457. ;-------------------------------------------------------------------------
  458. ;Right channel re-set up varibles
  459. ;-------------------------------------------------------------------------
  460. mov eax,[wBytes]
  461. mov esi,[(sCompInfo ebx).lpSource] ; point to source buffer
  462. mov edi,[(sCompInfo ebx).lpDest] ; point to destination buffer
  463. inc esi ; skip first byte
  464. inc edi ; ship first byte
  465. ; Check for 16 bit compression
  466. cmp [(sCompInfo ebx).wBitSize],16
  467. je short ??do16bit
  468. mov [dwCODECByteIndex],eax
  469. jmp short ??mainloopr
  470. ??do16bit:
  471. shr eax,1 ;16 bit so half as many bytes
  472. inc esi ;16 bit so 1 more byte to skip
  473. mov [dwCODECByteIndex],eax
  474. ;-----------------------------------------------------------------------
  475. ;Start of Stereo Right Side
  476. ;-----------------------------------------------------------------------
  477. ??mainloopr:
  478. ; determine bit size for input ;do{
  479. cmp [(sCompInfo ebx).wBitSize],16 ;are we doing 16 bit
  480. jne short ??input8Bitr ;no. goto 8 bit input **
  481. movsx eax,[word ptr esi] ;load next word from source
  482. add esi,4 ;inc source by 2 words **
  483. jmp short ??computeDiffr ;skip 8 bit load **
  484. ??input8Bitr:
  485. mov ah,[esi] ;Get 8 bit sample
  486. add esi,2 ;inc source by 2 bytes **
  487. xor al,al ;zero out low byte
  488. xor ah,80h ;flip sign bit
  489. movsx eax,ax ;sign extend into eax
  490. ??computeDiffr:
  491. ; compute difference
  492. movsx ecx,[word ptr (sCompInfo ebx).dwPredicted2]
  493. ;load predicted (starts at 0)
  494. sub eax,ecx ;difference=sample-preditcted
  495. ; check if dwDifference > 0. ECX is the
  496. ; sign bit, it is initialized to positive.
  497. xor ecx,ecx ;clear ecx
  498. cmp eax,0 ;if(difference>=0)
  499. jge short ??positiver ;goto positive
  500. neg eax ;else difference= -difference
  501. or ecx,8 ;set nibble sign bit in ecx
  502. ??positiver:
  503. mov [(sCompInfo ebx).wCode2],cx ;Store code from cx into struct
  504. ; set up to quantize difference. initialize
  505. ; wCODECTempStep = step value.
  506. movsx ecx,[(sCompInfo ebx).wStep2] ;ecx=step value(starts at 7)
  507. mov [dwCODECTempStep],ecx ;tempstep=step
  508. mov edx,4 ;edx=4 mask value (i think)
  509. mov ecx,3 ;ecx is loop number so loop 3 times
  510. ??quantizeLoopr:
  511. ; check to see if difference > tempstep value.
  512. cmp eax,[dwCODECTempStep] ;if(difference < tempstep)
  513. jl short ??nextQLoopr ;goto nextQloop
  514. ; OR in mask value into code and adjust difference.
  515. or [(sCompInfo ebx).wCode2],dx ;else or mask into code
  516. sub eax,[dwCODECTempStep] ;difference-=tempstep
  517. ??nextQLoopr:
  518. ; shift down tempstep and mask
  519. shr [dwCODECTempStep],1 ; TempStep>>=1
  520. shr edx,1 ; mask>>=1
  521. loop ??quantizeLoopr ; back to quatize loop
  522. ;------------------------------------------------------------------------------------------
  523. ; now i'v got the new diff and code is masked right
  524. ; store off new difference value
  525. mov [(sCompInfo ebx).dwDifference2],eax
  526. ; determine if sample index is even or odd.
  527. ; this will determine if we need to get a new token or not.
  528. test [(sCompInfo ebx).dwSampleIndex2],1 ; is it even? (starts at 0)
  529. jne short ??storeTokenr ; if so goto store token **
  530. ; else its odd so get token
  531. xor eax,eax
  532. mov ax,[(sCompInfo ebx).wCode2] ;ax=wCode
  533. and eax,0Fh ;and off high nibble
  534. mov [(sCompInfo ebx).wCodeBuf2],ax ;wCodeBuf=ax
  535. jmp short ??calcDifferencer ;goto calcDifference **
  536. ??storeTokenr:
  537. xor eax,eax
  538. mov ax,[(sCompInfo ebx).wCode2] ;ax=code
  539. shl eax,4 ;shift low nibble to hign nibble
  540. or ax,[(sCompInfo ebx).wCodeBuf2] ;or in the stored nibble
  541. mov [edi],al ;*dest=al
  542. add edi,2 ;dest+=2 **
  543. ??calcDifferencer:
  544. mov [(sCompInfo ebx).dwDifference2],0 ;dwDifference=0
  545. xor ecx,ecx ;ecx=0
  546. mov cx,[(sCompInfo ebx).wStep2] ;cx=Step
  547. xor eax,eax ;eax=0
  548. mov ax,[(sCompInfo ebx).wCode2] ;ax=wCode
  549. test eax,4 ;Check 0100
  550. je short ??no4r
  551. add [(sCompInfo ebx).dwDifference2],ecx ;difference+=step
  552. ??no4r:
  553. test eax,2 ;Check 0010
  554. je short ??no2r
  555. mov edx,ecx ;edx=wStep
  556. shr edx,1 ;edx>>1
  557. add [(sCompInfo ebx).dwDifference2],edx ;Difference=wstep>>1
  558. ??no2r:
  559. test eax,1 ;Check 0001
  560. je short ??no1r
  561. mov edx,ecx ;edx=wStep
  562. shr edx,2 ;edx>>2
  563. add [(sCompInfo ebx).dwDifference2],edx ;Difference=wstep>>2
  564. ??no1r:
  565. mov edx,ecx
  566. shr edx,3
  567. add [(sCompInfo ebx).dwDifference2],edx ;Difference=wstep>>3
  568. test eax,8 ;Check 1000
  569. je short ??no8r
  570. neg [(sCompInfo ebx).dwDifference2]
  571. ??no8r:
  572. ; add difference to predicted value.
  573. mov eax,[(sCompInfo ebx).dwPredicted2]
  574. add eax,[(sCompInfo ebx).dwDifference2] ;eax=Preditcted+Difference
  575. cmp eax,7FFFh
  576. jl short ??noOverflowr
  577. mov eax,7FFFh ;if overflow store 7fff in diff
  578. ??noOverflowr:
  579. cmp eax,0FFFF8000h
  580. jg short ??noUnderflowr
  581. mov eax,0FFFF8000h ;if overflow 0FFFF8000 in diff
  582. ??noUnderflowr:
  583. mov [(sCompInfo ebx).dwPredicted2],eax ;store into predicted
  584. xor ecx,ecx ;adjust index
  585. mov cx,[(sCompInfo ebx).wCode2] ;cx=Code
  586. xor eax,eax
  587. shl ecx,1 ;cx<<1
  588. mov ax,[wCODECIndexTab + ecx] ;ax=Indextab[ecx]
  589. add [(sCompInfo ebx).wIndex2],ax ;wIndex+=ax
  590. cmp [(sCompInfo ebx).wIndex2],8000h ;check if wIndex < 0
  591. jb short ??checkOverflowr
  592. mov [(sCompInfo ebx).wIndex2],0 ;reset index to zero
  593. jmp short ??adjustStepr
  594. ??checkOverflowr:
  595. cmp [(sCompInfo ebx).wIndex2],88 ;check if wIndex > 88
  596. jbe short ??adjustStepr
  597. mov [(sCompInfo ebx).wIndex2],88 ;reset index to 88
  598. ??adjustStepr:
  599. ; fetch wIndex so we can fetch new step value
  600. xor ecx,ecx
  601. mov cx,[(sCompInfo ebx).wIndex2]
  602. xor eax,eax
  603. shl ecx,1
  604. mov ax,[wCODECStepTab + ecx]
  605. ; advance index and store step value
  606. add [(sCompInfo ebx).dwSampleIndex2],1
  607. mov [(sCompInfo ebx).wStep2],ax
  608. ; decrement bytes processed and loop back.
  609. sub [dwCODECByteIndex],2 ; sub 2 for stereo
  610. jne ??mainloopr ; }while !0
  611. ;-------------------------------------------------------------------------
  612. ;Final clean up
  613. ;-------------------------------------------------------------------------
  614. ??exitout:
  615. ; save off ESI and EDI back into compress info structure.
  616. ; mov [(sCompInfo ebx).lpSource],esi
  617. ; mov [(sCompInfo ebx).lpDest],edi
  618. ; set up return value for number of bytes processed.
  619. mov eax,[dwCODECBytesProcessed]
  620. shr eax,1
  621. cmp [(sCompInfo ebx).wBitSize],16
  622. jne ??leave
  623. shr eax,1 ;if not 16 bit then div/2
  624. ??leave:
  625. pop edx
  626. pop ecx
  627. pop ebx
  628. pop edi
  629. pop esi
  630. ret
  631. ENDP sosCODECCompressData
  632. ;****************************************************************************
  633. ;*
  634. ;* NAME
  635. ;* sosCODECDecompressData - Decompress audio data.
  636. ;*
  637. ;* SYNOPSIS
  638. ;* Size = sosCODECDecompressData(CompInfo, NumBytes)
  639. ;*
  640. ;* long sosCODECDecompressData(_SOS_COMPRESS_INFO *, long);
  641. ;*
  642. ;* FUNCTION
  643. ;* Decompress data from a 4:1 ADPCM compressed stream. The number of
  644. ;* bytes decompressed is returned.
  645. ;*
  646. ;* INPUTS
  647. ;* CompInfo - Compress information structure.
  648. ;* NumBytes - Number of bytes to compress.
  649. ;*
  650. ;* RESULT
  651. ;* Size - Size of decompressed data.
  652. ;*
  653. ;****************************************************************************
  654. GLOBAL C sosCODECDecompressData:NEAR
  655. PROC sosCODECDecompressData C NEAR
  656. ARG sSOSInfo:NEAR PTR
  657. ARG wBytes:DWORD
  658. push esi
  659. push edi
  660. push ebx
  661. push ecx
  662. push edx
  663. ;*---------------------------------------------------------------------------
  664. ;* Initialize
  665. ;*---------------------------------------------------------------------------
  666. mov ebx,[sSOSInfo]
  667. mov eax,[wBytes]
  668. mov [dwCODECBytesProcessed],eax
  669. mov [(sCompInfo ebx).dwSampleIndex],0 ;start at head of index
  670. mov [(sCompInfo ebx).dwSampleIndex2],0 ;start at head of index
  671. ;* Check for 16 bit decompression
  672. cmp [(sCompInfo ebx).wBitSize],16
  673. jne short ??skipByteDivide
  674. shr eax,1
  675. ??skipByteDivide:
  676. mov [dwCODECByteIndex],eax
  677. mov esi,[(sCompInfo ebx).lpSource]
  678. mov edi,[(sCompInfo ebx).lpDest]
  679. cmp [(sCompInfo ebx).wChannels],2 ;stereo check
  680. je ??mainloopl ;do left side first
  681. ; Determine if sample index is even or odd. This will determine
  682. ; if we need to get a new token or not.
  683. ;*---------------------------------------------------------------------------
  684. ;* Main Mono Loop
  685. ;*---------------------------------------------------------------------------
  686. ??mainloop:
  687. test [(sCompInfo ebx).dwSampleIndex],1 ;odd ??
  688. je short ??fetchToken ;if so get new token
  689. xor eax,eax ;else shift int codebuf
  690. mov ax,[(sCompInfo ebx).wCodeBuf] ;ored with Code
  691. shr eax,4
  692. and eax,000Fh
  693. mov [(sCompInfo ebx).wCode],ax
  694. jmp short ??calcDifference
  695. ??fetchToken:
  696. xor eax,eax ;get a new token
  697. mov al,[esi] ;put in codebuf
  698. mov [(sCompInfo ebx).wCodeBuf],ax
  699. inc esi
  700. and eax,000Fh
  701. mov [(sCompInfo ebx).wCode],ax ;and then code
  702. ??calcDifference:
  703. mov [(sCompInfo ebx).dwDifference],0 ;reset diff
  704. xor ecx,ecx
  705. mov cx,[(sCompInfo ebx).wStep] ;cx is step value
  706. test eax,4 ;Check for wCode & 4
  707. je short ??no4
  708. add [(sCompInfo ebx).dwDifference],ecx ;Add wStep
  709. ??no4:
  710. test eax,2 ;Check for wCode & 2
  711. je short ??no2
  712. mov edx,ecx ;Add wStep >> 1
  713. shr edx,1
  714. add [(sCompInfo ebx).dwDifference],edx
  715. ??no2:
  716. test eax,1 ;Check for wCode & 1
  717. je short ??no1
  718. mov edx,ecx ;Add wStep >> 2
  719. shr edx,2
  720. add [(sCompInfo ebx).dwDifference],edx
  721. ??no1:
  722. mov edx,ecx ;Add in wStep >> 3
  723. shr edx,3
  724. add [(sCompInfo ebx).dwDifference],edx
  725. test eax,8 ;Check for wCode & 8
  726. je short ??no8
  727. neg [(sCompInfo ebx).dwDifference] ;Negate diff
  728. ??no8:
  729. ; add difference to predicted value.
  730. mov eax,[(sCompInfo ebx).dwPredicted]
  731. add eax,[(sCompInfo ebx).dwDifference]
  732. ; make sure there is no under or overflow.
  733. cmp eax,7FFFh
  734. jl short ??noOverflow
  735. mov eax,7FFFh
  736. ??noOverflow:
  737. cmp eax,0FFFF8000h
  738. jg short ??noUnderflow
  739. mov eax,0FFFF8000h
  740. ??noUnderflow:
  741. mov [(sCompInfo ebx).dwPredicted],eax
  742. cmp [(sCompInfo ebx).wBitSize],16
  743. jne short ??output8Bit
  744. mov [edi],ax ;Output 16bit sample
  745. add edi,2
  746. jmp short ??adjustIndex
  747. ??output8Bit:
  748. ; output 8 bit sample
  749. xor ah,80h
  750. mov [edi],ah
  751. inc edi
  752. ??adjustIndex:
  753. xor ecx,ecx
  754. mov cx,[(sCompInfo ebx).wCode]
  755. xor eax,eax
  756. shl ecx,1
  757. mov ax,[wCODECIndexTab + ecx]
  758. add [(sCompInfo ebx).wIndex],ax ;check if wIndex < 0
  759. cmp [(sCompInfo ebx).wIndex],8000h
  760. jb short ??checkOverflow
  761. mov [(sCompInfo ebx).wIndex],0 ;reset index to zero
  762. jmp short ??adjustStep
  763. ??checkOverflow:
  764. cmp [(sCompInfo ebx).wIndex],88 ;check if wIndex > 88
  765. jbe short ??adjustStep
  766. mov [(sCompInfo ebx).wIndex],88 ;reset index to 88
  767. ??adjustStep:
  768. ; fetch wIndex so we can fetch new step value
  769. xor ecx,ecx
  770. mov cx,[(sCompInfo ebx).wIndex]
  771. xor eax,eax
  772. shl ecx,1
  773. mov ax,[wCODECStepTab + ecx]
  774. ; advance index and store step value
  775. add [(sCompInfo ebx).dwSampleIndex],1
  776. mov [(sCompInfo ebx).wStep],ax
  777. ; decrement bytes processed and loop back.
  778. dec [dwCODECByteIndex]
  779. jne ??mainloop
  780. jmp ??exitout
  781. ;--------------------------------------------------------------------------
  782. ;Left Channel Start
  783. ;--------------------------------------------------------------------------
  784. ??mainloopl:
  785. test [(sCompInfo ebx).dwSampleIndex],1
  786. je short ??fetchTokenl
  787. xor eax,eax
  788. mov ax,[(sCompInfo ebx).wCodeBuf]
  789. shr eax,4
  790. and eax,000Fh
  791. mov [(sCompInfo ebx).wCode],ax
  792. jmp short ??calcDifferencel
  793. ??fetchTokenl:
  794. xor eax,eax
  795. mov al,[esi]
  796. mov [(sCompInfo ebx).wCodeBuf],ax
  797. add esi,2 ;2 for stereo
  798. and eax,000Fh
  799. mov [(sCompInfo ebx).wCode],ax
  800. ??calcDifferencel:
  801. ; reset difference
  802. mov [(sCompInfo ebx).dwDifference],0
  803. xor ecx,ecx
  804. mov cx,[(sCompInfo ebx).wStep]
  805. test eax,4 ;Check for wCode & 4
  806. je short ??no4l
  807. add [(sCompInfo ebx).dwDifference],ecx ;Add wStep
  808. ??no4l:
  809. test eax,2 ;Check for wCode & 2
  810. je short ??no2l
  811. mov edx,ecx ;Add wStep >> 1
  812. shr edx,1
  813. add [(sCompInfo ebx).dwDifference],edx
  814. ??no2l:
  815. test eax,1 ;Check for wCode & 1
  816. je short ??no1l
  817. mov edx,ecx ;Add wStep >> 2
  818. shr edx,2
  819. add [(sCompInfo ebx).dwDifference],edx
  820. ??no1l:
  821. mov edx,ecx ;Add in wStep >> 3
  822. shr edx,3
  823. add [(sCompInfo ebx).dwDifference],edx
  824. test eax,8 ;Check for wCode & 8
  825. je short ??no8l
  826. neg [(sCompInfo ebx).dwDifference] ;Negate diff
  827. ??no8l:
  828. ; add difference to predicted value.
  829. mov eax,[(sCompInfo ebx).dwPredicted]
  830. add eax,[(sCompInfo ebx).dwDifference]
  831. ; make sure there is no under or overflow.
  832. cmp eax,7FFFh
  833. jl short ??noOverflowl
  834. mov eax,7FFFh
  835. ??noOverflowl:
  836. cmp eax,0FFFF8000h
  837. jg short ??noUnderflowl
  838. mov eax,0FFFF8000h
  839. ??noUnderflowl:
  840. mov [(sCompInfo ebx).dwPredicted],eax
  841. cmp [(sCompInfo ebx).wBitSize],16
  842. jne short ??output8Bitl
  843. mov [edi],ax ;Output 16bit sample
  844. add edi,4 ;4 for stereo
  845. jmp short ??adjustIndexl
  846. ??output8Bitl:
  847. ; output 8 bit sample
  848. xor ah,80h
  849. mov [edi],ah
  850. add edi,2 ;2 for stereo
  851. ??adjustIndexl:
  852. xor ecx,ecx
  853. mov cx,[(sCompInfo ebx).wCode]
  854. xor eax,eax
  855. shl ecx,1
  856. mov ax,[wCODECIndexTab + ecx]
  857. add [(sCompInfo ebx).wIndex],ax
  858. ; check if wIndex < 0
  859. cmp [(sCompInfo ebx).wIndex],8000h
  860. jb short ??checkOverflowl
  861. mov [(sCompInfo ebx).wIndex],0
  862. jmp short ??adjustStepl ;reset index to zero
  863. ??checkOverflowl:
  864. cmp [(sCompInfo ebx).wIndex],88 ; check if wIndex > 88
  865. jbe short ??adjustStepl
  866. mov [(sCompInfo ebx).wIndex],88 ; reset index to 88
  867. ??adjustStepl:
  868. ; fetch wIndex so we can fetch new step value
  869. xor ecx,ecx
  870. mov cx,[(sCompInfo ebx).wIndex]
  871. xor eax,eax
  872. shl ecx,1
  873. mov ax,[wCODECStepTab + ecx]
  874. ; advance index and store step value
  875. add [(sCompInfo ebx).dwSampleIndex],1
  876. mov [(sCompInfo ebx).wStep],ax
  877. ; decrement bytes processed and loop back.
  878. sub [dwCODECByteIndex],2
  879. jne ??mainloopl
  880. ;----------------------------------------------------------------------------
  881. ; Right Side Setup
  882. ;----------------------------------------------------------------------------
  883. mov eax,[wBytes]
  884. mov [dwCODECBytesProcessed],eax
  885. mov esi,[(sCompInfo ebx).lpSource]
  886. mov edi,[(sCompInfo ebx).lpDest]
  887. inc esi ; skip left channel
  888. inc edi ; skip left channel
  889. cmp [(sCompInfo ebx).wBitSize],16 ;16 bit ??
  890. je short ??doByteDivide
  891. mov [dwCODECByteIndex],eax
  892. jmp short ??mainloopr
  893. ??doByteDivide:
  894. shr eax,1 ;Divide size by two
  895. inc edi ; 16 bit so skip 1 more
  896. mov [dwCODECByteIndex],eax
  897. ;--------------------------------------------------------------------------
  898. ;Right Channel Start
  899. ;--------------------------------------------------------------------------
  900. ??mainloopr:
  901. test [(sCompInfo ebx).dwSampleIndex2],1
  902. je short ??fetchTokenr
  903. xor eax,eax
  904. mov ax,[(sCompInfo ebx).wCodeBuf2]
  905. shr eax,4
  906. and eax,000Fh
  907. mov [(sCompInfo ebx).wCode2],ax
  908. jmp short ??calcDifferencer
  909. ??fetchTokenr:
  910. xor eax,eax
  911. mov al,[esi]
  912. mov [(sCompInfo ebx).wCodeBuf2],ax
  913. add esi,2 ;2 for stereo
  914. and eax,000Fh
  915. mov [(sCompInfo ebx).wCode2],ax
  916. ??calcDifferencer:
  917. ; reset difference
  918. mov [(sCompInfo ebx).dwDifference2],0
  919. xor ecx,ecx
  920. mov cx,[(sCompInfo ebx).wStep2]
  921. test eax,4 ;Check for wCode & 4
  922. je short ??no4r
  923. add [(sCompInfo ebx).dwDifference2],ecx ;Add wStep
  924. ??no4r:
  925. test eax,2 ;Check for wCode & 2
  926. je short ??no2r
  927. mov edx,ecx ;Add wStep >> 1
  928. shr edx,1
  929. add [(sCompInfo ebx).dwDifference2],edx
  930. ??no2r:
  931. test eax,1 ;Check for wCode & 1
  932. je short ??no1r
  933. mov edx,ecx ;Add wStep >> 2
  934. shr edx,2
  935. add [(sCompInfo ebx).dwDifference2],edx
  936. ??no1r:
  937. mov edx,ecx ;Add in wStep >> 3
  938. shr edx,3
  939. add [(sCompInfo ebx).dwDifference2],edx
  940. test eax,8 ;Check for wCode & 8
  941. je short ??no8r
  942. neg [(sCompInfo ebx).dwDifference2] ;Negate diff
  943. ??no8r:
  944. ; add difference to predicted value.
  945. mov eax,[(sCompInfo ebx).dwPredicted2]
  946. add eax,[(sCompInfo ebx).dwDifference2]
  947. cmp eax,7FFFh
  948. jl short ??noOverflowr
  949. mov eax,7FFFh
  950. ??noOverflowr:
  951. cmp eax,0FFFF8000h
  952. jg short ??noUnderflowr
  953. mov eax,0FFFF8000h
  954. ??noUnderflowr:
  955. mov [(sCompInfo ebx).dwPredicted2],eax
  956. cmp [(sCompInfo ebx).wBitSize],16
  957. jne short ??output8Bitr
  958. mov [edi],ax ;Output 16bit sample
  959. add edi,4 ;4 for stereo ***
  960. jmp short ??adjustIndexr
  961. ??output8Bitr:
  962. ; output 8 bit sample
  963. xor ah,80h
  964. mov [edi],ah
  965. add edi,2 ;2 for stereo
  966. ??adjustIndexr:
  967. xor ecx,ecx
  968. mov cx,[(sCompInfo ebx).wCode2]
  969. xor eax,eax
  970. shl ecx,1
  971. mov ax,[wCODECIndexTab + ecx]
  972. add [(sCompInfo ebx).wIndex2],ax
  973. ; check if wIndex < 0
  974. cmp [(sCompInfo ebx).wIndex2],8000h
  975. jb short ??checkOverflowr
  976. ; reset index to zero
  977. mov [(sCompInfo ebx).wIndex2],0
  978. jmp short ??adjustStepr
  979. ??checkOverflowr:
  980. ; check if wIndex > 88
  981. cmp [(sCompInfo ebx).wIndex2],88
  982. jbe short ??adjustStepr
  983. mov [(sCompInfo ebx).wIndex2],88 ; reset index to 88
  984. ??adjustStepr:
  985. ; fetch wIndex so we can fetch new step value
  986. xor ecx,ecx
  987. mov cx,[(sCompInfo ebx).wIndex2]
  988. xor eax,eax
  989. shl ecx,1
  990. mov ax,[wCODECStepTab + ecx]
  991. ; advance index and store step value
  992. add [(sCompInfo ebx).dwSampleIndex2],1
  993. mov [(sCompInfo ebx).wStep2],ax
  994. ; decrement bytes processed and loop back.
  995. sub [dwCODECByteIndex],2
  996. jne ??mainloopr
  997. ??exitout:
  998. ; don't think we need this but just in case i'll leave it here!!
  999. ; mov [(sCompInfo ebx).lpSource],esi
  1000. ; mov [(sCompInfo ebx).lpDest],edi
  1001. ; set up return value for number of bytes processed.
  1002. mov eax,[dwCODECBytesProcessed]
  1003. pop edx
  1004. pop ecx
  1005. pop ebx
  1006. pop edi
  1007. pop esi
  1008. ret
  1009. ENDP sosCODECDecompressData
  1010. END
  1011.