mirror of
https://github.com/electronicarts/CnC_Red_Alert.git
synced 2025-12-16 07:31:39 -05:00
Initial commit of Command & Conquer Red Alert source code.
This commit is contained in:
398
VQ/VQM32/AUDZAP.CPP
Normal file
398
VQ/VQM32/AUDZAP.CPP
Normal file
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
** Command & Conquer Red Alert(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* C O N F I D E N T I A L --- W E S T W O O D S T U D I O S
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*
|
||||
* FILE
|
||||
* Audzap.c
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Lossy audio compression. (32-Bit protected mode)
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Joe L. Bostic
|
||||
*
|
||||
* DATE
|
||||
* January 26, 1995
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*
|
||||
* PUBLIC
|
||||
* AudioZap - Compress audio sample data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <mem.h>
|
||||
#include "compress.h"
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* PRIVATE DECLARATIONS
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
|
||||
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
|
||||
|
||||
typedef enum {
|
||||
CODE_2BIT, /* Bit packed 2 bit delta. */
|
||||
CODE_4BIT, /* Nibble packed 4 bit delta. */
|
||||
CODE_RAW, /* Raw sample. */
|
||||
CODE_SILENCE /* Run of silence. */
|
||||
} SCodeType;
|
||||
|
||||
char _2bitencode[5] = {
|
||||
0,1,2,3
|
||||
};
|
||||
|
||||
long _2bitdecode[4] = {
|
||||
-2,-1,0,1
|
||||
};
|
||||
|
||||
char _4bitencode[19] = {
|
||||
0,1,2,2,3,4,5,6,7,(8),
|
||||
8,9,10,11,12,13,13,14,15
|
||||
};
|
||||
|
||||
long _4bitdecode[16] = {
|
||||
-9,-8,-6,-5,-4,-3,-2,
|
||||
-1,0,1,2,3,4,5,6,8
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* AudioZap - Compress audio sample data.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* Size = AudioZap(Source, Dest, Size)
|
||||
*
|
||||
* long AudioZap(void *, void *, long);
|
||||
*
|
||||
* FUNCTION
|
||||
* NOTE - If the compressed size is equal to or greater than the original
|
||||
* size then the data could not be compressed and the uncompressed data
|
||||
* should be written.
|
||||
*
|
||||
* INPUTS
|
||||
* Source - Pointer to buffer containing audio sample data.
|
||||
* Dest - Pointer to buffer to put encoded data.
|
||||
* Size - Number of bytes to compress.
|
||||
*
|
||||
* RESULT
|
||||
* Size - Size in bytes of encoded data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
long AudioZap(void *source, void *dest, long size)
|
||||
{
|
||||
unsigned char *s = (unsigned char *)source;
|
||||
unsigned char *d = (unsigned char *)dest;
|
||||
long delta;
|
||||
unsigned long previous = 0x80;
|
||||
long outcount = 0;
|
||||
unsigned char *s4;
|
||||
unsigned long p4;
|
||||
long max4;
|
||||
unsigned char *lastraw = 0;
|
||||
long osize = size;
|
||||
unsigned long i;
|
||||
unsigned long dd;
|
||||
|
||||
/* Reduce very small amplitudes to silence. Usually a rather large
|
||||
* portion of a sample is hovering around the silence value. This is
|
||||
* due, in part, to the artifacting of the sample process. These low
|
||||
* amplitudes are not audible.
|
||||
*/
|
||||
max4 = size;
|
||||
s = (unsigned char *)source;
|
||||
|
||||
while (size > 0 && outcount < osize) {
|
||||
|
||||
/* First check for runs of zero deltas. If a run of at least
|
||||
* any can be found, then output it.
|
||||
*/
|
||||
s4 = s;
|
||||
max4 = MIN(63 + 1, size);
|
||||
|
||||
for (i = 0; i < max4; i++) {
|
||||
if (previous != *s4++)
|
||||
break;
|
||||
}
|
||||
|
||||
/* When there is a code transition, terminate any run of raw
|
||||
* samples.
|
||||
*/
|
||||
if (i > 2) {
|
||||
lastraw = 0;
|
||||
*d++ = ((i - 1)|(CODE_SILENCE << 6));
|
||||
outcount++;
|
||||
s += i;
|
||||
size -= i;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If there are fewer than 4 samples remaining, then using delta
|
||||
* compression is inefficient. Just drop into the raw routine
|
||||
*/
|
||||
if (size > 4) {
|
||||
s4 = s;
|
||||
p4 = previous;
|
||||
|
||||
/* Find out the number of lossless 2 bit deltas available. These
|
||||
* deltas are always present in quads. The compressed code is
|
||||
* the delta quad count followed by the deltas in bit packed bytes.
|
||||
*/
|
||||
max4 = MIN(64L * 4L + 4L + 4L, size);
|
||||
|
||||
for (i = 0; i < max4; i++) {
|
||||
delta = (((int)*s4++) - p4);
|
||||
|
||||
if ((delta < -2) || (delta > 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
p4 += _2bitdecode[_2bitencode[delta + 2]];
|
||||
|
||||
if (((signed)p4) < 0) {
|
||||
p4 = 0;
|
||||
}
|
||||
|
||||
if (((signed)p4) > 255) {
|
||||
p4 = 255;
|
||||
}
|
||||
}
|
||||
|
||||
i >>= 2; // Delta 2 always occur in quads -- force this.
|
||||
|
||||
/* If there is the minimum benificial number of delta 2s available,
|
||||
* then compress them.
|
||||
*/
|
||||
if (i) {
|
||||
|
||||
/* When there is a code transition, terminate any run of raw
|
||||
* samples.
|
||||
*/
|
||||
lastraw = 0;
|
||||
|
||||
/* Output the delta 4 pair count. This is the number of pairs
|
||||
* minus the 'free' two pairs already assumed to be there.
|
||||
*/
|
||||
i = MIN(i, (63 + 1));
|
||||
*d++ = ((i - 1)|(CODE_2BIT << 6));
|
||||
outcount++;
|
||||
|
||||
for (dd = 0; dd < i; dd++) {
|
||||
int delta1, delta2, delta3, delta4;
|
||||
|
||||
delta1 = _2bitencode[((((int)*s++) - previous) + 2)];
|
||||
previous += _2bitdecode[delta1];
|
||||
|
||||
if (((signed)previous) < 0) {
|
||||
previous = 0;
|
||||
}
|
||||
|
||||
if (((signed)previous) > 255) {
|
||||
previous = 255;
|
||||
}
|
||||
|
||||
size--;
|
||||
delta2 = _2bitencode[((((int)*s++) - previous) + 2)];
|
||||
previous += _2bitdecode[delta2];
|
||||
|
||||
if (((signed)previous) < 0) {
|
||||
previous = 0;
|
||||
}
|
||||
|
||||
if (((signed)previous) > 255) {
|
||||
previous = 255;
|
||||
}
|
||||
|
||||
size--;
|
||||
delta3 = _2bitencode[((((int)*s++) - previous) + 2)];
|
||||
previous += _2bitdecode[delta3];
|
||||
|
||||
if (((signed)previous) < 0) {
|
||||
previous = 0;
|
||||
}
|
||||
|
||||
if (((signed)previous) > 255) {
|
||||
previous = 255;
|
||||
}
|
||||
|
||||
size--;
|
||||
delta4 = _2bitencode[((((int)*s++) - previous) + 2)];
|
||||
previous += _2bitdecode[delta4];
|
||||
|
||||
if (((signed)previous) < 0) {
|
||||
previous = 0;
|
||||
}
|
||||
|
||||
if (((signed)previous) > 255) {
|
||||
previous = 255;
|
||||
}
|
||||
|
||||
size--;
|
||||
*d++ = ((delta4 << 6)|(delta3 << 4)|(delta2 << 2)|delta1);
|
||||
outcount++;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
s4 = s;
|
||||
p4 = previous;
|
||||
|
||||
/* Find out the number of lossless 4 bit deltas follow. These
|
||||
* deltas are always present in pairs. The compressed code is
|
||||
* the delta pair count followed by the deltas in nibble packed
|
||||
* bytes.
|
||||
*/
|
||||
max4 = MIN(64L * 2L + 4L + 4L, size);
|
||||
|
||||
for (i = 0; i < max4; i++) {
|
||||
delta = (((int)*s4++) - p4);
|
||||
|
||||
if (delta < -9 || delta >= 9) {
|
||||
break;
|
||||
}
|
||||
|
||||
p4 += _4bitdecode[_4bitencode[(delta + 9)]];
|
||||
|
||||
if (((signed)p4) < 0) {
|
||||
p4 = 0;
|
||||
}
|
||||
|
||||
if (((signed)p4) > 255) {
|
||||
p4 = 255;
|
||||
}
|
||||
}
|
||||
|
||||
i >>= 1; // Delta 4 always occur in pairs -- force this.
|
||||
|
||||
/* If there is the minimum benificial number of delta 4s available,
|
||||
* then compress them.
|
||||
*/
|
||||
if (i) {
|
||||
|
||||
/* When there is a code transition, terminate any run of raw
|
||||
* samples.
|
||||
*/
|
||||
lastraw = 0;
|
||||
|
||||
/* Output the delta 4 pair count. This is the number of pairs
|
||||
* minus the 'free' two pairs already assumed to be there.
|
||||
*/
|
||||
i = MIN(i, (63 + 1));
|
||||
*d++ = ((i - 1)|(CODE_4BIT << 6));
|
||||
outcount++;
|
||||
|
||||
for (dd = 0; dd < i; dd++) {
|
||||
int delta1, delta2;
|
||||
|
||||
delta1 = _4bitencode[((((int)*s++) - previous) + 9)];
|
||||
previous += _4bitdecode[delta1];
|
||||
|
||||
if (((signed)previous) < 0) {
|
||||
previous = 0;
|
||||
}
|
||||
|
||||
if (((signed)previous) > 255) {
|
||||
previous = 255;
|
||||
}
|
||||
|
||||
size--;
|
||||
delta2 = _4bitencode[((((int)*s++) - previous) + 9)];
|
||||
previous += _4bitdecode[delta2];
|
||||
|
||||
if (((signed)previous) < 0) {
|
||||
previous = 0;
|
||||
}
|
||||
|
||||
if (((signed)previous) > 255) {
|
||||
previous = 255;
|
||||
}
|
||||
|
||||
size--;
|
||||
*d++ = ((delta2 << 4)|(delta1 & 0x0F));
|
||||
outcount++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Raw output since deltas were unsuccessful. If this is a run
|
||||
* of raw output, then merely tack it onto the run rather than
|
||||
* create a new code sequence.
|
||||
*/
|
||||
if (lastraw) {
|
||||
*lastraw = ((*lastraw) + 1);
|
||||
|
||||
/* There is only so much a run code can accomodate. If the limit
|
||||
* has been reached, then terminate this code. A new one will be
|
||||
* created if necessary.
|
||||
*/
|
||||
if ((*lastraw & 0x1F) == 0x1F) {
|
||||
lastraw = 0;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* If there is no current raw dump of samples, then check to see if
|
||||
* this sample can fit into a 5 bit delta. If it can, then store
|
||||
* it as such as a parasite to the "raw" code. This will save a byte
|
||||
* for any stray 5 bit deltas that happen along. It is expected that
|
||||
* this is more frequent than 6 or more bit deltas that would necessitate
|
||||
* the use of the RAW code.
|
||||
*/
|
||||
delta = (((int)*s) - previous);
|
||||
|
||||
if ((delta >= -16) && (delta <= 15)) {
|
||||
lastraw = 0;
|
||||
*d++ = ((CODE_RAW << 6)|0x20|(delta & 0x1F));
|
||||
outcount++;
|
||||
previous = *s++;
|
||||
size--;
|
||||
continue;
|
||||
} else {
|
||||
lastraw = d;
|
||||
*d++ = (CODE_RAW << 6);
|
||||
outcount++;
|
||||
}
|
||||
}
|
||||
|
||||
*d++ = previous = *s++;
|
||||
size--;
|
||||
outcount++;
|
||||
}
|
||||
|
||||
/* Check to see if the compression process actually resulted in smaller
|
||||
* data size. In some cases, the 'compressed' data is actually larger. In
|
||||
* this case, just output the raw frame. If the compressed and actual frame
|
||||
* size match, then it is presumed that no compression occurs.
|
||||
*/
|
||||
if (outcount >= osize) {
|
||||
memcpy(dest, source, (size_t)osize);
|
||||
outcount = osize;
|
||||
}
|
||||
|
||||
return(outcount);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user