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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,132 +1,107 @@
|
||||
/**
|
||||
* 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.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);
|
||||
|
||||
FileHdr.Size = ((FileHdr.Size + 1) & ~1) - 4;
|
||||
while (FileHdr.Size != 0)
|
||||
{
|
||||
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 (!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)
|
||||
{
|
||||
if (!memcmp(ChunkHdr.Id,"fmt ",4))
|
||||
{
|
||||
fread(&FmtHdr,1,sizeof(WAVFmtHdr_Struct),Stream);
|
||||
if (FmtHdr.Format==0x0001)
|
||||
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 ?
|
||||
@@ -136,49 +111,40 @@ void LoadWAVFile (char *file, uint32 *format, void **data, uint32 *size, uint32
|
||||
decoder_formats.stereo8
|
||||
: decoder_formats.stereo16)
|
||||
);
|
||||
*freq=FmtHdr.SamplesPerSec;
|
||||
fseek(Stream,ChunkHdr.Size-sizeof(WAVFmtHdr_Struct),SEEK_CUR);
|
||||
*freq = FmtHdr.SamplesPerSec;
|
||||
fseek (fp, ChunkHdr.Size - 16, SEEK_CUR);
|
||||
}
|
||||
else
|
||||
{
|
||||
fread(&FmtExHdr,1,sizeof(WAVFmtExHdr_Struct),Stream);
|
||||
fseek(Stream,ChunkHdr.Size-sizeof(WAVFmtHdr_Struct)-
|
||||
sizeof(WAVFmtExHdr_Struct),SEEK_CUR);
|
||||
fprintf (stderr, "LoadWAVFile(): unsupported format %x\n", FmtHdr.Format);
|
||||
fclose (fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!memcmp(ChunkHdr.Id,"data",4))
|
||||
else if (ChunkHdr.Id == DATA)
|
||||
{
|
||||
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);
|
||||
*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(Stream,ChunkHdr.Size,SEEK_CUR);
|
||||
{
|
||||
fseek(fp, ChunkHdr.Size, SEEK_CUR);
|
||||
}
|
||||
|
||||
fseek(Stream,ChunkHdr.Size&1,SEEK_CUR);
|
||||
FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8);
|
||||
fseek (fp, ChunkHdr.Size & 1, SEEK_CUR);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user