Skip to content

Commit

Permalink
Torbj?rn Andersson fixed AIFF music playing support
Browse files Browse the repository at this point in the history
I removed malloc.h from timidity so it would build on MacOS X
  • Loading branch information
slouken committed Aug 19, 2001
1 parent 1718ea0 commit e53f8d6
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 60 deletions.
2 changes: 2 additions & 0 deletions CHANGES
@@ -1,5 +1,7 @@

1.2.1:
Torbj�rn Andersson - Sun, 19 Aug 2001 16:03:30
* Fixed AIFF music playing support
Sam Lantinga - Sat Aug 18 04:14:13 PDT 2001
* Fixed building Ogg Vorbis support on Windows
Ryan C. Gordon - Thu, 7 Jun 2001 13:15:51
Expand Down
5 changes: 0 additions & 5 deletions timidity/instrum.c
Expand Up @@ -25,12 +25,7 @@

#include <stdio.h>
#include <string.h>

#if defined(__FreeBSD__) || defined (__WIN32__)
#include <stdlib.h>
#else
#include <malloc.h>
#endif

#include "config.h"
#include "common.h"
Expand Down
2 changes: 1 addition & 1 deletion timidity/mix.c
Expand Up @@ -23,7 +23,7 @@

#include <math.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#include "config.h"
#include "common.h"
Expand Down
2 changes: 1 addition & 1 deletion timidity/resample.c
Expand Up @@ -22,7 +22,7 @@

#include <math.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#include "config.h"
#include "common.h"
Expand Down
136 changes: 83 additions & 53 deletions wavestream.c
Expand Up @@ -337,49 +337,58 @@ static FILE *LoadWAVStream (const char *file, SDL_AudioSpec *spec,
return(wavefp);
}

static double SANE_to_double(Uint32 l1, Uint32 l2, Uint16 s1)
/* I couldn't get SANE_to_double() to work, so I stole this from libsndfile.
* I don't pretend to fully understand it.
*/

static Uint32 SANE_to_Uint32 (Uint8 *sanebuf)
{
double d;
struct almost_double {
Uint32 hi, lo;
} *dp = (struct almost_double *)&d;

dp->hi = ((l1 << 4) & 0x3ff00000) | (l1 & 0xc0000000);
dp->hi |= (l1 << 5) & 0xffff0;
dp->hi |= (l2 >> 27) & 0x1f;
dp->lo = (l2 << 5) & 0xffffffe0;
dp->lo |= ((s1 >> 11) & 0x1f);
return(d);
/* Negative number? */
if (sanebuf[0] & 0x80)
return 0;

/* Less than 1? */
if (sanebuf[0] <= 0x3F)
return 1;

/* Way too big? */
if (sanebuf[0] > 0x40)
return 0x4000000;

/* Still too big? */
if (sanebuf[0] == 0x40 && sanebuf[1] > 0x1C)
return 800000000;

return ((sanebuf[2] << 23) | (sanebuf[3] << 15) | (sanebuf[4] << 7)
| (sanebuf[5] >> 1)) >> (29 - sanebuf[1]);
}

