wrote a simple wave loader to remove dependency on a private openal function.

This commit is contained in:
Steven Fuller 2007-01-13 07:48:52 +00:00 committed by Patryk Obara
parent 0e484b73da
commit 71204923ad
2 changed files with 172 additions and 114 deletions

View file

@ -8,10 +8,10 @@ CFLAGS = -g -Wall -pipe -O2
CFLAGS += -DLINUX
CFLAGS += -Dengine=1 -I. -Iinclude -Iwin95 -Iavp -Iavp/win95 -Iavp/support -Iavp/win95/frontend -Iavp/win95/gadgets
CFLAGS += $(shell sdl-config --cflags)
CFLAGS += $(shell sdl-config --cflags) $(shell openal-config --cflags)
CXXFLAGS = $(CFLAGS)
LDLIBS = $(shell sdl-config --libs) -lopenal
LDLIBS = $(shell sdl-config --libs) $(shell openal-config --libs)
ROOT = main.c files.c winapi.c stubs.c version.c mathline.c opengl.c oglfunc.c openal.c cdplayer.c menus.c net.c frustum.c kshape.c map.c maths.c md5.c mem3dc.c mem3dcpp.cpp module.c morph.c object.c shpanim.c sphere.c tables.c vdb.c
AVP = ai_sight.c avpview.c bh_agun.c bh_ais.c bh_alien.c bh_binsw.c bh_cable.c bh_corpse.c bh_deathvol.c bh_debri.c bh_dummy.c bh_fan.c bh_far.c bh_fhug.c bh_gener.c bh_ldoor.c bh_lift.c bh_light.c bh_lnksw.c bh_ltfx.c bh_marin.c bh_mission.c bh_near.c bh_pargen.c bh_plachier.c bh_plift.c bh_pred.c bh_queen.c bh_rubberduck.c bh_selfdest.c bh_snds.c bh_spcl.c bh_swdor.c bh_track.c bh_types.c bh_videoscreen.c bh_waypt.c bh_weap.c bh_xeno.c bonusabilities.c cconvars.cpp cdtrackselection.cpp cheatmodes.c comp_map.c comp_shp.c consolelog.cpp davehook.cpp deaths.c decal.c detaillevels.c dynamics.c dynblock.c equipmnt.c equiputl.cpp extents.c game.c game_statistics.c gamecmds.cpp gamevars.cpp hmodel.c hud.c inventry.c language.c lighting.c load_shp.c los.c maps.c mempool.c messagehistory.c missions.cpp movement.c paintball.c particle.c pfarlocs.c pheromon.c player.c pmove.c psnd.c psndproj.c pvisible.c savegame.c scream.cpp secstats.c sfx.c stratdef.c targeting.c track.c triggers.c weapons.c
@ -48,15 +48,15 @@ WIN95OBJ = $(call OBJNAMES,$(WIN95),win95)
SRC = $(ROOTSRC) $(AVPSRC) $(SHAPESSRC) $(SUPPORTSRC) $(AVPWIN95SRC) $(FRONTENDSRC) $(GADGETSSRC) $(WIN95SRC)
OBJ = $(ROOTOBJ) $(AVPOBJ) $(SHAPESOBJ) $(SUPPORTOBJ) $(AVPWIN95OBJ) $(FRONTENDOBJ) $(GADGETSOBJ) $(WIN95OBJ)
all: AvP
all: AvP.bin
AvP: $(OBJ) # depend $(OBJ)
$(CXX) -o AvP $(OBJ) $(LDLIBS)
AvP.bin: $(OBJ) # depend $(OBJ)
$(CXX) -o AvP.bin $(OBJ) $(LDLIBS)
compile: $(OBJ)
clean:
-rm -rf depend depend.bak $(OBJ) AvP
-rm -rf depend depend.bak $(OBJ) AvP.bin
distclean: clean
-rm -rf `find . -name "*~"`

View file

