SOSCODEC.ASM 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ;SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ;IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ;FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  9. ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  10. ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/main/rcs/soscodec.asm $
  13. ; $Revision: 2.0 $
  14. ; $Author: john $
  15. ; $Date: 1995/02/27 11:29:36 $
  16. ;
  17. ; Routines for compressing digital sounds.
  18. ;
  19. ; $Log: soscodec.asm $
  20. ; Revision 2.0 1995/02/27 11:29:36 john
  21. ; New version 2.0, which has no anonymous unions, builds with
  22. ; Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  23. ;
  24. ; Revision 1.2 1994/11/30 14:08:46 john
  25. ; First version.
  26. ;
  27. ; Revision 1.1 1994/11/29 14:33:51 john
  28. ; Initial revision
  29. ;
  30. ;
  31. .386
  32. option oldstructs
  33. .nolist
  34. include types.inc
  35. include psmacros.inc
  36. .list
  37. assume cs:_TEXT, ds:_DATA
  38. _DATA segment dword public USE32 'DATA'
  39. rcsid db "$Id: soscodec.asm 2.0 1995/02/27 11:29:36 john Exp $"
  40. align 4
  41. ; public declarations
  42. public sosCODECDecompressData_
  43. public sosCODECCompressData_
  44. public sosCODECInitStream_
  45. ; structure definitions
  46. sCompressInfo struc
  47. Source dd 0 ; pointer to compressed data
  48. Dest dd 0 ; pointer to uncompressed data
  49. dwCompSize dd 0 ; compressed size
  50. dwUnCompSize dd 0 ; uncompressed size
  51. dwSampleIndex dd 0 ; index into sample
  52. dwPredicted dd 0 ; next predicted value
  53. dwDifference dd 0 ; difference from last sample
  54. wCodeBuf dw 0 ; holds 2 nibbles for decompression
  55. wCode dw 0 ; current 4 bit code
  56. wStep dw 0 ; step value in table
  57. wIndex dw 0 ; index into step table
  58. wBitSize dw 0 ; bit size for decompression
  59. sCompressInfo ends
  60. ; index table for stepping into step table
  61. ;
  62. wCODECIndexTab dw -1,-1,-1,-1, 2, 4, 6, 8
  63. dw -1,-1,-1,-1, 2, 4, 6, 8
  64. wCODECStepTab dw 7, 8, 9, 10, 11, 12, 13, 14
  65. dw 16, 17, 19, 21, 23, 25, 28
  66. dw 31, 34, 37, 41, 45, 50, 55
  67. dw 60, 66, 73, 80, 88, 97, 107
  68. dw 118, 130, 143, 157, 173, 190, 209
  69. dw 230, 253, 279, 307, 337, 371, 408
  70. dw 449, 494, 544, 598, 658, 724, 796
  71. dw 876, 963,1060,1166,1282,1411,1552
  72. dw 1707,1878
  73. dw 2066,2272,2499,2749,3024,3327,3660,4026
  74. dw 4428,4871,5358,5894,6484,7132,7845,8630
  75. dw 9493,10442,11487,12635,13899,15289,16818
  76. dw 18500,20350,22385,24623,27086,29794,32767
  77. ; byte index counter
  78. wCODECByteIndex dd 0
  79. ; total bytes processed
  80. wCODECBytesProcessed dd 0
  81. ; current mask value
  82. wCODECMask dw 0
  83. ; temp step value
  84. dwCODECTempStep dd 0
  85. _DATA ends
  86. _TEXT segment dword public USE32 'CODE'
  87. sosCODECInitStream_:
  88. ; save used registers
  89. push ebx
  90. ;
  91. ; set up pointer to _SOS_COMPRESS_INFO
  92. ; structure in EBX.
  93. ;
  94. mov ebx, eax
  95. ;
  96. ; init members of compression stream
  97. ;
  98. mov word ptr [ ebx ].wIndex, 0
  99. mov word ptr [ ebx ].wStep, 7
  100. mov dword ptr [ ebx ].dwPredicted, 0
  101. mov dword ptr [ ebx ].dwSampleIndex, 0
  102. ; restore registers
  103. pop ebx
  104. ret
  105. ;
  106. ; DWORD sosCODECDecompressData( _SOS_COMPRESS_INFO * sSOSInfo, DWORD wBytes )
  107. ;
  108. ; decompress data from a 4:1 ADPCM compressed file. the number of
  109. ; bytes decompressed is returned.
  110. ;
  111. ;
  112. sosCODECDecompressData_:
  113. ; eax = sSOSInfo
  114. ; edx = wBytes
  115. ;
  116. ; save registers used
  117. ;
  118. push esi
  119. push edi
  120. push ebx
  121. push ecx
  122. push edx
  123. ;
  124. ; set up EBX as a pointer to
  125. ; info structure.
  126. ;
  127. mov ebx, eax
  128. ;
  129. ; set up byte counter. if 16 bit data
  130. ; divide bytes by two since we will
  131. ; spit out two bytes @ a time.
  132. ;
  133. mov eax, edx
  134. mov wCODECBytesProcessed, eax
  135. mov wCODECByteIndex, eax
  136. ;
  137. ; set up source and destination
  138. ; pointers
  139. ;
  140. mov esi, [ ebx ].Source
  141. mov edi, [ ebx ].Dest
  142. Decompmainloop:
  143. ;
  144. ; determine if sample index is even
  145. ; or odd. this will determine if we
  146. ; need to get a new token or not.
  147. ;
  148. test dword ptr [ ebx ].dwSampleIndex, 1
  149. je short DecompfetchToken
  150. ;
  151. ; get token
  152. ;
  153. movzx eax, word ptr [ ebx ].wCodeBuf
  154. shr eax, 4
  155. and eax, 000fh
  156. mov word ptr [ ebx ].wCode, ax
  157. jmp short DecompcalcDifference
  158. DecompfetchToken:
  159. ;
  160. ; fetch new token
  161. ;
  162. xor eax, eax
  163. mov al, byte ptr [ esi ]
  164. mov word ptr [ ebx ].wCodeBuf, ax
  165. inc esi
  166. and eax, 000fh
  167. mov word ptr [ ebx ].wCode, ax
  168. DecompcalcDifference:
  169. ;
  170. ; reset difference
  171. ;
  172. mov dword ptr [ ebx ].dwDifference, 0
  173. ;
  174. ; set up ECX as the step value
  175. ;
  176. movzx ecx, word ptr [ ebx ].wStep
  177. ;
  178. ; check for wCode & 4
  179. ;
  180. test eax, 4
  181. je short Decompno4
  182. ; add wStep
  183. add dword ptr [ ebx ].dwDifference, ecx
  184. Decompno4:
  185. ;
  186. ; check for wCode & 2
  187. ;
  188. test eax, 2
  189. je short Decompno2
  190. ; add wStep >> 1
  191. mov edx, ecx
  192. shr edx, 1
  193. add dword ptr [ ebx ].dwDifference, edx
  194. Decompno2:
  195. ;
  196. ; check for wCode & 1
  197. ;
  198. test eax, 1
  199. je short Decompno1
  200. ; add wStep >> 2
  201. mov edx, ecx
  202. shr edx, 2
  203. add dword ptr [ ebx ].dwDifference, edx
  204. Decompno1:
  205. ;
  206. ; add in wStep >> 3
  207. ;
  208. mov edx, ecx
  209. shr edx, 3
  210. add dword ptr [ ebx ].dwDifference, edx
  211. ;
  212. ; check for wCode & 8
  213. ;
  214. test eax, 8
  215. je short Decompno8
  216. ; negate difference
  217. neg dword ptr [ ebx ].dwDifference
  218. Decompno8:
  219. ;
  220. ; add difference to predicted
  221. ; value.
  222. ;
  223. mov eax, [ ebx ].dwPredicted
  224. add eax, [ ebx ].dwDifference
  225. ;
  226. ; make sure there is no under or
  227. ; overflow.
  228. ;
  229. cmp eax, 7fffh
  230. jl short DecompnoOverflow
  231. mov eax, 7fffh
  232. DecompnoOverflow:
  233. cmp eax, 0ffff8000h
  234. jg short DecompnoUnderflow
  235. mov eax, 0ffff8000h
  236. DecompnoUnderflow:
  237. mov dword ptr [ ebx ].dwPredicted, eax
  238. ;
  239. ; output 8 bit sample
  240. ;
  241. xor ah, 80h
  242. mov al, ah
  243. stosb
  244. ;
  245. ; adjust index
  246. ;
  247. movzx ecx, word ptr [ ebx ].wCode
  248. movzx eax, word ptr wCODECIndexTab[ ecx * 2 ]
  249. add word ptr [ ebx ].wIndex, ax
  250. ;
  251. ; check if wIndex < 0
  252. ;
  253. cmp word ptr [ ebx ].wIndex, 8000h
  254. jb short DecompcheckOverflow
  255. ; reset index to zero
  256. mov word ptr [ ebx ].wIndex, 0
  257. jmp short DecompadjustStep
  258. DecompcheckOverflow:
  259. ;
  260. ; check if wIndex > 88
  261. ;
  262. cmp word ptr [ ebx ].wIndex, 88
  263. jbe short DecompadjustStep
  264. ; reset index to 88
  265. mov word ptr [ ebx ].wIndex, 88
  266. DecompadjustStep:
  267. ;
  268. ; fetch wIndex so we can fetch
  269. ; new step value
  270. ;
  271. movzx ecx, word ptr [ ebx ].wIndex
  272. movzx eax, word ptr wCODECStepTab[ ecx * 2 ]
  273. ;
  274. ; advance index and store step value
  275. ;
  276. add dword ptr [ ebx ].dwSampleIndex, 1
  277. mov word ptr [ ebx ].wStep, ax
  278. ;
  279. ; decrement bytes processed
  280. ; and loop back.
  281. ;
  282. dec wCODECByteIndex
  283. jne Decompmainloop
  284. ;
  285. ; save off ESI and EDI back into
  286. ; compress info structure.
  287. ;
  288. mov dword ptr [ ebx ].Source, esi
  289. mov dword ptr [ ebx ].Dest, edi
  290. ;
  291. ; set up return value for number
  292. ; of bytes processed.
  293. ;
  294. mov eax, wCODECBytesProcessed
  295. ;
  296. ; restore registers
  297. ;
  298. pop edx
  299. pop ecx
  300. pop ebx
  301. pop edi
  302. pop esi
  303. ret
  304. ;
  305. ; DWORD sosCODECCompressData( _SOS_COMPRESS_INFO * sSOSInfo, DWORD wBytes )
  306. ;
  307. ; Compresses a data stream into 4:1 ADPCM. 16 bit data is compressed 4:1
  308. ; 8 bit data is compressed 2:1.
  309. ;
  310. ;
  311. sosCODECCompressData_:
  312. ; eax = sSOSInfo
  313. ; edx = wBytes
  314. ;
  315. ; save registers used
  316. ;
  317. push esi
  318. push edi
  319. push ebx
  320. push ecx
  321. push edx
  322. ;
  323. ; set up EBX as a pointer to
  324. ; info structure.
  325. ;
  326. mov ebx, eax
  327. ;
  328. ; set up byte counter. if 16 bit data
  329. ; divide bytes by two since we will
  330. ; spit out two bytes @ a time.
  331. ;
  332. mov eax, edx
  333. mov wCODECBytesProcessed, eax
  334. ;
  335. ; check for 16 bit decompression
  336. ;
  337. cmp word ptr [ ebx ].wBitSize, 16
  338. jne short CompskipByteDivide
  339. ;
  340. ; divide size requested by two
  341. ;
  342. shr eax, 1
  343. CompskipByteDivide:
  344. mov wCODECByteIndex, eax
  345. ;
  346. ; set up source and destination
  347. ; pointers
  348. ;
  349. mov esi, [ ebx ].Source
  350. mov edi, [ ebx ].Dest
  351. Compmainloop:
  352. ;
  353. ; determine bit size for input
  354. ;
  355. cmp word ptr [ ebx ].wBitSize, 16
  356. jne short Compinput8Bit
  357. ;
  358. ; get 16 bit sample
  359. ;
  360. movsx eax, word ptr [ esi ]
  361. add esi, 2
  362. jmp short CompcomputeDiff
  363. Compinput8Bit:
  364. ;
  365. ; get 8 bit sample
  366. ;
  367. mov ah, byte ptr [ esi ]
  368. inc esi
  369. xor al, al
  370. xor ah, 80h
  371. movsx eax, ax
  372. CompcomputeDiff:
  373. ;
  374. ; compute difference
  375. ;
  376. movsx ecx, word ptr [ ebx ].dwPredicted
  377. sub eax, ecx
  378. ;
  379. ; check if dwDifference > 0. ECX is the
  380. ; sign bit, it is initialized to positive.
  381. ;
  382. xor ecx, ecx
  383. cmp eax, 0
  384. jge Comppositive
  385. ;
  386. ; negate difference
  387. ;
  388. neg eax
  389. or ecx, 8
  390. Comppositive:
  391. ;
  392. ; store code value
  393. ;
  394. mov word ptr [ ebx ].wCode, cx
  395. ;
  396. ; set up to quantize difference. initialize
  397. ; wCODECTempStep = step value.
  398. ;
  399. movsx ecx, word ptr [ ebx ].wStep
  400. mov dwCODECTempStep, ecx
  401. mov edx, 4
  402. mov ecx, 3
  403. CompquantizeLoop:
  404. ;
  405. ; check to see if difference > tempstep
  406. ; value.
  407. ;
  408. cmp eax, dwCODECTempStep
  409. jl short CompnextQLoop
  410. ;
  411. ; OR in mask value into code and
  412. ; adjust difference.
  413. ;
  414. or word ptr [ ebx ].wCode, dx
  415. sub eax, dwCODECTempStep
  416. CompnextQLoop:
  417. ;
  418. ; shift down tempstep and mask
  419. ;
  420. shr dwCODECTempStep, 1
  421. shr edx, 1
  422. loop CompquantizeLoop
  423. ;
  424. ; store off new difference value
  425. ;
  426. mov dword ptr [ ebx ].dwDifference, eax
  427. ;
  428. ; determine if sample index is even
  429. ; or odd. this will determine if we
  430. ; need to get a new token or not.
  431. ;
  432. test dword ptr [ ebx ].dwSampleIndex, 1
  433. jne short CompstoreToken
  434. ;
  435. ; get token
  436. ;
  437. movzx eax, word ptr [ ebx ].wCode
  438. and eax, 0fh
  439. mov word ptr [ ebx ].wCodeBuf, ax
  440. jmp short CompcalcDifference
  441. CompstoreToken:
  442. ;
  443. ; fetch new token
  444. ;
  445. movzx eax, word ptr [ ebx ].wCode
  446. shl eax, 4
  447. or ax, word ptr [ ebx ].wCodeBuf
  448. mov byte ptr [ edi ], al
  449. inc edi
  450. CompcalcDifference:
  451. ;
  452. ; reset difference
  453. ;
  454. mov dword ptr [ ebx ].dwDifference, 0
  455. ;
  456. ; set up ECX as the step value
  457. ;
  458. movzx ecx, word ptr [ ebx ].wStep
  459. ;
  460. ; get code in AX
  461. ;
  462. movzx eax, word ptr [ ebx ].wCode
  463. ;
  464. ; check for wCode & 4
  465. ;
  466. test eax, 4
  467. je short Compno4
  468. ; add wStep
  469. add dword ptr [ ebx ].dwDifference, ecx
  470. Compno4:
  471. ;
  472. ; check for wCode & 2
  473. ;
  474. test eax, 2
  475. je short Compno2
  476. ; add wStep >> 1
  477. mov edx, ecx
  478. shr edx, 1
  479. add dword ptr [ ebx ].dwDifference, edx
  480. Compno2:
  481. ;
  482. ; check for wCode & 1
  483. ;
  484. test eax, 1
  485. je short Compno1
  486. ; add wStep >> 2
  487. mov edx, ecx
  488. shr edx, 2
  489. add dword ptr [ ebx ].dwDifference, edx
  490. Compno1:
  491. ;
  492. ; add in wStep >> 3
  493. ;
  494. mov edx, ecx
  495. shr edx, 3
  496. add dword ptr [ ebx ].dwDifference, edx
  497. ;
  498. ; check for wCode & 8
  499. ;
  500. test eax, 8
  501. je short Compno8
  502. ; negate difference
  503. neg dword ptr [ ebx ].dwDifference
  504. Compno8:
  505. ;
  506. ; add difference to predicted
  507. ; value.
  508. ;
  509. mov eax, [ ebx ].dwPredicted
  510. add eax, [ ebx ].dwDifference
  511. ;
  512. ; make sure there is no under or
  513. ; overflow.
  514. ;
  515. cmp eax, 7fffh
  516. jl short CompnoOverflow
  517. mov eax, 7fffh
  518. CompnoOverflow:
  519. cmp eax, 0ffff8000h
  520. jg short CompnoUnderflow
  521. mov eax, 0ffff8000h
  522. CompnoUnderflow:
  523. mov dword ptr [ ebx ].dwPredicted, eax
  524. ;
  525. ; adjust index
  526. ;
  527. movzx ecx, word ptr [ ebx ].wCode
  528. movzx eax, word ptr wCODECIndexTab[ ecx * 2 ]
  529. add word ptr [ ebx ].wIndex, ax
  530. ;
  531. ; check if wIndex < 0
  532. ;
  533. cmp word ptr [ ebx ].wIndex, 8000h
  534. jb short CompcheckOverflow
  535. ; reset index to zero
  536. mov word ptr [ ebx ].wIndex, 0
  537. jmp short CompadjustStep
  538. CompcheckOverflow:
  539. ;
  540. ; check if wIndex > 88
  541. ;
  542. cmp word ptr [ ebx ].wIndex, 88
  543. jbe short CompadjustStep
  544. ; reset index to 88
  545. mov word ptr [ ebx ].wIndex, 88
  546. CompadjustStep:
  547. ;
  548. ; fetch wIndex so we can fetch
  549. ; new step value
  550. ;
  551. movzx ecx, word ptr [ ebx ].wIndex
  552. movzx eax, word ptr wCODECStepTab[ ecx * 2 ]
  553. ;
  554. ; advance index and store step value
  555. ;
  556. add dword ptr [ ebx ].dwSampleIndex, 1
  557. mov word ptr [ ebx ].wStep, ax
  558. ;
  559. ; decrement bytes processed
  560. ; and loop back.
  561. ;
  562. dec wCODECByteIndex
  563. jne Compmainloop
  564. ;
  565. ; save off ESI and EDI back into
  566. ; compress info structure.
  567. ;
  568. mov dword ptr [ ebx ].Source, esi
  569. mov dword ptr [ ebx ].Dest, edi
  570. ;
  571. ; set up return value for number
  572. ; of bytes processed.
  573. ;
  574. mov eax, wCODECBytesProcessed
  575. shr eax, 2
  576. ;
  577. ; restore registers
  578. ;
  579. pop edx
  580. pop ecx
  581. pop ebx
  582. pop edi
  583. pop esi
  584. ret
  585. _TEXT ends
  586. end
  587.