Wav loader is now endian safe (bug #165)

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@962 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
gewlitys
2003-05-13 22:16:18 +00:00
parent 52a1f58334
commit ce7692a68f
6 changed files with 137 additions and 185 deletions
+1
View File
@@ -1,4 +1,5 @@
Changes towards version 0.3: Changes towards version 0.3:
- Wav loader is now endian safe (bug #165) -Mika
- Dialogue patch for Melnorme, fixing bug #335 - Dialogue patch for Melnorme, fixing bug #335
- Two dialogue spots where visit count could run away patched; fixes bug - Two dialogue spots where visit count could run away patched; fixes bug
#333, from Stas Sergeev #333, from Stas Sergeev
+4
View File
@@ -3304,6 +3304,10 @@ SOURCE=..\types.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\endian.h
# End Source File
# Begin Source File
SOURCE=..\starcon2.c SOURCE=..\starcon2.c
# End Source File # End Source File
# End Group # End Group
+1 -14
View File
@@ -505,24 +505,11 @@ uint32 SoundDecoder_DecodeAll (TFB_SoundDecoder *decoder)
{ {
case SOUNDDECODER_WAV: case SOUNDDECODER_WAV:
{ {
bool loop;
LoadWAVFile (decoder->filename ,&decoder->format, &decoder->buffer, LoadWAVFile (decoder->filename ,&decoder->format, &decoder->buffer,
&decoder->buffer_size, &decoder->frequency, &loop); &decoder->buffer_size, &decoder->frequency, decoder_formats.want_big_endian);
if (decoder->buffer_size != 0) if (decoder->buffer_size != 0)
{ {
/* WAVs are loaded in little-endian order
* may need to do a word-swap
*/
if (decoder_formats.want_big_endian &&
(decoder->format == decoder_formats.stereo16
|| decoder->format == decoder_formats.mono16))
{
SoundDecoder_SwapWords (
decoder->buffer, decoder->buffer_size);
}
decoder->type = SOUNDDECODER_BUF; decoder->type = SOUNDDECODER_BUF;
decoder->data = decoder->buffer; decoder->data = decoder->buffer;
decoder->pos = 0; decoder->pos = 0;
@@ -79,7 +79,7 @@ enum
}; };
extern TFB_DecoderFormats decoder_formats; extern TFB_DecoderFormats decoder_formats;
void SoundDecoder_SwapWords (uint16* data, uint32 size);
sint32 SoundDecoder_Init (int flags, TFB_DecoderFormats* formats); sint32 SoundDecoder_Init (int flags, TFB_DecoderFormats* formats);
void SoundDecoder_Uninit (void); void SoundDecoder_Uninit (void);
TFB_SoundDecoder* SoundDecoder_Load (char *filename, uint32 buffer_size, TFB_SoundDecoder* SoundDecoder_Load (char *filename, uint32 buffer_size,
+96 -130
View File
@@ -1,132 +1,107 @@
/** /*
* OpenAL cross platform audio library * This program is free software; you can redistribute it and/or modify
* Copyright (C) 1999-2000 by authors. * it under the terms of the GNU General Public License as published by
* This library is free software; you can redistribute it and/or * the Free Software Foundation; either version 2 of the License, or
* modify it under the terms of the GNU Library General Public * (at your option) any later version.
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Library General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU Library General Public * You should have received a copy of the GNU General Public License
* License along with this library; if not, write to the * along with this program; if not, write to the Free Software
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/ */
/* NOTE by Mika: Wav loader, (c) Creative, taken from their OpenAL /* Loader for .wav files
* implementation and modified. * Code is based on Creative's Win32 OpenAL implementation.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <memory.h> #include <memory.h>
#include "libs/misc.h" #include "libs/misc.h"
#include "wav.h" #include "wav.h"
#include "decoder.h" #include "decoder.h"
#include "endian.h"
#if defined _MSC_VER #define FMT 0x20746D66 /* "fmt " */
#pragma pack (push,1) /* Turn off alignment */ #define DATA 0x61746164 /* "data" */
#elif defined __GNUC__
#define PADOFF_VAR __attribute__((packed))
#endif
#ifndef PADOFF_VAR typedef struct
#define PADOFF_VAR
#endif
typedef struct /* WAV File-header */
{ {
uint8 Id[4] PADOFF_VAR; uint32 Id;
sint32 Size PADOFF_VAR; sint32 Size;
uint8 Type[4] PADOFF_VAR; uint32 Type;
} WAVFileHdr_Struct; } WAVFileHdr_Struct;
typedef struct /* WAV Fmt-header */ typedef struct
{ {
uint16 Format PADOFF_VAR; uint16 Format;
uint16 Channels PADOFF_VAR; uint16 Channels;
uint32 SamplesPerSec PADOFF_VAR; uint32 SamplesPerSec;
uint32 BytesPerSec PADOFF_VAR; uint32 BytesPerSec;
uint16 BlockAlign PADOFF_VAR; uint16 BlockAlign;
uint16 BitsPerSample PADOFF_VAR; uint16 BitsPerSample;
} WAVFmtHdr_Struct; } WAVFmtHdr_Struct;
typedef struct /* WAV FmtEx-header */ typedef struct
{ {
uint16 Size PADOFF_VAR; uint32 Id;
uint16 SamplesPerBlock PADOFF_VAR; uint32 Size;
} WAVFmtExHdr_Struct;
typedef struct /* WAV Smpl-header */
{
uint32 Manufacturer PADOFF_VAR;
uint32 Product PADOFF_VAR;
uint32 SamplePeriod PADOFF_VAR;
uint32 Note PADOFF_VAR;
uint32 FineTune PADOFF_VAR;
uint32 SMPTEFormat PADOFF_VAR;
uint32 SMPTEOffest PADOFF_VAR;
uint32 Loops PADOFF_VAR;
uint32 SamplerData PADOFF_VAR;
struct
{
uint32 Identifier PADOFF_VAR;
uint32 Type PADOFF_VAR;
uint32 Start PADOFF_VAR;
uint32 End PADOFF_VAR;
uint32 Fraction PADOFF_VAR;
uint32 Count PADOFF_VAR;
} Loop[1] PADOFF_VAR;
} WAVSmplHdr_Struct;
typedef struct /* WAV Chunk-header */
{
uint8 Id[4] PADOFF_VAR;
uint32 Size PADOFF_VAR;
} WAVChunkHdr_Struct; } WAVChunkHdr_Struct;
#ifdef PADOFF_VAR /* Default alignment */ void
#undef PADOFF_VAR LoadWAVFile (const char *file, uint32 *format, void **data, uint32 *size,
#endif uint32 *freq, bool want_big_endian)
#if defined _MSC_VER
#pragma pack (pop)
#endif
/* loads the WAV file in little endian byte order */
void LoadWAVFile (char *file, uint32 *format, void **data, uint32 *size, uint32 *freq, bool *loop)
{ {
WAVChunkHdr_Struct ChunkHdr; WAVChunkHdr_Struct ChunkHdr;
WAVFmtExHdr_Struct FmtExHdr;
WAVFileHdr_Struct FileHdr; WAVFileHdr_Struct FileHdr;
WAVSmplHdr_Struct SmplHdr;
WAVFmtHdr_Struct FmtHdr; WAVFmtHdr_Struct FmtHdr;
FILE *Stream; FILE *fp;
*format=decoder_formats.mono16; *format = decoder_formats.mono16;
*data=NULL; *data = NULL;
*size=0; *size = 0;
*freq=22050; *freq = 22050;
*loop=false;
if (file) fp = fopen (file, "rb");
if (fp)
{ {
Stream=fopen(file,"rb"); fread(&FileHdr.Id, 4, 1, fp);
if (Stream) FileHdr.Id = UQM_SwapLE32 (FileHdr.Id);
fread(&FileHdr.Size, 4, 1, fp);
FileHdr.Size = UQM_SwapLE32 (FileHdr.Size);
fread(&FileHdr.Type, 4, 1, fp);
FileHdr.Type = UQM_SwapLE32 (FileHdr.Type);
FileHdr.Size = ((FileHdr.Size + 1) & ~1) - 4;
while (FileHdr.Size != 0)
{ {
fread(&FileHdr,1,sizeof(WAVFileHdr_Struct),Stream); if (!fread (&ChunkHdr.Id, 4, 1, fp))
FileHdr.Size=((FileHdr.Size+1)&~1)-4; break;
while ((FileHdr.Size!=0)&&(fread(&ChunkHdr,1,sizeof(WAVChunkHdr_Struct),Stream))) ChunkHdr.Id = UQM_SwapLE32 (ChunkHdr.Id);
if (!fread (&ChunkHdr.Size, 4, 1, fp))
break;
ChunkHdr.Size = UQM_SwapLE32 (ChunkHdr.Size);
if (ChunkHdr.Id == FMT)
{ {
if (!memcmp(ChunkHdr.Id,"fmt ",4)) fread (&FmtHdr.Format, 2, 1, fp);
{ FmtHdr.Format = UQM_SwapLE16 (FmtHdr.Format);
fread(&FmtHdr,1,sizeof(WAVFmtHdr_Struct),Stream); fread (&FmtHdr.Channels, 2, 1, fp);
if (FmtHdr.Format==0x0001) FmtHdr.Channels = UQM_SwapLE16 (FmtHdr.Channels);
fread (&FmtHdr.SamplesPerSec, 4, 1, fp);
FmtHdr.SamplesPerSec = UQM_SwapLE32 (FmtHdr.SamplesPerSec);
fread (&FmtHdr.BytesPerSec, 4, 1, fp);
FmtHdr.BytesPerSec = UQM_SwapLE32 (FmtHdr.BytesPerSec);
fread (&FmtHdr.BlockAlign, 2, 1, fp);
FmtHdr.BlockAlign = UQM_SwapLE16 (FmtHdr.BlockAlign);
fread (&FmtHdr.BitsPerSample, 2, 1, fp);
FmtHdr.BitsPerSample = UQM_SwapLE16 (FmtHdr.BitsPerSample);
if (FmtHdr.Format == 0x0001)
{ {
*format=(FmtHdr.Channels == 1 ? *format=(FmtHdr.Channels == 1 ?
(FmtHdr.BitsPerSample == 8 ? (FmtHdr.BitsPerSample == 8 ?
@@ -136,49 +111,40 @@ void LoadWAVFile (char *file, uint32 *format, void **data, uint32 *size, uint32
decoder_formats.stereo8 decoder_formats.stereo8
: decoder_formats.stereo16) : decoder_formats.stereo16)
); );
*freq=FmtHdr.SamplesPerSec; *freq = FmtHdr.SamplesPerSec;
fseek(Stream,ChunkHdr.Size-sizeof(WAVFmtHdr_Struct),SEEK_CUR); fseek (fp, ChunkHdr.Size - 16, SEEK_CUR);
} }
else else
{ {
fread(&FmtExHdr,1,sizeof(WAVFmtExHdr_Struct),Stream); fprintf (stderr, "LoadWAVFile(): unsupported format %x\n", FmtHdr.Format);
fseek(Stream,ChunkHdr.Size-sizeof(WAVFmtHdr_Struct)- fclose (fp);
sizeof(WAVFmtExHdr_Struct),SEEK_CUR); return;
} }
} }
else if (!memcmp(ChunkHdr.Id,"data",4)) else if (ChunkHdr.Id == DATA)
{ {
if (FmtHdr.Format==0x0001) *size = ChunkHdr.Size;
{ if ((*data = HMalloc (ChunkHdr.Size + 31)))
*size=ChunkHdr.Size; fread (*data, FmtHdr.BlockAlign, ChunkHdr.Size / FmtHdr.BlockAlign, fp);
*data=HMalloc(ChunkHdr.Size+31); memset(((char *)*data) + ChunkHdr.Size, 0, 31);
if (*data)
fread(*data,FmtHdr.BlockAlign,
ChunkHdr.Size/FmtHdr.BlockAlign,Stream);
memset(((char *)*data)+ChunkHdr.Size,0,31);
}
else if (FmtHdr.Format==0x0011)
{
//IMA ADPCM
}
else if (FmtHdr.Format==0x0055)
{
//MP3 WAVE
}
}
else if (!memcmp(ChunkHdr.Id,"smpl",4))
{
fread(&SmplHdr,1,sizeof(WAVSmplHdr_Struct),Stream);
*loop = (SmplHdr.Loops ? true : false);
fseek(Stream,ChunkHdr.Size-sizeof(WAVSmplHdr_Struct),SEEK_CUR);
} }
else else
fseek(Stream,ChunkHdr.Size,SEEK_CUR); {
fseek(fp, ChunkHdr.Size, SEEK_CUR);
}
fseek(Stream,ChunkHdr.Size&1,SEEK_CUR); fseek (fp, ChunkHdr.Size & 1, SEEK_CUR);
FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8); FileHdr.Size -= (((ChunkHdr.Size + 1) & ~1) + 8);
} }
fclose(Stream); fclose(fp);
} }
if (want_big_endian &&
(*format == decoder_formats.stereo16 || *format == decoder_formats.mono16))
{
SoundDecoder_SwapWords (*data, *size);
} }
if (*size == 0)
fprintf (stderr, "LoadWAVFile(): loading %s failed!\n", file);
} }
+14 -20
View File
@@ -1,33 +1,27 @@
/** /*
* OpenAL cross platform audio library * This program is free software; you can redistribute it and/or modify
* Copyright (C) 1999-2000 by authors. * it under the terms of the GNU General Public License as published by
* This library is free software; you can redistribute it and/or * the Free Software Foundation; either version 2 of the License, or
* modify it under the terms of the GNU Library General Public * (at your option) any later version.
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Library General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU Library General Public * You should have received a copy of the GNU General Public License
* License along with this library; if not, write to the * along with this program; if not, write to the Free Software
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/ */
/* NOTE by Mika: Wav loader, (c) Creative, taken from their OpenAL /* Loader for .wav files */
* implementation and modified.
*/
#ifndef WAV_H #ifndef WAV_H
#define WAV_H #define WAV_H
#include "types.h" #include "types.h"
/* loads the WAV file in little endian byte order */ void LoadWAVFile (const char *file, uint32 *format, void **data, uint32 *size,
void LoadWAVFile (char *file, uint32 *format, void **data, uint32 *size, uint32 *freq, bool *loop); uint32 *freq, bool want_big_endian);
#endif #endif