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:
- Wav loader is now endian safe (bug #165) -Mika
- Dialogue patch for Melnorme, fixing bug #335
- Two dialogue spots where visit count could run away patched; fixes bug
#333, from Stas Sergeev
+4
View File
@@ -3304,6 +3304,10 @@ SOURCE=..\types.h
# End Source File
# Begin Source File
SOURCE=..\endian.h
# End Source File
# Begin Source File
SOURCE=..\starcon2.c
# End Source File
# End Group
+1 -14
View File
@@ -505,24 +505,11 @@ uint32 SoundDecoder_DecodeAll (TFB_SoundDecoder *decoder)
{
case SOUNDDECODER_WAV:
{
bool loop;
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)
{
/* 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->data = decoder->buffer;
decoder->pos = 0;
@@ -79,7 +79,7 @@ enum
};
extern TFB_DecoderFormats decoder_formats;
void SoundDecoder_SwapWords (uint16* data, uint32 size);
sint32 SoundDecoder_Init (int flags, TFB_DecoderFormats* formats);
void SoundDecoder_Uninit (void);
TFB_SoundDecoder* SoundDecoder_Load (char *filename, uint32 buffer_size,
+116 -150
View File
@@ -1,184 +1,150 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2000 by authors.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
/*
* 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 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
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* NOTE by Mika: Wav loader, (c) Creative, taken from their OpenAL
* implementation and modified.
/* Loader for .wav files
* Code is based on Creative's Win32 OpenAL implementation.
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "libs/misc.h"
#include "wav.h"
#include "decoder.h"
#include "endian.h"
#if defined _MSC_VER
#pragma pack (push,1) /* Turn off alignment */
#elif defined __GNUC__
#define PADOFF_VAR __attribute__((packed))
#endif
#define FMT 0x20746D66 /* "fmt " */
#define DATA 0x61746164 /* "data" */
#ifndef PADOFF_VAR
#define PADOFF_VAR
#endif
typedef struct /* WAV File-header */
typedef struct
{
uint8 Id[4] PADOFF_VAR;
sint32 Size PADOFF_VAR;
uint8 Type[4] PADOFF_VAR;
uint32 Id;
sint32 Size;
uint32 Type;
} WAVFileHdr_Struct;
typedef struct /* WAV Fmt-header */
typedef struct
{
uint16 Format PADOFF_VAR;
uint16 Channels PADOFF_VAR;
uint32 SamplesPerSec PADOFF_VAR;
uint32 BytesPerSec PADOFF_VAR;
uint16 BlockAlign PADOFF_VAR;
uint16 BitsPerSample PADOFF_VAR;
uint16 Format;
uint16 Channels;
uint32 SamplesPerSec;
uint32 BytesPerSec;
uint16 BlockAlign;
uint16 BitsPerSample;
} WAVFmtHdr_Struct;
typedef struct /* WAV FmtEx-header */
typedef struct
{
uint16 Size PADOFF_VAR;
uint16 SamplesPerBlock PADOFF_VAR;
} 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;
uint32 Id;
uint32 Size;
} WAVChunkHdr_Struct;
#ifdef PADOFF_VAR /* Default alignment */
#undef PADOFF_VAR
#endif
#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)
void
LoadWAVFile (const char *file, uint32 *format, void **data, uint32 *size,
uint32 *freq, bool want_big_endian)
{
WAVChunkHdr_Struct ChunkHdr;
WAVFmtExHdr_Struct FmtExHdr;
WAVFileHdr_Struct FileHdr;
WAVSmplHdr_Struct SmplHdr;
WAVFmtHdr_Struct FmtHdr;
FILE *Stream;
FILE *fp;
*format=decoder_formats.mono16;
*data=NULL;
*size=0;
*freq=22050;
*loop=false;
if (file)
*format = decoder_formats.mono16;
*data = NULL;
*size = 0;
*freq = 22050;
fp = fopen (file, "rb");
if (fp)
{
Stream=fopen(file,"rb");
if (Stream)
{
fread(&FileHdr,1,sizeof(WAVFileHdr_Struct),Stream);
FileHdr.Size=((FileHdr.Size+1)&~1)-4;
while ((FileHdr.Size!=0)&&(fread(&ChunkHdr,1,sizeof(WAVChunkHdr_Struct),Stream)))
{
if (!memcmp(ChunkHdr.Id,"fmt ",4))
{
fread(&FmtHdr,1,sizeof(WAVFmtHdr_Struct),Stream);
if (FmtHdr.Format==0x0001)
{
*format=(FmtHdr.Channels == 1 ?
(FmtHdr.BitsPerSample == 8 ?
decoder_formats.mono8
: decoder_formats.mono16)
: (FmtHdr.BitsPerSample == 8 ?
decoder_formats.stereo8
: decoder_formats.stereo16)
);
*freq=FmtHdr.SamplesPerSec;
fseek(Stream,ChunkHdr.Size-sizeof(WAVFmtHdr_Struct),SEEK_CUR);
}
else
{
fread(&FmtExHdr,1,sizeof(WAVFmtExHdr_Struct),Stream);
fseek(Stream,ChunkHdr.Size-sizeof(WAVFmtHdr_Struct)-
sizeof(WAVFmtExHdr_Struct),SEEK_CUR);
}
}
else if (!memcmp(ChunkHdr.Id,"data",4))
{
if (FmtHdr.Format==0x0001)
{
*size=ChunkHdr.Size;
*data=HMalloc(ChunkHdr.Size+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
fseek(Stream,ChunkHdr.Size,SEEK_CUR);
fread(&FileHdr.Id, 4, 1, fp);
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);
fseek(Stream,ChunkHdr.Size&1,SEEK_CUR);
FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8);
FileHdr.Size = ((FileHdr.Size + 1) & ~1) - 4;
while (FileHdr.Size != 0)
{
if (!fread (&ChunkHdr.Id, 4, 1, fp))
break;
ChunkHdr.Id = UQM_SwapLE32 (ChunkHdr.Id);
if (!fread (&ChunkHdr.Size, 4, 1, fp))
break;
ChunkHdr.Size = UQM_SwapLE32 (ChunkHdr.Size);
if (ChunkHdr.Id == FMT)
{
fread (&FmtHdr.Format, 2, 1, fp);
FmtHdr.Format = UQM_SwapLE16 (FmtHdr.Format);
fread (&FmtHdr.Channels, 2, 1, fp);
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 ?
(FmtHdr.BitsPerSample == 8 ?
decoder_formats.mono8
: decoder_formats.mono16)
: (FmtHdr.BitsPerSample == 8 ?
decoder_formats.stereo8
: decoder_formats.stereo16)
);
*freq = FmtHdr.SamplesPerSec;
fseek (fp, ChunkHdr.Size - 16, SEEK_CUR);
}
else
{
fprintf (stderr, "LoadWAVFile(): unsupported format %x\n", FmtHdr.Format);
fclose (fp);
return;
}
}
fclose(Stream);
}
else if (ChunkHdr.Id == DATA)
{
*size = ChunkHdr.Size;
if ((*data = HMalloc (ChunkHdr.Size + 31)))
fread (*data, FmtHdr.BlockAlign, ChunkHdr.Size / FmtHdr.BlockAlign, fp);
memset(((char *)*data) + ChunkHdr.Size, 0, 31);
}
else
{
fseek(fp, ChunkHdr.Size, SEEK_CUR);
}
fseek (fp, ChunkHdr.Size & 1, SEEK_CUR);
FileHdr.Size -= (((ChunkHdr.Size + 1) & ~1) + 8);
}
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
* Copyright (C) 1999-2000 by authors.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
/*
* 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 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
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
* 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 Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* NOTE by Mika: Wav loader, (c) Creative, taken from their OpenAL
* implementation and modified.
*/
/* Loader for .wav files */
#ifndef WAV_H
#define WAV_H
#include "types.h"
/* loads the WAV file in little endian byte order */
void LoadWAVFile (char *file, uint32 *format, void **data, uint32 *size, uint32 *freq, bool *loop);
void LoadWAVFile (const char *file, uint32 *format, void **data, uint32 *size,
uint32 *freq, bool want_big_endian);
#endif