123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690 |
- ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
- ;SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
- ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
- ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
- ;IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
- ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
- ;FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
- ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
- ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
- ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
- ;
- ; $Source: f:/miner/source/main/rcs/soscodec.asm $
- ; $Revision: 2.0 $
- ; $Author: john $
- ; $Date: 1995/02/27 11:29:36 $
- ;
- ; Routines for compressing digital sounds.
- ;
- ; $Log: soscodec.asm $
- ; Revision 2.0 1995/02/27 11:29:36 john
- ; New version 2.0, which has no anonymous unions, builds with
- ; Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
- ;
- ; Revision 1.2 1994/11/30 14:08:46 john
- ; First version.
- ;
- ; Revision 1.1 1994/11/29 14:33:51 john
- ; Initial revision
- ;
- ;
- .386
- option oldstructs
- .nolist
- include types.inc
- include psmacros.inc
- .list
- assume cs:_TEXT, ds:_DATA
- _DATA segment dword public USE32 'DATA'
- rcsid db "$Id: soscodec.asm 2.0 1995/02/27 11:29:36 john Exp $"
- align 4
- ; public declarations
- public sosCODECDecompressData_
- public sosCODECCompressData_
- public sosCODECInitStream_
- ; structure definitions
- sCompressInfo struc
- Source dd 0 ; pointer to compressed data
- Dest dd 0 ; pointer to uncompressed data
- dwCompSize dd 0 ; compressed size
- dwUnCompSize dd 0 ; uncompressed size
- dwSampleIndex dd 0 ; index into sample
- dwPredicted dd 0 ; next predicted value
- dwDifference dd 0 ; difference from last sample
- wCodeBuf dw 0 ; holds 2 nibbles for decompression
- wCode dw 0 ; current 4 bit code
- wStep dw 0 ; step value in table
- wIndex dw 0 ; index into step table
- wBitSize dw 0 ; bit size for decompression
- sCompressInfo ends
- ; index table for stepping into step table
- ;
- wCODECIndexTab dw -1,-1,-1,-1, 2, 4, 6, 8
- dw -1,-1,-1,-1, 2, 4, 6, 8
- wCODECStepTab dw 7, 8, 9, 10, 11, 12, 13, 14
- dw 16, 17, 19, 21, 23, 25, 28
- dw 31, 34, 37, 41, 45, 50, 55
- dw 60, 66, 73, 80, 88, 97, 107
- dw 118, 130, 143, 157, 173, 190, 209
- dw 230, 253, 279, 307, 337, 371, 408
- dw 449, 494, 544, 598, 658, 724, 796
- dw 876, 963,1060,1166,1282,1411,1552
- dw 1707,1878
- dw 2066,2272,2499,2749,3024,3327,3660,4026
- dw 4428,4871,5358,5894,6484,7132,7845,8630
- dw 9493,10442,11487,12635,13899,15289,16818
- dw 18500,20350,22385,24623,27086,29794,32767
- ; byte index counter
- wCODECByteIndex dd 0
- ; total bytes processed
- wCODECBytesProcessed dd 0
- ; current mask value
- wCODECMask dw 0
- ; temp step value
- dwCODECTempStep dd 0
- _DATA ends
- _TEXT segment dword public USE32 'CODE'
- sosCODECInitStream_:
- ; save used registers
- push ebx
- ;
- ; set up pointer to _SOS_COMPRESS_INFO
- ; structure in EBX.
- ;
- mov ebx, eax
- ;
- ; init members of compression stream
- ;
- mov word ptr [ ebx ].wIndex, 0
- mov word ptr [ ebx ].wStep, 7
- mov dword ptr [ ebx ].dwPredicted, 0
- mov dword ptr [ ebx ].dwSampleIndex, 0
- ; restore registers
- pop ebx
- ret
-
- ;
- ; DWORD sosCODECDecompressData( _SOS_COMPRESS_INFO * sSOSInfo, DWORD wBytes )
- ;
- ; decompress data from a 4:1 ADPCM compressed file. the number of
- ; bytes decompressed is returned.
- ;
- ;
- sosCODECDecompressData_:
- ; eax = sSOSInfo
- ; edx = wBytes
- ;
- ; save registers used
- ;
- push esi
- push edi
- push ebx
- push ecx
- push edx
- ;
- ; set up EBX as a pointer to
- ; info structure.
- ;
- mov ebx, eax
- ;
- ; set up byte counter. if 16 bit data
- ; divide bytes by two since we will
- ; spit out two bytes @ a time.
- ;
- mov eax, edx
- mov wCODECBytesProcessed, eax
- mov wCODECByteIndex, eax
- ;
- ; set up source and destination
- ; pointers
- ;
- mov esi, [ ebx ].Source
- mov edi, [ ebx ].Dest
- Decompmainloop:
- ;
- ; determine if sample index is even
- ; or odd. this will determine if we
- ; need to get a new token or not.
- ;
- test dword ptr [ ebx ].dwSampleIndex, 1
- je short DecompfetchToken
- ;
- ; get token
- ;
- movzx eax, word ptr [ ebx ].wCodeBuf
- shr eax, 4
- and eax, 000fh
- mov word ptr [ ebx ].wCode, ax
- jmp short DecompcalcDifference
- DecompfetchToken:
- ;
- ; fetch new token
- ;
- xor eax, eax
- mov al, byte ptr [ esi ]
- mov word ptr [ ebx ].wCodeBuf, ax
- inc esi
- and eax, 000fh
- mov word ptr [ ebx ].wCode, ax
- DecompcalcDifference:
- ;
- ; reset difference
- ;
- mov dword ptr [ ebx ].dwDifference, 0
- ;
- ; set up ECX as the step value
- ;
- movzx ecx, word ptr [ ebx ].wStep
- ;
- ; check for wCode & 4
- ;
- test eax, 4
- je short Decompno4
- ; add wStep
- add dword ptr [ ebx ].dwDifference, ecx
- Decompno4:
- ;
- ; check for wCode & 2
- ;
- test eax, 2
- je short Decompno2
- ; add wStep >> 1
- mov edx, ecx
- shr edx, 1
- add dword ptr [ ebx ].dwDifference, edx
- Decompno2:
- ;
- ; check for wCode & 1
- ;
- test eax, 1
- je short Decompno1
- ; add wStep >> 2
- mov edx, ecx
- shr edx, 2
- add dword ptr [ ebx ].dwDifference, edx
- Decompno1:
- ;
- ; add in wStep >> 3
- ;
- mov edx, ecx
- shr edx, 3
- add dword ptr [ ebx ].dwDifference, edx
- ;
- ; check for wCode & 8
- ;
- test eax, 8
- je short Decompno8
- ; negate difference
- neg dword ptr [ ebx ].dwDifference
- Decompno8:
- ;
- ; add difference to predicted
- ; value.
- ;
- mov eax, [ ebx ].dwPredicted
- add eax, [ ebx ].dwDifference
- ;
- ; make sure there is no under or
- ; overflow.
- ;
- cmp eax, 7fffh
- jl short DecompnoOverflow
- mov eax, 7fffh
- DecompnoOverflow:
- cmp eax, 0ffff8000h
- jg short DecompnoUnderflow
- mov eax, 0ffff8000h
- DecompnoUnderflow:
- mov dword ptr [ ebx ].dwPredicted, eax
- ;
- ; output 8 bit sample
- ;
- xor ah, 80h
- mov al, ah
- stosb
- ;
- ; adjust index
- ;
- movzx ecx, word ptr [ ebx ].wCode
- movzx eax, word ptr wCODECIndexTab[ ecx * 2 ]
- add word ptr [ ebx ].wIndex, ax
- ;
- ; check if wIndex < 0
- ;
- cmp word ptr [ ebx ].wIndex, 8000h
- jb short DecompcheckOverflow
- ; reset index to zero
- mov word ptr [ ebx ].wIndex, 0
- jmp short DecompadjustStep
- DecompcheckOverflow:
- ;
- ; check if wIndex > 88
- ;
- cmp word ptr [ ebx ].wIndex, 88
- jbe short DecompadjustStep
- ; reset index to 88
- mov word ptr [ ebx ].wIndex, 88
- DecompadjustStep:
- ;
- ; fetch wIndex so we can fetch
- ; new step value
- ;
- movzx ecx, word ptr [ ebx ].wIndex
- movzx eax, word ptr wCODECStepTab[ ecx * 2 ]
- ;
- ; advance index and store step value
- ;
- add dword ptr [ ebx ].dwSampleIndex, 1
- mov word ptr [ ebx ].wStep, ax
- ;
- ; decrement bytes processed
- ; and loop back.
- ;
- dec wCODECByteIndex
- jne Decompmainloop
- ;
- ; save off ESI and EDI back into
- ; compress info structure.
- ;
- mov dword ptr [ ebx ].Source, esi
- mov dword ptr [ ebx ].Dest, edi
- ;
- ; set up return value for number
- ; of bytes processed.
- ;
- mov eax, wCODECBytesProcessed
- ;
- ; restore registers
- ;
- pop edx
- pop ecx
- pop ebx
- pop edi
- pop esi
- ret
- ;
- ; DWORD sosCODECCompressData( _SOS_COMPRESS_INFO * sSOSInfo, DWORD wBytes )
- ;
- ; Compresses a data stream into 4:1 ADPCM. 16 bit data is compressed 4:1
- ; 8 bit data is compressed 2:1.
- ;
- ;
- sosCODECCompressData_:
- ; eax = sSOSInfo
- ; edx = wBytes
- ;
- ; save registers used
- ;
- push esi
- push edi
- push ebx
- push ecx
- push edx
- ;
- ; set up EBX as a pointer to
- ; info structure.
- ;
- mov ebx, eax
- ;
- ; set up byte counter. if 16 bit data
- ; divide bytes by two since we will
- ; spit out two bytes @ a time.
- ;
- mov eax, edx
- mov wCODECBytesProcessed, eax
- ;
- ; check for 16 bit decompression
- ;
- cmp word ptr [ ebx ].wBitSize, 16
- jne short CompskipByteDivide
- ;
- ; divide size requested by two
- ;
- shr eax, 1
- CompskipByteDivide:
- mov wCODECByteIndex, eax
- ;
- ; set up source and destination
- ; pointers
- ;
- mov esi, [ ebx ].Source
- mov edi, [ ebx ].Dest
- Compmainloop:
- ;
- ; determine bit size for input
- ;
- cmp word ptr [ ebx ].wBitSize, 16
- jne short Compinput8Bit
- ;
- ; get 16 bit sample
- ;
- movsx eax, word ptr [ esi ]
- add esi, 2
- jmp short CompcomputeDiff
- Compinput8Bit:
- ;
- ; get 8 bit sample
- ;
- mov ah, byte ptr [ esi ]
- inc esi
- xor al, al
- xor ah, 80h
- movsx eax, ax
- CompcomputeDiff:
- ;
- ; compute difference
- ;
- movsx ecx, word ptr [ ebx ].dwPredicted
- sub eax, ecx
- ;
- ; check if dwDifference > 0. ECX is the
- ; sign bit, it is initialized to positive.
- ;
- xor ecx, ecx
- cmp eax, 0
- jge Comppositive
- ;
- ; negate difference
- ;
- neg eax
- or ecx, 8
- Comppositive:
- ;
- ; store code value
- ;
- mov word ptr [ ebx ].wCode, cx
- ;
- ; set up to quantize difference. initialize
- ; wCODECTempStep = step value.
- ;
- movsx ecx, word ptr [ ebx ].wStep
- mov dwCODECTempStep, ecx
- mov edx, 4
- mov ecx, 3
- CompquantizeLoop:
- ;
- ; check to see if difference > tempstep
- ; value.
- ;
- cmp eax, dwCODECTempStep
- jl short CompnextQLoop
- ;
- ; OR in mask value into code and
- ; adjust difference.
- ;
- or word ptr [ ebx ].wCode, dx
- sub eax, dwCODECTempStep
- CompnextQLoop:
- ;
- ; shift down tempstep and mask
- ;
- shr dwCODECTempStep, 1
- shr edx, 1
- loop CompquantizeLoop
- ;
- ; store off new difference value
- ;
- mov dword ptr [ ebx ].dwDifference, eax
- ;
- ; determine if sample index is even
- ; or odd. this will determine if we
- ; need to get a new token or not.
- ;
- test dword ptr [ ebx ].dwSampleIndex, 1
- jne short CompstoreToken
- ;
- ; get token
- ;
- movzx eax, word ptr [ ebx ].wCode
- and eax, 0fh
- mov word ptr [ ebx ].wCodeBuf, ax
- jmp short CompcalcDifference
- CompstoreToken:
- ;
- ; fetch new token
- ;
- movzx eax, word ptr [ ebx ].wCode
- shl eax, 4
- or ax, word ptr [ ebx ].wCodeBuf
- mov byte ptr [ edi ], al
- inc edi
- CompcalcDifference:
- ;
- ; reset difference
- ;
- mov dword ptr [ ebx ].dwDifference, 0
- ;
- ; set up ECX as the step value
- ;
- movzx ecx, word ptr [ ebx ].wStep
- ;
- ; get code in AX
- ;
- movzx eax, word ptr [ ebx ].wCode
- ;
- ; check for wCode & 4
- ;
- test eax, 4
- je short Compno4
- ; add wStep
- add dword ptr [ ebx ].dwDifference, ecx
- Compno4:
- ;
- ; check for wCode & 2
- ;
- test eax, 2
- je short Compno2
- ; add wStep >> 1
- mov edx, ecx
- shr edx, 1
- add dword ptr [ ebx ].dwDifference, edx
- Compno2:
- ;
- ; check for wCode & 1
- ;
- test eax, 1
- je short Compno1
- ; add wStep >> 2
- mov edx, ecx
- shr edx, 2
- add dword ptr [ ebx ].dwDifference, edx
- Compno1:
- ;
- ; add in wStep >> 3
- ;
- mov edx, ecx
- shr edx, 3
- add dword ptr [ ebx ].dwDifference, edx
- ;
- ; check for wCode & 8
- ;
- test eax, 8
- je short Compno8
- ; negate difference
- neg dword ptr [ ebx ].dwDifference
- Compno8:
- ;
- ; add difference to predicted
- ; value.
- ;
- mov eax, [ ebx ].dwPredicted
- add eax, [ ebx ].dwDifference
- ;
- ; make sure there is no under or
- ; overflow.
- ;
- cmp eax, 7fffh
- jl short CompnoOverflow
- mov eax, 7fffh
- CompnoOverflow:
- cmp eax, 0ffff8000h
- jg short CompnoUnderflow
- mov eax, 0ffff8000h
- CompnoUnderflow:
- mov dword ptr [ ebx ].dwPredicted, eax
- ;
- ; adjust index
- ;
- movzx ecx, word ptr [ ebx ].wCode
- movzx eax, word ptr wCODECIndexTab[ ecx * 2 ]
- add word ptr [ ebx ].wIndex, ax
- ;
- ; check if wIndex < 0
- ;
- cmp word ptr [ ebx ].wIndex, 8000h
- jb short CompcheckOverflow
- ; reset index to zero
- mov word ptr [ ebx ].wIndex, 0
- jmp short CompadjustStep
- CompcheckOverflow:
- ;
- ; check if wIndex > 88
- ;
- cmp word ptr [ ebx ].wIndex, 88
- jbe short CompadjustStep
- ; reset index to 88
- mov word ptr [ ebx ].wIndex, 88
- CompadjustStep:
- ;
- ; fetch wIndex so we can fetch
- ; new step value
- ;
- movzx ecx, word ptr [ ebx ].wIndex
- movzx eax, word ptr wCODECStepTab[ ecx * 2 ]
- ;
- ; advance index and store step value
- ;
- add dword ptr [ ebx ].dwSampleIndex, 1
- mov word ptr [ ebx ].wStep, ax
- ;
- ; decrement bytes processed
- ; and loop back.
- ;
- dec wCODECByteIndex
- jne Compmainloop
- ;
- ; save off ESI and EDI back into
- ; compress info structure.
- ;
- mov dword ptr [ ebx ].Source, esi
- mov dword ptr [ ebx ].Dest, edi
- ;
- ; set up return value for number
- ; of bytes processed.
- ;
- mov eax, wCODECBytesProcessed
- shr eax, 2
- ;
- ; restore registers
- ;
- pop edx
- pop ecx
- pop ebx
- pop edi
- pop esi
- ret
- _TEXT ends
- end
|