static FILE *LoadAIFFStream (const char *file, SDL_AudioSpec *spec,
long *start, long *stop)
{
int was_error;
int found_SSND;
int found_COMM;
FILE *wavefp;
SDL_RWops *src;

Uint32 chunk_type;
Uint32 chunk_length;
long next_chunk;

/* AIFF magic header */
Uint32 FORMchunk;
Uint32 chunklen;
Uint32 AIFFmagic;
/* SSND chunk */
Uint32 SSNDchunk;
Uint32 ssndlen;
Uint32 offset;
Uint32 blocksize;
/* COMM format chunk */
Uint32 COMMchunk;
Uint32 commlen;
Uint16 channels;
Uint32 numsamples;
Uint16 samplesize;
struct { /* plus a SANE format double precision number */
Uint32 l1;
Uint32 l2;
Uint16 s1;
} sane_freq;

Uint8 sane_freq[10];
Uint32 frequency;


Expand All @@ -397,47 +406,68 @@ static FILE *LoadAIFFStream (const char *file, SDL_AudioSpec *spec,

/* Check the magic header */
FORMchunk = SDL_ReadLE32(src);
chunklen = SDL_ReadLE32(src);
chunk_length = SDL_ReadBE32(src);
AIFFmagic = SDL_ReadLE32(src);
if ( (FORMchunk != FORM) || (AIFFmagic != AIFF) ) {
SDL_SetError("Unrecognized file type (not AIFF)");
was_error = 1;
goto done;
}

/* Read the SSND data chunk */
SSNDchunk = SDL_ReadLE32(src);
if ( SSNDchunk != SSND ) {
SDL_SetError("Unrecognized AIFF chunk (not SSND)");
was_error = 1;
goto done;
}
ssndlen = SDL_ReadLE32(src);
offset = SDL_ReadLE32(src);
blocksize = SDL_ReadLE32(src);
/* From what I understand of the specification, chunks may appear in
* any order, and we should just ignore unknown ones.
*/

/* Fill in start and stop pointers, then seek to format chunk */
ssndlen -= (2*sizeof(Uint32));
*start = SDL_RWtell(src) + offset;
*stop = SDL_RWtell(src) + ssndlen;
SDL_RWseek(src, *stop, SEEK_SET);
found_SSND = 0;
found_COMM = 0;

/* Read the audio data format chunk */
COMMchunk = SDL_ReadLE32(src);
if ( COMMchunk != COMM ) {
SDL_SetError("Unrecognized AIFF chunk (not COMM)");
was_error = 1;
goto done;
do {
chunk_type = SDL_ReadLE32(src);
chunk_length = SDL_ReadBE32(src);
next_chunk = SDL_RWtell(src) + chunk_length;

/* Paranoia to avoid infinite loops */
if (chunk_length == 0)
break;

switch (chunk_type) {
case SSND:
found_SSND = 1;
offset = SDL_ReadBE32(src);
blocksize = SDL_ReadBE32(src);
*start = SDL_RWtell(src) + offset;
break;

case COMM:
found_COMM = 1;

/* Read the audio data format chunk */
channels = SDL_ReadBE16(src);
numsamples = SDL_ReadBE32(src);
samplesize = SDL_ReadBE16(src);
SDL_RWread(src, sane_freq, sizeof(sane_freq), 1);
frequency = SANE_to_Uint32(sane_freq);
break;

default:
break;
}
} while ((!found_SSND || !found_COMM)
&& SDL_RWseek(src, next_chunk, SEEK_SET) != -1);

if (!found_SSND) {
SDL_SetError("Bad AIFF file (no SSND chunk)");
was_error = 1;
goto done;
}

if (!found_COMM) {
SDL_SetError("Bad AIFF file (no COMM chunk)");
was_error = 1;
goto done;
}
commlen = SDL_ReadLE32(src);
channels = SDL_ReadLE16(src);
numsamples = SDL_ReadLE32(src);
samplesize = SDL_ReadLE16(src);
sane_freq.l1 = SDL_ReadLE32(src);
sane_freq.l2 = SDL_ReadLE32(src);
sane_freq.s1 = SDL_ReadLE16(src);
frequency = (Uint32)SANE_to_double(sane_freq.l1, sane_freq.l2,
sane_freq.s1);

*stop = *start + channels * numsamples * (samplesize / 8) - 1;

/* Decode the audio data format */
memset(spec, 0, (sizeof *spec));
Expand All @@ -447,7 +477,7 @@ static FILE *LoadAIFFStream (const char *file, SDL_AudioSpec *spec,
spec->format = AUDIO_U8;
break;
case 16:
spec->format = AUDIO_S16;
spec->format = AUDIO_S16MSB;
break;
default:
SDL_SetError("Unknown samplesize in data format");
Expand Down

0 comments on commit e53f8d6

Please sign in to comment.