/* $Id: sound_linux.c,v 1.1 2000/07/28 15:27:35 hans Exp $ * Linux/FreeBSD do not have alutLoadWAVMemory / alutUnloadWAV */ #ifdef USE_OPENAL #ifndef _WIN32 #include #include #include #include #include ALvoid alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq); ALvoid alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq); typedef struct /* WAV File-header */ { ALubyte Id[4]; ALsizei Size; ALubyte Type[4]; } WAVFileHdr_Struct; typedef struct /* WAV Fmt-header */ { ALushort Format; ALushort Channels; ALuint SamplesPerSec; ALuint BytesPerSec; ALushort BlockAlign; ALushort BitsPerSample; } WAVFmtHdr_Struct; typedef struct /* WAV FmtEx-header */ { ALushort Size; ALushort SamplesPerBlock; } WAVFmtExHdr_Struct; typedef struct /* WAV Smpl-header */ { ALuint Manufacturer; ALuint Product; ALuint SamplePeriod; ALuint Note; ALuint FineTune; ALuint SMPTEFormat; ALuint SMPTEOffest; ALuint Loops; ALuint SamplerData; struct { ALuint Identifier; ALuint Type; ALuint Start; ALuint End; ALuint Fraction; ALuint Count; } Loop[1]; } WAVSmplHdr_Struct; typedef struct /* WAV Chunk-header */ { ALubyte Id[4]; ALuint Size; } WAVChunkHdr_Struct; ALvoid alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq) { WAVChunkHdr_Struct ChunkHdr; WAVFmtExHdr_Struct FmtExHdr; WAVFileHdr_Struct FileHdr; WAVSmplHdr_Struct SmplHdr; WAVFmtHdr_Struct FmtHdr; ALbyte *Stream; *format=AL_FORMAT_MONO16; *data=NULL; *size=0; *freq=22050; if (memory) { Stream=memory; if (Stream) { memcpy(&FileHdr,Stream,sizeof(WAVFileHdr_Struct)); Stream+=sizeof(WAVFileHdr_Struct); FileHdr.Size=((FileHdr.Size+1)&~1)-4; while ((FileHdr.Size!=0)&&(memcpy(&ChunkHdr,Stream,sizeof(WAVChunkHdr_Struct)))) { Stream+=sizeof(WAVChunkHdr_Struct); if (!memcmp(ChunkHdr.Id,"fmt ",4)) { memcpy(&FmtHdr,Stream,sizeof(WAVFmtHdr_Struct)); if (FmtHdr.Format==0x0001) { *format=(FmtHdr.Channels==1? (FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16): (FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16)); *freq=FmtHdr.SamplesPerSec; Stream+=ChunkHdr.Size; } else { memcpy(&FmtExHdr,Stream,sizeof(WAVFmtExHdr_Struct)); Stream+=ChunkHdr.Size; } } else if (!memcmp(ChunkHdr.Id,"data",4)) { if (FmtHdr.Format==0x0001) { *size=ChunkHdr.Size; *data=malloc(ChunkHdr.Size+31); if (*data) memcpy(*data,Stream,ChunkHdr.Size); memset(((char *)*data)+ChunkHdr.Size,0,31); Stream+=ChunkHdr.Size; } else if (FmtHdr.Format==0x0011) { //IMA ADPCM } else if (FmtHdr.Format==0x0055) { //MP3 WAVE } } else if (!memcmp(ChunkHdr.Id,"smpl",4)) { memcpy(&SmplHdr,Stream,sizeof(WAVSmplHdr_Struct)); Stream+=ChunkHdr.Size; } else Stream+=ChunkHdr.Size; Stream+=ChunkHdr.Size&1; FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8); } } } } ALvoid alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq) { if (data) free(data); } #endif /* _WIN32 */ #endif /* USE_OPENAL */