@ -5,9 +5,6 @@
#include <AL/al.h>
#include <AL/alc.h>
#include <AL/alut.h>
#include <SDL/SDL_audio.h> // For a few defines (AUDIO_*)
#include "fixer.h"
@ -35,6 +32,112 @@ extern int WantSound;
static int SoundActivated = 0;
/* start simplistic riff wave parsing */
#define lsb8 (buf, x) (((unsigned int)buf[(x)+0] << 0))
#define lsb16(buf, x) (((unsigned int)buf[(x)+0] << 0) | ((unsigned int)buf[(x)+1] << 8))
#define lsb32(buf, x) (((unsigned int)buf[(x)+0] << 0) | ((unsigned int)buf[(x)+1] << 8) | ((unsigned int)buf[(x)+2] << 16) | ((unsigned int)buf[(x)+3] << 24))
typedef struct FormatChunk {
short wFormatTag;
unsigned short wChannels;
unsigned long dwSamplesPerSec;
unsigned long dwAvgBytesPerSec;
unsigned short wBlockAlign;
unsigned short wBitsPerSample;
} FormatChunk;
typedef struct DataChunk {
unsigned char* pData;
unsigned int dwLength;
} DataChunk;
static int ParseWAV( const unsigned char* data, unsigned char** pFmtPtr, unsigned char** pDataPtr )
{
unsigned char* pData;
unsigned char* pDataEnd;
unsigned char* fmtPtr;
int riffLength;
int chunkLength;
if( data == NULL || pFmtPtr == NULL || pDataPtr == NULL ) {
return 0;
}
/* assuming input data is complete and not corrupt... */
pData = (unsigned char*) data;
/* bytes 0-3 are the RIFF groupId */
if( pData[ 0 ] != 'R' || pData[ 1 ] != 'I' || pData[ 2 ] != 'F' || pData[ 3 ] != 'F' ) {
/* bad group id */
return 0;
}
/* bytes 4-7 are the RIFF length. */
riffLength = lsb32( pData, 4 );
pDataEnd = pData + 8 + riffLength;
if( pData[ 8 ] != 'W' || pData[ 9 ] != 'A' || pData[ 10 ] != 'V' || pData[ 11 ] != 'E' ) {
/* bad riff type */
return 0;
}
/* all valid wave files have the 'fmt ' chunk before the 'data' chunk. */
/* skip passed the initial header. */
pData += 12;
/* look for the 'fmt ' and 'data' chunks. */
fmtPtr = NULL;
while( pData+8 < pDataEnd ) {
chunkLength = lsb32( pData, 4 );
if( fmtPtr == NULL && pData[ 0 ] == 'f' && pData[ 1 ] == 'm' && pData[ 2 ] == 't' && pData[ 3 ] == ' ' ) {
fmtPtr = pData;
} else if( fmtPtr != NULL && pData[ 0 ] == 'd' && pData[ 1 ] == 'a' && pData[ 2 ] == 't' && pData[ 3 ] == 'a' ) {
*pFmtPtr = fmtPtr;
*pDataPtr = pData;
return 1;
}
pData += 8 + chunkLength;
}
return 0;
}
static int SimpleLoadWAV( const unsigned char* data, FormatChunk* pFmtChunk, DataChunk* pDataChunk)
{
unsigned char* fmtPtr;
unsigned char* dataPtr;
if( data == NULL || pFmtChunk == NULL || pDataChunk == NULL ) {
return 0;
}
if( !ParseWAV( data, &fmtPtr, &dataPtr ) ) {
return 0;
}
pFmtChunk->wFormatTag = lsb16( fmtPtr, 8 );
pFmtChunk->wChannels = lsb16( fmtPtr, 10 );
pFmtChunk->dwSamplesPerSec = lsb32( fmtPtr, 12 );
pFmtChunk->dwAvgBytesPerSec = lsb32( fmtPtr, 16 );
pFmtChunk->wBlockAlign = lsb16( fmtPtr, 20 );
pFmtChunk->wBitsPerSample = lsb16( fmtPtr, 22 );
pDataChunk->pData = &dataPtr[ 8 ];
pDataChunk->dwLength = lsb32( dataPtr, 4 );
return 1;
}
/* end simplistic riff wave parsing */
/*
openal.c TODO:
1. There is no EAX/Reverb. But there's probably not much I can do...
@ -821,29 +924,54 @@ void UpdateSoundFrequencies()
}
}
// In libopenal
extern void *acLoadWAV (void *data, ALuint *size, void **udata,
ALushort *fmt, ALushort *chan, ALushort *freq);
static unsigned char *Force8to16 (unsigned char *buf, int *len)
static int LoadWAV( ALvoid* data, ALvoid** bufferPtr, ALushort* format, ALushort* freq, int* len, int* seclen )
{
unsigned char *nbuf;
unsigned int i;
nbuf = (unsigned char *) AllocateMem (*len * 2);
for (i = 0; i < *len; i++) {
short int x = ((buf[i] << 8) | buf[i]) ^ 0x8000;
nbuf[i*2+0] = (x & 0x00ff);
nbuf[i*2+1] = (x >> 8) & 0xff;
FormatChunk fmtChunk;
DataChunk dataChunk;
if( !SimpleLoadWAV( (unsigned char*)data, &fmtChunk, &dataChunk ) ) {
printf("WAV DEBUG: file didn't parse\n");
return 0;
}
*len *= 2;
return nbuf;
if( fmtChunk.wFormatTag != 1 ) {
printf("WAV DEBUG: got format tag %d\n", fmtChunk.wFormatTag );
return 0;
}
if( fmtChunk.wBitsPerSample == 8 ) {
if( fmtChunk.wChannels == 1 ) {
*format = AL_FORMAT_MONO8;
} else if( fmtChunk.wChannels == 2 ) {
*format = AL_FORMAT_STEREO8;
} else {
printf("WAV DEBUG: too many channels\n" );
return 0;
}
} else if( fmtChunk.wBitsPerSample == 16 ) {
if( fmtChunk.wChannels == 1 ) {
*format = AL_FORMAT_MONO16;
} else if( fmtChunk.wChannels == 2 ) {
*format = AL_FORMAT_STEREO16;
} else {
printf("WAV DEBUG: too many channels\n" );
return 0;
}
} else {
printf("WAV DEBUG: bad bit setup\n");
return 0;
}
*freq = fmtChunk.dwSamplesPerSec;
*len = dataChunk.dwLength;
*bufferPtr = dataChunk.pData;
*seclen = DIV_FIXED( dataChunk.dwLength, fmtChunk.dwAvgBytesPerSec );
return 1;
}
int LoadWavFile(int soundNum, char * wavFileName)
{
ALuint size;
@ -851,7 +979,8 @@ int LoadWavFile(int soundNum, char * wavFileName)
ALvoid *data, *bufferPtr;
int len, seclen;
FILE *fp;
char* wavname;
#ifdef OPENAL_DEBUG
fprintf(stderr, "LoadWavFile(%d, %s) - sound\n", soundNum, wavFileName);
#endif
@ -872,57 +1001,22 @@ int LoadWavFile(int soundNum, char * wavFileName)
fread(data, 1, len, fp);
fclose(fp);
if (acLoadWAV (data, &size, &bufferPtr, &format,
&chan, &freq) == NULL) {
fprintf(stderr, "LoadWavFile: Unable to convert data\n");
free(data);
return 0;
}
free(data);
data = bufferPtr;
len = size;
/* openal conv. 8->16 is not good at all */
if (format == AUDIO_U8) {
unsigned char *nb = Force8to16 (data, &len);
format = AUDIO_S16LSB;
free (data);
data = nb;
}
if ((format == AUDIO_S16LSB) || (format == AUDIO_S16MSB)) {
int bps;
if (chan == 2) {
format = AL_FORMAT_STEREO16;
bps = freq * 2 * 2;
} /* else if (rchan == 1) */ {
format = AL_FORMAT_MONO16;
bps = freq * 2 * 1;
}
seclen = DIV_FIXED(len, bps);
} else {
free(data);
if( !LoadWAV( data, &bufferPtr, &format, &len, &seclen, &freq ) ) {
free( data );
return 0;
}
alGenBuffers (1, &(GameSounds[soundNum].dsBufferP));
alBufferData (GameSounds[soundNum].dsBufferP, format, data, len, freq);
alBufferData (GameSounds[soundNum].dsBufferP, format, bufferPtr, len, freq);
{
char * wavname = strrchr (wavFileName, '\\');
wavname = strrchr (wavFileName, '\\');
if (wavname)
wavname++;
else
wavname = wavFileName;
GameSounds[soundNum].wavName = (char *)AllocateMem (strlen (wavname) + 1);
strcpy (GameSounds[soundNum].wavName, wavname);
}
GameSounds[soundNum].flags = SAMPLE_IN_HW;
GameSounds[soundNum].length = (seclen != 0) ? seclen : 1;
GameSounds[soundNum].dsFrequency = freq;
@ -957,58 +1051,22 @@ fprintf(stderr, "OPENAL: ExtractWavFile(%d, %p)\n", soundIndex, bufferPtr);
fprintf(stderr, "OPENAL: Loaded %s\n", GameSounds[soundIndex].wavName);
#endif
#if 1 /* TODO: replace with own routine later */
if (acLoadWAV (bufferPtr, &rsize, &udata, &rfmt,
&rchan, &rfreq) == NULL) {
fprintf(stderr, "ExtractWavFile: Unable to convert data\n");
return NULL;
if( LoadWAV( bufferPtr, &udata, &rfmt, &len, &seclen, &rfreq ) ) {
alGenBuffers (1, &(GameSounds[soundIndex].dsBufferP));
alBufferData (GameSounds[soundIndex].dsBufferP,
rfmt, udata, len, rfreq);
/* GameSounds[soundIndex].loaded = 1; */
GameSounds[soundIndex].flags = SAMPLE_IN_HW;
GameSounds[soundIndex].length = (seclen != 0) ? seclen : 1;
GameSounds[soundIndex].dsFrequency = rfreq;
/* GameSounds[soundIndex].pitch = PITCH_DEFAULTPLAT; */
}
len = rsize;
/* openal conv. 8->16 is not good at all */
if (rfmt == AUDIO_U8) {
unsigned char *nb = Force8to16 (udata, &len);
rfmt = AUDIO_S16LSB;
free (udata);
udata = nb;
}
if ((rfmt == AUDIO_S16LSB) || (rfmt == AUDIO_S16MSB)) {
int bps;
if (rchan == 2) {
rfmt = AL_FORMAT_STEREO16;
bps = rfreq * 2 * 2;
} /* else if (rchan == 1) */ {
rfmt = AL_FORMAT_MONO16;
bps = rfreq * 2 * 1;
}
seclen = DIV_FIXED(len, bps);
} else
return NULL;
#endif
alGenBuffers (1, &(GameSounds[soundIndex].dsBufferP));
alBufferData (GameSounds[soundIndex].dsBufferP,
rfmt, udata, len, rfreq);
/* GameSounds[soundIndex].loaded = 1; */
GameSounds[soundIndex].flags = SAMPLE_IN_HW;
GameSounds[soundIndex].length = (seclen != 0) ? seclen : 1;
GameSounds[soundIndex].dsFrequency = rfreq;
/* GameSounds[soundIndex].pitch = PITCH_DEFAULTPLAT; */
#if 1 /* TODO: see above */
free (udata);
/* read RIFF chunk length and jump past it */
return bufferPtr + 8 +
((bufferPtr[4] << 0) | (bufferPtr[5] << 8) |
(bufferPtr[6] << 16) | (bufferPtr[7] << 24));
#endif
}
int LoadWavFromFastFile(int soundNum, char * wavFileName)