Drop SDL Wave loading dependency. Implement own Wave file loading

This commit is contained in:
2014-07-02 21:07:43 +02:00
committed by Valeriano A.R
parent a47a9d6d54
commit ef228d14d9

View File

@@ -18,30 +18,35 @@ static void Audio_MixerCallback(void *ud,Uint8 *stream,int l);
// AudioWave //
///////////////
// Reference to a sound.
typedef struct Tag_AudioWave {
SDL_AudioSpec spec;
typedef struct TAudioWave TAudioWave, *AudioWave;
struct TAudioWave {
unsigned int sampleRate;
int channels;
int bpb;
int BPB;
Uint32 len;
Uint8 *buffer;
struct Tag_AudioWave *next;
} AudioWave;
AudioWave *_waves=NULL;
AudioWave next;
};
AudioWave _waves=NULL;
////////////////////////////////////////////////
// AudioChan //
///////////////
// Reference to a sound.
typedef struct Tag_AudioChan {
AudioWave *wave;
typedef struct TAudioChan TAudioChan, *AudioChan;
struct TAudioChan {
AudioWave wave;
Uint32 pos;
unsigned char rightvol;
unsigned char leftvol;
struct Tag_AudioChan *next;
} AudioChan;
AudioChan *_channels=NULL;
AudioChan *_free_channels=NULL;
AudioChan next;
};
AudioChan _channels=NULL;
AudioChan _free_channels=NULL;
/////////////////////////////
// Audio_Init
@@ -58,7 +63,7 @@ int Audio_Init(){
#endif
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0){
printf("Audio_Init: Failure initializing SDL Audio.\n");
printf("Audio_Init: SDL Error: %s\n",SDL_GetError());
printf("\tSDL Error: %s\n",SDL_GetError());
return(0);
}
@@ -66,15 +71,11 @@ int Audio_Init(){
as.freq = 44100;
as.format = AUDIO_S16SYS;
as.channels = 2;
#ifdef EMSCRIPTEN
as.samples = 4096;
#else
as.samples = 1024;
#endif
as.samples = 2048;
as.callback = Audio_MixerCallback;
if(SDL_OpenAudio(&as, &as2) < 0){
printf("Audio_Init: Failure opening audio.\n");
printf("Audio_Init: SDL Error: %s\n",SDL_GetError());
printf("\tSDL Error: %s\n",SDL_GetError());
return(0);
}
@@ -101,16 +102,16 @@ int Audio_Init(){
// Mixes the audio channels.
static void Audio_MixerCallback(void *ud,Uint8 *stream,int l){
signed short *ptr_out,*ptr_wave;
AudioChan *prevchan;
AudioChan *chan;
AudioWave *wave;
AudioChan prevchan;
AudioChan chan;
AudioWave wave;
int len=l/4; // Asume 16bpb and 2 output chan
int chan_remain;
int len_mix;
int i;
// Clean
memset(stream,0,len);
memset(stream,0,l);
// Mix all the channels
prevchan=NULL;
@@ -118,7 +119,7 @@ static void Audio_MixerCallback(void *ud,Uint8 *stream,int l){
while(chan){
if(!chan->wave){
// Remove finished channels
AudioChan *aux_chan=chan->next;
AudioChan aux_chan=chan->next;
chan->next=_free_channels;
_free_channels=chan;
chan=aux_chan;
@@ -197,38 +198,105 @@ void Audio_Frame(){
//
// Loads a sound, giving a reference.
AudioSnd Audio_LoadSound(char *filename){
AudioWave *wave;
int error = 0;
FILE *f;
char id[5] = { 0, 0, 0, 0, 0 }, *sndBuffer = NULL;
short formatTag, channels, bitsPerSample;
int formatLen, sampleRate, dataSize;
// Allocate and load the sound
wave=malloc(sizeof(AudioWave));
if( SDL_LoadWAV(filename,
&wave->spec, &wave->buffer, &wave->len) == NULL )
{
printf("Audio_LoadSound: Failure Loading sound: %s\n",filename);
printf("Audio_LoadSound: SDL Error: %s\n",SDL_GetError());
free(wave);
f = fopen(filename, "rb");
if (!f) {
printf("Audio_LoadSound: Failure opening file.\n");
return(NULL);
}
// Asert results
if( wave->spec.format != AUDIO_S16 ||
wave->spec.freq != 44100 ||
wave->spec.channels != 1 )
{
printf("Audio_LoadSound: Failure opening sound. (44.1Khz/16b/1c).\n");
SDL_FreeWAV(wave->buffer);
free(wave);
return(0);
// Read id "RIFF"
fread(id, 4, sizeof(char), f);
if (strcmp(id, "RIFF")) {
printf("Audio_LoadSound: File is not RIFF.\n");
fclose(f);
return(NULL);
}
// Correct the lenght
wave->len/=2;
// File size (-"RIFF")
fseek(f, 4, SEEK_CUR); // size
// Read id "WAVE"
fread(id, 4, sizeof(char), f);
if (strcmp(id, "WAVE")) {
printf("Audio_LoadSound: File is not WAVE.\n");
fclose(f);
return(NULL);
}
// Read the format
fread(id, 1, sizeof(char) * 4, f); // Read "fmt "
fread(&formatLen, 1, sizeof(int), f);
if (formatLen < 14) {
printf("Audio_LoadSound: File too short.\n");
fclose(f);
return (NULL );
}
fread(&formatTag, 1, sizeof(short), f); // 1=PCM
if (formatTag != 1) {
printf("Audio_LoadSound: Not PCM format.\n");
fclose(f);
return (NULL );
}
fread(&channels, 1, sizeof(short), f);
fread(&sampleRate, 1, sizeof(int), f);
fseek(f, 2, SEEK_CUR); // avgBytesSec
fseek(f, 2, SEEK_CUR); // blockAlign
fread(&bitsPerSample, 1, sizeof(short), f);
fseek(f, formatLen - 14, SEEK_CUR); // Align read
// Assert sound format
if (sampleRate!=44100 || channels!=1 || bitsPerSample!=2) {
printf("Audio_LoadSound: Format not supported: "
"sampleRate:%d; channels:%d; BPB:%d\n",
sampleRate, channels, bitsPerSample);
fclose(f);
return(NULL);
}
// Skip no "data" blocks
do{
int lenRead=fread(id, 1, sizeof(char) * 4, f);
if(lenRead<4){ break; }
if (strcmp(id, "data")) {
fread(&dataSize, 1, sizeof(int), f);
fseek(f, dataSize, SEEK_CUR);
}else{
break;
}
}while(1);
if (strcmp(id, "data")) {
printf("Audio_LoadSound: DATA block not found\n");
fclose(f);
return (NULL );
}
// Read the "data" block
fread(&dataSize, 1, sizeof(int), f);
sndBuffer = malloc(sizeof(char)*dataSize);
fread(sndBuffer, dataSize, sizeof(char), f);
fclose(f);
// Build the wave object
AudioWave wave = malloc(sizeof(TAudioWave));
wave->sampleRate = sampleRate;
wave->channels = channels;
wave->buffer = (Uint8 *) sndBuffer;
wave->BPB = bitsPerSample;
wave->bpb = wave->bpb * 8;
wave->len = dataSize / (wave->BPB * wave->channels);
// Take a reference
wave->next=_waves;
_waves=wave;
return((AudioSnd)wave);
return (wave);
}
@@ -239,8 +307,8 @@ AudioSnd Audio_LoadSound(char *filename){
void Audio_PlaySound(AudioSnd snd,
float leftvol, float rightvol)
{
AudioChan *chan;
AudioWave *wave;
AudioChan chan;
AudioWave wave;
if(!snd)
return;
@@ -253,7 +321,7 @@ void Audio_PlaySound(AudioSnd snd,
_free_channels=chan->next;
chan->next=NULL;
}else{
chan=malloc(sizeof(AudioChan));
chan=malloc(sizeof(TAudioChan));
chan->next=NULL;
}