Torbj�rn Andersson - Tue Sep 11 11:22:29 PDT 2001
authorSam Lantinga <slouken@libsdl.org>
Tue, 11 Sep 2001 18:24:38 +0000
changeset 1113b709e102787
parent 110 1885d27bab6c
child 112 7f8dd3c0cbdc
Torbj�rn Andersson - Tue Sep 11 11:22:29 PDT 2001
* Added support for loading AIFF audio chunks
CHANGES
Makefile.am
load_aiff.c
load_aiff.h
load_voc.c
load_voc.h
mixer.c
voc.c
wave.h
wavestream.c
     1.1 --- a/CHANGES	Fri Sep 07 01:06:20 2001 +0000
     1.2 +++ b/CHANGES	Tue Sep 11 18:24:38 2001 +0000
     1.3 @@ -1,5 +1,7 @@
     1.4  
     1.5  1.2.1:
     1.6 +Torbjrn Andersson - Tue Sep 11 11:22:29 PDT 2001
     1.7 + * Added support for loading AIFF audio chunks
     1.8  Max Horn - Tue Sep  4 20:38:11 PDT 2001
     1.9   * Added native MIDI music support on MacOS and MacOS X
    1.10  Florian Schulze - Sun Aug 19 14:55:37 PDT 2001
     2.1 --- a/Makefile.am	Fri Sep 07 01:06:20 2001 +0000
     2.2 +++ b/Makefile.am	Tue Sep 11 18:24:38 2001 +0000
     2.3 @@ -10,16 +10,18 @@
     2.4  	SDL_mixer.h
     2.5  
     2.6  libSDL_mixer_la_SOURCES =	\
     2.7 +	load_aiff.c		\
     2.8 +	load_aiff.h		\
     2.9 +	load_voc.c		\
    2.10 +	load_voc.h		\
    2.11  	mixer.c			\
    2.12  	music.c			\
    2.13  	music_cmd.c		\
    2.14  	music_cmd.h		\
    2.15  	music_ogg.c		\
    2.16  	music_ogg.h		\
    2.17 -	wave.h			\
    2.18  	wavestream.c		\
    2.19 -	wavestream.h		\
    2.20 -	voc.c
    2.21 +	wavestream.h
    2.22  
    2.23  if USE_MIKMOD
    2.24  MIKMOD_LIB = mikmod/libmikmod.la
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/load_aiff.c	Tue Sep 11 18:24:38 2001 +0000
     3.3 @@ -0,0 +1,203 @@
     3.4 +/*
     3.5 +    SDL_mixer:  An audio mixer library based on the SDL library
     3.6 +    Copyright (C) 1997-2001  Sam Lantinga
     3.7 +
     3.8 +    This library is free software; you can redistribute it and/or
     3.9 +    modify it under the terms of the GNU Library General Public
    3.10 +    License as published by the Free Software Foundation; either
    3.11 +    version 2 of the License, or (at your option) any later version.
    3.12 +
    3.13 +    This library is distributed in the hope that it will be useful,
    3.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3.16 +    Library General Public License for more details.
    3.17 +
    3.18 +    You should have received a copy of the GNU Library General Public
    3.19 +    License along with this library; if not, write to the Free
    3.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.21 +
    3.22 +    This is the source needed to decode an AIFF file into a waveform.
    3.23 +    It's pretty straightforward once you get going. The only
    3.24 +    externally-callable function is Mix_LoadAIFF_RW(), which is meant to
    3.25 +    act as identically to SDL_LoadWAV_RW() as possible.
    3.26 +
    3.27 +    This file by Torbjrn Andersson (torbjorn.andersson@eurotime.se)
    3.28 +*/
    3.29 +
    3.30 +#include "SDL_mutex.h"
    3.31 +#include "SDL_endian.h"
    3.32 +#include "SDL_timer.h"
    3.33 +
    3.34 +#include "SDL_mixer.h"
    3.35 +#include "load_aiff.h"
    3.36 +
    3.37 +/*********************************************/
    3.38 +/* Define values for AIFF (IFF audio) format */
    3.39 +/*********************************************/
    3.40 +#define FORM		0x4d524f46		/* "FORM" */
    3.41 +#define AIFF		0x46464941		/* "AIFF" */
    3.42 +#define SSND		0x444e5353		/* "SSND" */
    3.43 +#define COMM		0x4d4d4f43		/* "COMM" */
    3.44 +
    3.45 +/* This function was taken from libsndfile. I don't pretend to fully
    3.46 + * understand it.
    3.47 + */
    3.48 +
    3.49 +static Uint32 SANE_to_Uint32 (Uint8 *sanebuf)
    3.50 +{
    3.51 +	/* Is the frequency outside of what we can represent with Uint32? */
    3.52 +	if ( (sanebuf[0] & 0x80) || (sanebuf[0] <= 0x3F) || (sanebuf[0] > 0x40)
    3.53 +		|| (sanebuf[0] == 0x40 && sanebuf[1] > 0x1C) )
    3.54 +		return 0;
    3.55 +
    3.56 +	return ((sanebuf[2] << 23) | (sanebuf[3] << 15) | (sanebuf[4] << 7)
    3.57 +		| (sanebuf[5] >> 1)) >> (29 - sanebuf[1]);
    3.58 +}
    3.59 +
    3.60 +/* This function is based on SDL_LoadWAV_RW(). */
    3.61 +
    3.62 +SDL_AudioSpec *Mix_LoadAIFF_RW (SDL_RWops *src, int freesrc,
    3.63 +	SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
    3.64 +{
    3.65 +	int was_error;
    3.66 +	int found_SSND;
    3.67 +	int found_COMM;
    3.68 +	long start;
    3.69 +
    3.70 +	Uint32 chunk_type;
    3.71 +	Uint32 chunk_length;
    3.72 +	long next_chunk;
    3.73 +
    3.74 +	/* AIFF magic header */
    3.75 +	Uint32 FORMchunk;
    3.76 +	Uint32 AIFFmagic;
    3.77 +
    3.78 +	/* SSND chunk */
    3.79 +	Uint32 offset;
    3.80 +	Uint32 blocksize;
    3.81 +
    3.82 +	/* COMM format chunk */
    3.83 +	Uint16 channels;
    3.84 +	Uint32 numsamples;
    3.85 +	Uint16 samplesize;
    3.86 +	Uint8 sane_freq[10];
    3.87 +	Uint32 frequency;
    3.88 +
    3.89 +	/* Make sure we are passed a valid data source */
    3.90 +	was_error = 0;
    3.91 +	if ( src == NULL ) {
    3.92 +		was_error = 1;
    3.93 +		goto done;
    3.94 +	}
    3.95 +
    3.96 +	FORMchunk	= SDL_ReadLE32(src);
    3.97 +	chunk_length	= SDL_ReadBE32(src);
    3.98 +	if ( chunk_length == AIFF ) { /* The FORMchunk has already been read */
    3.99 +		AIFFmagic    = chunk_length;
   3.100 +		chunk_length = FORMchunk;
   3.101 +		FORMchunk    = FORM;
   3.102 +	} else {
   3.103 +		AIFFmagic    = SDL_ReadLE32(src);
   3.104 +	}
   3.105 +	if ( (FORMchunk != FORM) || (AIFFmagic != AIFF) ) {
   3.106 +		SDL_SetError("Unrecognized file type (not AIFF)");
   3.107 +		was_error = 1;
   3.108 +		goto done;
   3.109 +	}
   3.110 +
   3.111 +	/* TODO: Better santity-checking. */
   3.112 +
   3.113 +	found_SSND = 0;
   3.114 +	found_COMM = 0;
   3.115 +
   3.116 +	do {
   3.117 +		chunk_type	= SDL_ReadLE32(src);
   3.118 +		chunk_length	= SDL_ReadBE32(src);
   3.119 +		next_chunk	= SDL_RWtell(src) + chunk_length;
   3.120 +
   3.121 +		/* Paranoia to avoid infinite loops */
   3.122 +		if (chunk_length == 0)
   3.123 +			break;
   3.124 +
   3.125 +		switch (chunk_type) {
   3.126 +			case SSND:
   3.127 +				found_SSND	= 1;
   3.128 +				offset		= SDL_ReadBE32(src);
   3.129 +				blocksize	= SDL_ReadBE32(src);
   3.130 +				start		= SDL_RWtell(src) + offset;
   3.131 +				break;
   3.132 +
   3.133 +			case COMM:
   3.134 +				found_COMM	= 1;
   3.135 +				channels	= SDL_ReadBE16(src);
   3.136 +				numsamples	= SDL_ReadBE32(src);
   3.137 +				samplesize	= SDL_ReadBE16(src);
   3.138 +				SDL_RWread(src, sane_freq, sizeof(sane_freq), 1);
   3.139 +				frequency	= SANE_to_Uint32(sane_freq);
   3.140 +				if (frequency == 0) {
   3.141 +					SDL_SetError("Bad AIFF sample frequency");
   3.142 +					was_error = 1;
   3.143 +					goto done;
   3.144 +				}
   3.145 +				break;
   3.146 +
   3.147 +			default:
   3.148 +				break;
   3.149 +		}
   3.150 +	} while ( ( !found_SSND || !found_COMM )
   3.151 +		  && SDL_RWseek(src, next_chunk, SEEK_SET) != 1 );
   3.152 +
   3.153 +	if ( !found_SSND ) {
   3.154 +		SDL_SetError("Bad AIFF (no SSND chunk)");
   3.155 +		was_error = 1;
   3.156 +		goto done;
   3.157 +	}
   3.158 +
   3.159 +	if ( !found_COMM ) {
   3.160 +		SDL_SetError("Bad AIFF (no COMM chunk)");
   3.161 +		was_error = 1;
   3.162 +		goto done;
   3.163 +	}
   3.164 +
   3.165 +	/* Decode the audio data format */
   3.166 +	memset(spec, 0, sizeof(*spec));
   3.167 +	spec->freq = frequency;
   3.168 +	switch (samplesize) {
   3.169 +		case 8:
   3.170 +			spec->format = AUDIO_S8;
   3.171 +			break;
   3.172 +		case 16:
   3.173 +			spec->format = AUDIO_S16MSB;
   3.174 +			break;
   3.175 +		default:
   3.176 +			SDL_SetError("Unsupported AIFF samplesize");
   3.177 +			was_error = 1;
   3.178 +			goto done;
   3.179 +	}
   3.180 +	spec->channels = (Uint8) channels;
   3.181 +	spec->samples = 4096;		/* Good default buffer size */
   3.182 +
   3.183 +	*audio_len = channels * numsamples * (samplesize / 8);
   3.184 +	*audio_buf = (Uint8 *)malloc(*audio_len);
   3.185 +	if ( *audio_buf == NULL ) {
   3.186 +		SDL_SetError("Out of memory");
   3.187 +		return(NULL);
   3.188 +	}
   3.189 +	SDL_RWseek(src, start, SEEK_SET);
   3.190 +	if ( SDL_RWread(src, *audio_buf, *audio_len, 1) != 1 ) {
   3.191 +		SDL_SetError("Unable to read audio data");
   3.192 +		return(NULL);
   3.193 +	}
   3.194 +
   3.195 +	/* Don't return a buffer that isn't a multiple of samplesize */
   3.196 +	*audio_len &= ~((samplesize / 8) - 1);
   3.197 +
   3.198 +done:
   3.199 +	if ( freesrc && src ) {
   3.200 +		SDL_RWclose(src);
   3.201 +	}
   3.202 +	if ( was_error ) {
   3.203 +		spec = NULL;
   3.204 +	}
   3.205 +	return(spec);
   3.206 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/load_aiff.h	Tue Sep 11 18:24:38 2001 +0000
     4.3 @@ -0,0 +1,31 @@
     4.4 +/*
     4.5 +    SDL_mixer:  An audio mixer library based on the SDL library
     4.6 +    Copyright (C) 1997-2001  Sam Lantinga
     4.7 +
     4.8 +    This library is free software; you can redistribute it and/or
     4.9 +    modify it under the terms of the GNU Library General Public
    4.10 +    License as published by the Free Software Foundation; either
    4.11 +    version 2 of the License, or (at your option) any later version.
    4.12 +
    4.13 +    This library is distributed in the hope that it will be useful,
    4.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.16 +    Library General Public License for more details.
    4.17 +
    4.18 +    You should have received a copy of the GNU Library General Public
    4.19 +    License along with this library; if not, write to the Free
    4.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.21 +
    4.22 +    This is the source needed to decode an AIFF file into a waveform.
    4.23 +    It's pretty straightforward once you get going. The only
    4.24 +    externally-callable function is Mix_LoadAIFF_RW(), which is meant to
    4.25 +    act as identically to SDL_LoadWAV_RW() as possible.
    4.26 +
    4.27 +    This file by Torbjrn Andersson (torbjorn.andersson@eurotime.se)
    4.28 +*/
    4.29 +
    4.30 +/* $Id$ */
    4.31 +
    4.32 +/* Don't call this directly; use Mix_LoadWAV_RW() for now. */
    4.33 +SDL_AudioSpec *Mix_LoadAIFF_RW (SDL_RWops *src, int freesrc,
    4.34 +	SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/load_voc.c	Tue Sep 11 18:24:38 2001 +0000
     5.3 @@ -0,0 +1,472 @@
     5.4 +/*
     5.5 +    SDL_mixer:  An audio mixer library based on the SDL library
     5.6 +    Copyright (C) 1997-2001  Sam Lantinga
     5.7 +
     5.8 +    This library is free software; you can redistribute it and/or
     5.9 +    modify it under the terms of the GNU Library General Public
    5.10 +    License as published by the Free Software Foundation; either
    5.11 +    version 2 of the License, or (at your option) any later version.
    5.12 +
    5.13 +    This library is distributed in the hope that it will be useful,
    5.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.16 +    Library General Public License for more details.
    5.17 +
    5.18 +    You should have received a copy of the GNU Library General Public
    5.19 +    License along with this library; if not, write to the Free
    5.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.21 +
    5.22 +    This is the source needed to decode a Creative Labs VOC file into a
    5.23 +    waveform. It's pretty straightforward once you get going. The only
    5.24 +    externally-callable function is Mix_LoadVOC_RW(), which is meant to
    5.25 +    act as identically to SDL_LoadWAV_RW() as possible.
    5.26 +
    5.27 +    This file by Ryan C. Gordon (icculus@linuxgames.com).
    5.28 +
    5.29 +    Heavily borrowed from sox v12.17.1's voc.c.
    5.30 +        (http://www.freshmeat.net/projects/sox/)
    5.31 +*/
    5.32 +
    5.33 +/* $Id$ */
    5.34 +
    5.35 +#include <stdio.h>
    5.36 +#include <stdlib.h>
    5.37 +#include <string.h>
    5.38 +
    5.39 +#include "SDL_mutex.h"
    5.40 +#include "SDL_endian.h"
    5.41 +#include "SDL_timer.h"
    5.42 +
    5.43 +#include "SDL_mixer.h"
    5.44 +#include "load_voc.h"
    5.45 +
    5.46 +#ifdef VOC_SAMPLES
    5.47 +
    5.48 +/* Private data for VOC file */
    5.49 +typedef struct vocstuff {
    5.50 +	Uint32	rest;			/* bytes remaining in current block */
    5.51 +	Uint32	rate;			/* rate code (byte) of this chunk */
    5.52 +	int 	silent;		/* sound or silence? */
    5.53 +	Uint32	srate;			/* rate code (byte) of silence */
    5.54 +	Uint32	blockseek;		/* start of current output block */
    5.55 +	Uint32	samples;		/* number of samples output */
    5.56 +	Uint32	size;		/* word length of data */
    5.57 +	int 	channels;	/* number of sound channels */
    5.58 +	int     extended;       /* Has an extended block been read? */
    5.59 +} vs_t;
    5.60 +
    5.61 +/* Size field */ 
    5.62 +/* SJB: note that the 1st 3 are sometimes used as sizeof(type) */
    5.63 +#define	ST_SIZE_BYTE	1
    5.64 +#define ST_SIZE_8BIT	1
    5.65 +#define	ST_SIZE_WORD	2
    5.66 +#define ST_SIZE_16BIT	2
    5.67 +#define	ST_SIZE_DWORD	4
    5.68 +#define ST_SIZE_32BIT	4
    5.69 +#define	ST_SIZE_FLOAT	5
    5.70 +#define ST_SIZE_DOUBLE	6
    5.71 +#define ST_SIZE_IEEE	7	/* IEEE 80-bit floats. */
    5.72 +
    5.73 +/* Style field */
    5.74 +#define ST_ENCODING_UNSIGNED	1 /* unsigned linear: Sound Blaster */
    5.75 +#define ST_ENCODING_SIGN2	2 /* signed linear 2's comp: Mac */
    5.76 +#define	ST_ENCODING_ULAW	3 /* U-law signed logs: US telephony, SPARC */
    5.77 +#define ST_ENCODING_ALAW	4 /* A-law signed logs: non-US telephony */
    5.78 +#define ST_ENCODING_ADPCM	5 /* Compressed PCM */
    5.79 +#define ST_ENCODING_IMA_ADPCM	6 /* Compressed PCM */
    5.80 +#define ST_ENCODING_GSM		7 /* GSM 6.10 33-byte frame lossy compression */
    5.81 +
    5.82 +#define	VOC_TERM	0
    5.83 +#define	VOC_DATA	1
    5.84 +#define	VOC_CONT	2
    5.85 +#define	VOC_SILENCE	3
    5.86 +#define	VOC_MARKER	4
    5.87 +#define	VOC_TEXT	5
    5.88 +#define	VOC_LOOP	6
    5.89 +#define	VOC_LOOPEND	7
    5.90 +#define VOC_EXTENDED    8
    5.91 +#define VOC_DATA_16	9
    5.92 +
    5.93 +
    5.94 +static inline int voc_check_header(SDL_RWops *src)
    5.95 +{
    5.96 +    /* VOC magic header */
    5.97 +    Uint8  signature[20];  /* "Creative Voice File\032" */
    5.98 +    Uint16 datablockofs;
    5.99 +
   5.100 +    SDL_RWseek(src, 0, SEEK_SET);
   5.101 +
   5.102 +    if (SDL_RWread(src, signature, sizeof (signature), 1) != 1)
   5.103 +        return(0);
   5.104 +
   5.105 +    if (memcmp(signature, "Creative Voice File\032", sizeof (signature)) != 0) {
   5.106 +        SDL_SetError("Unrecognized file type (not VOC)");
   5.107 +        return(0);
   5.108 +    }
   5.109 +
   5.110 +        /* get the offset where the first datablock is located */
   5.111 +    if (SDL_RWread(src, &datablockofs, sizeof (Uint16), 1) != 1)
   5.112 +        return(0);
   5.113 +
   5.114 +    datablockofs = SDL_SwapLE16(datablockofs);
   5.115 +
   5.116 +    if (SDL_RWseek(src, datablockofs, SEEK_SET) != datablockofs)
   5.117 +        return(0);
   5.118 +
   5.119 +    return(1);  /* success! */
   5.120 +} /* voc_check_header */
   5.121 +
   5.122 +
   5.123 +/* Read next block header, save info, leave position at start of data */
   5.124 +static int voc_get_block(SDL_RWops *src, vs_t *v, SDL_AudioSpec *spec)
   5.125 +{
   5.126 +    Uint8 bits24[3];
   5.127 +    Uint8 uc, block;
   5.128 +    Uint32 sblen;
   5.129 +    Uint16 new_rate_short;
   5.130 +    Uint32 new_rate_long;
   5.131 +    Uint8 trash[6];
   5.132 +    Uint16 period;
   5.133 +    int i;
   5.134 +
   5.135 +    v->silent = 0;
   5.136 +    while (v->rest == 0)
   5.137 +    {
   5.138 +        if (SDL_RWread(src, &block, sizeof (block), 1) != 1)
   5.139 +            return 1;  /* assume that's the end of the file. */
   5.140 +
   5.141 +        if (block == VOC_TERM)
   5.142 +            return 1;
   5.143 +
   5.144 +        if (SDL_RWread(src, bits24, sizeof (bits24), 1) != 1)
   5.145 +            return 1;  /* assume that's the end of the file. */
   5.146 +        
   5.147 +        /* Size is an 24-bit value. Ugh. */
   5.148 +        sblen = ( (bits24[0]) | (bits24[1] << 8) | (bits24[2] << 16) );
   5.149 +
   5.150 +        switch(block)
   5.151 +        {
   5.152 +            case VOC_DATA:
   5.153 +                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   5.154 +                    return 0;
   5.155 +
   5.156 +                /* When DATA block preceeded by an EXTENDED     */
   5.157 +                /* block, the DATA blocks rate value is invalid */
   5.158 +                if (!v->extended)
   5.159 +                {
   5.160 +                    if (uc == 0)
   5.161 +                    {
   5.162 +                        SDL_SetError("VOC Sample rate is zero?");
   5.163 +                        return 0;
   5.164 +                    }
   5.165 +
   5.166 +                    if ((v->rate != -1) && (uc != v->rate))
   5.167 +                    {
   5.168 +                        SDL_SetError("VOC sample rate codes differ");
   5.169 +                        return 0;
   5.170 +                    }
   5.171 +
   5.172 +                    v->rate = uc;
   5.173 +                    spec->freq = 1000000.0/(256 - v->rate);
   5.174 +                    v->channels = 1;
   5.175 +                }
   5.176 +
   5.177 +                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   5.178 +                    return 0;
   5.179 +
   5.180 +                if (uc != 0)
   5.181 +                {
   5.182 +                    SDL_SetError("VOC decoder only interprets 8-bit data");
   5.183 +                    return 0;
   5.184 +                }
   5.185 +
   5.186 +                v->extended = 0;
   5.187 +                v->rest = sblen - 2;
   5.188 +                v->size = ST_SIZE_BYTE;
   5.189 +                return 1;
   5.190 +
   5.191 +            case VOC_DATA_16:
   5.192 +                if (SDL_RWread(src, &new_rate_long, sizeof (new_rate_long), 1) != 1)
   5.193 +                    return 0;
   5.194 +                new_rate_long = SDL_SwapLE32(new_rate_long);
   5.195 +                if (new_rate_long == 0)
   5.196 +                {
   5.197 +                    SDL_SetError("VOC Sample rate is zero?");
   5.198 +                    return 0;
   5.199 +                }
   5.200 +                if ((v->rate != -1) && (new_rate_long != v->rate))
   5.201 +                {
   5.202 +                    SDL_SetError("VOC sample rate codes differ");
   5.203 +                    return 0;
   5.204 +                }
   5.205 +                v->rate = new_rate_long;
   5.206 +                spec->freq = new_rate_long;
   5.207 +
   5.208 +                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   5.209 +                    return 0;
   5.210 +
   5.211 +                switch (uc)
   5.212 +                {
   5.213 +                    case 8:  v->size = ST_SIZE_BYTE; break;
   5.214 +                    case 16: v->size = ST_SIZE_WORD; break;
   5.215 +                    default:
   5.216 +                        SDL_SetError("VOC with unknown data size");
   5.217 +                        return 0;
   5.218 +                }
   5.219 +
   5.220 +                if (SDL_RWread(src, &v->channels, sizeof (Uint8), 1) != 1)
   5.221 +                    return 0;
   5.222 +
   5.223 +                if (SDL_RWread(src, trash, sizeof (Uint8), 6) != 6)
   5.224 +                    return 0;
   5.225 +
   5.226 +                v->rest = sblen - 12;
   5.227 +                return 1;
   5.228 +
   5.229 +            case VOC_CONT:
   5.230 +                v->rest = sblen;
   5.231 +                return 1;
   5.232 +
   5.233 +            case VOC_SILENCE:
   5.234 +                if (SDL_RWread(src, &period, sizeof (period), 1) != 1)
   5.235 +                    return 0;
   5.236 +                period = SDL_SwapLE16(period);
   5.237 +
   5.238 +                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   5.239 +                    return 0;
   5.240 +                if (uc == 0)
   5.241 +                {
   5.242 +                    SDL_SetError("VOC silence sample rate is zero");
   5.243 +                    return 0;
   5.244 +                }
   5.245 +
   5.246 +                /*
   5.247 +                 * Some silence-packed files have gratuitously
   5.248 +                 * different sample rate codes in silence.
   5.249 +                 * Adjust period.
   5.250 +                 */
   5.251 +                if ((v->rate != -1) && (uc != v->rate))
   5.252 +                    period = (period * (256 - uc))/(256 - v->rate);
   5.253 +                else
   5.254 +                    v->rate = uc;
   5.255 +                v->rest = period;
   5.256 +                v->silent = 1;
   5.257 +                return 1;
   5.258 +
   5.259 +            case VOC_LOOP:
   5.260 +            case VOC_LOOPEND:
   5.261 +                for(i = 0; i < sblen; i++)   /* skip repeat loops. */
   5.262 +                {
   5.263 +                    if (SDL_RWread(src, trash, sizeof (Uint8), 1) != 1)
   5.264 +                        return 0;
   5.265 +                }
   5.266 +                break;
   5.267 +
   5.268 +            case VOC_EXTENDED:
   5.269 +                /* An Extended block is followed by a data block */
   5.270 +                /* Set this byte so we know to use the rate      */
   5.271 +                /* value from the extended block and not the     */
   5.272 +                /* data block.                     */
   5.273 +                v->extended = 1;
   5.274 +                if (SDL_RWread(src, &new_rate_short, sizeof (new_rate_short), 1) != 1)
   5.275 +                    return 0;
   5.276 +                new_rate_short = SDL_SwapLE16(new_rate_short);
   5.277 +                if (new_rate_short == 0)
   5.278 +                {
   5.279 +                   SDL_SetError("VOC sample rate is zero");
   5.280 +                   return 0;
   5.281 +                }
   5.282 +                if ((v->rate != -1) && (new_rate_short != v->rate))
   5.283 +                {
   5.284 +                   SDL_SetError("VOC sample rate codes differ");
   5.285 +                   return 0;
   5.286 +                }
   5.287 +                v->rate = new_rate_short;
   5.288 +
   5.289 +                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   5.290 +                    return 0;
   5.291 +
   5.292 +                if (uc != 0)
   5.293 +                {
   5.294 +                    SDL_SetError("VOC decoder only interprets 8-bit data");
   5.295 +                    return 0;
   5.296 +                }
   5.297 +
   5.298 +                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   5.299 +                    return 0;
   5.300 +
   5.301 +                if (uc)
   5.302 +                    spec->channels = 2;  /* Stereo */
   5.303 +                /* Needed number of channels before finishing
   5.304 +                   compute for rate */
   5.305 +                spec->freq = (256000000L/(65536L - v->rate))/spec->channels;
   5.306 +                /* An extended block must be followed by a data */
   5.307 +                /* block to be valid so loop back to top so it  */
   5.308 +                /* can be grabed.                */
   5.309 +                continue;
   5.310 +
   5.311 +            case VOC_MARKER:
   5.312 +                if (SDL_RWread(src, trash, sizeof (Uint8), 2) != 2)
   5.313 +                    return 0;
   5.314 +
   5.315 +                /* Falling! Falling! */
   5.316 +
   5.317 +            default:  /* text block or other krapola. */
   5.318 +                for(i = 0; i < sblen; i++)
   5.319 +                {
   5.320 +                    if (SDL_RWread(src, &trash, sizeof (Uint8), 1) != 1)
   5.321 +                        return 0;
   5.322 +                }
   5.323 +
   5.324 +                if (block == VOC_TEXT)
   5.325 +                    continue;    /* get next block */
   5.326 +        }
   5.327 +    }
   5.328 +
   5.329 +    return 1;
   5.330 +}
   5.331 +
   5.332 +
   5.333 +static int voc_read(SDL_RWops *src, vs_t *v, Uint8 *buf, SDL_AudioSpec *spec)
   5.334 +{
   5.335 +    int done = 0;
   5.336 +    Uint8 silence = 0x80;
   5.337 +
   5.338 +    if (v->rest == 0)
   5.339 +    {
   5.340 +        if (!voc_get_block(src, v, spec))
   5.341 +            return 0;
   5.342 +    }
   5.343 +
   5.344 +    if (v->rest == 0)
   5.345 +        return 0;
   5.346 +
   5.347 +    if (v->silent)
   5.348 +    {
   5.349 +        if (v->size == ST_SIZE_WORD)
   5.350 +            silence = 0x00;
   5.351 +
   5.352 +        /* Fill in silence */
   5.353 +        memset(buf, silence, v->rest);
   5.354 +        done = v->rest;
   5.355 +        v->rest = 0;
   5.356 +    }
   5.357 +
   5.358 +    else
   5.359 +    {
   5.360 +        done = SDL_RWread(src, buf, 1, v->rest);
   5.361 +        v->rest -= done;
   5.362 +        if (v->size == ST_SIZE_WORD)
   5.363 +        {
   5.364 +            done >>= 1;
   5.365 +            #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
   5.366 +                for (; v->rest > 0; v->rest -= 2)
   5.367 +                {
   5.368 +                    *((Uint16 *) buf) = SDL_SwapLE16(*((Uint16 *) buf));
   5.369 +                    ((Uint16 *) buf)++;
   5.370 +                }
   5.371 +            #endif
   5.372 +        }
   5.373 +    }
   5.374 +
   5.375 +    return done;
   5.376 +} /* voc_read */
   5.377 +
   5.378 +
   5.379 +/* don't call this directly; use Mix_LoadWAV_RW() for now. */
   5.380 +SDL_AudioSpec *Mix_LoadVOC_RW (SDL_RWops *src, int freesrc,
   5.381 +        SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
   5.382 +{
   5.383 +    vs_t v;
   5.384 +    int was_error = 1;
   5.385 +    int samplesize;
   5.386 +    Uint8 *fillptr;
   5.387 +    void *ptr;
   5.388 +
   5.389 +    if ( (!src) || (!audio_buf) || (!audio_len) )   /* sanity checks. */
   5.390 +        goto done;
   5.391 +
   5.392 +    if ( !voc_check_header(src) )
   5.393 +        goto done;
   5.394 +
   5.395 +    v.rate = -1;
   5.396 +    v.rest = 0;
   5.397 +    v.extended = 0;
   5.398 +    *audio_buf = NULL;
   5.399 +    *audio_len = 0;
   5.400 +    memset(spec, '\0', sizeof (SDL_AudioSpec));
   5.401 +
   5.402 +    if (!voc_get_block(src, &v, spec))
   5.403 +        goto done;
   5.404 +
   5.405 +    if (v.rate == -1)
   5.406 +    {
   5.407 +        SDL_SetError("VOC data had no sound!");
   5.408 +        goto done;
   5.409 +    }
   5.410 +
   5.411 +    spec->format = ((v.size == ST_SIZE_WORD) ? AUDIO_S16 : AUDIO_U8);
   5.412 +    if (spec->channels == 0)
   5.413 +        spec->channels = v.channels;
   5.414 +
   5.415 +    *audio_len = v.rest;
   5.416 +    *audio_buf = malloc(v.rest);
   5.417 +    if (*audio_buf == NULL)
   5.418 +        goto done;
   5.419 +
   5.420 +    fillptr = *audio_buf;
   5.421 +
   5.422 +    while (voc_read(src, &v, fillptr, spec) > 0)
   5.423 +    {
   5.424 +        if (!voc_get_block(src, &v, spec))
   5.425 +            goto done;
   5.426 +
   5.427 +        *audio_len += v.rest;
   5.428 +        ptr = realloc(*audio_buf, *audio_len);
   5.429 +        if (ptr == NULL)
   5.430 +        {
   5.431 +            free(*audio_buf);
   5.432 +            *audio_buf = NULL;
   5.433 +            *audio_len = 0;
   5.434 +            goto done;
   5.435 +        }
   5.436 +
   5.437 +        *audio_buf = ptr;
   5.438 +        fillptr = ((Uint8 *) ptr) + (*audio_len - v.rest);
   5.439 +    }
   5.440 +
   5.441 +    spec->samples = (*audio_len / v.size);
   5.442 +
   5.443 +    was_error = 0;  /* success, baby! */
   5.444 +
   5.445 +    /* Don't return a buffer that isn't a multiple of samplesize */
   5.446 +    samplesize = ((spec->format & 0xFF)/8)*spec->channels;
   5.447 +    *audio_len &= ~(samplesize-1);
   5.448 +
   5.449 +done:
   5.450 +    if (src)
   5.451 +    {
   5.452 +        if (freesrc)
   5.453 +            SDL_RWclose(src);
   5.454 +        else
   5.455 +            SDL_RWseek(src, 0, SEEK_SET);
   5.456 +    }
   5.457 +
   5.458 +    if ( was_error )
   5.459 +        spec = NULL;
   5.460 +
   5.461 +    return(spec);
   5.462 +} /* Mix_LoadVOC_RW */
   5.463 +
   5.464 +#else
   5.465 +
   5.466 +SDL_AudioSpec *Mix_LoadVOC_RW (SDL_RWops *src, int freesrc,
   5.467 +        SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
   5.468 +{
   5.469 +    SDL_SetError("VOC file loading not supported");
   5.470 +    return(NULL);
   5.471 +}
   5.472 +
   5.473 +#endif /* VOC_SAMPLES */
   5.474 +
   5.475 +/* end of load_voc.c ... */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/load_voc.h	Tue Sep 11 18:24:38 2001 +0000
     6.3 @@ -0,0 +1,34 @@
     6.4 +/*
     6.5 +    SDL_mixer:  An audio mixer library based on the SDL library
     6.6 +    Copyright (C) 1997-2001  Sam Lantinga
     6.7 +
     6.8 +    This library is free software; you can redistribute it and/or
     6.9 +    modify it under the terms of the GNU Library General Public
    6.10 +    License as published by the Free Software Foundation; either
    6.11 +    version 2 of the License, or (at your option) any later version.
    6.12 +
    6.13 +    This library is distributed in the hope that it will be useful,
    6.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.16 +    Library General Public License for more details.
    6.17 +
    6.18 +    You should have received a copy of the GNU Library General Public
    6.19 +    License along with this library; if not, write to the Free
    6.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.21 +
    6.22 +    This is the source needed to decode a Creative Labs VOC file into a
    6.23 +    waveform. It's pretty straightforward once you get going. The only
    6.24 +    externally-callable function is Mix_LoadVOC_RW(), which is meant to
    6.25 +    act as identically to SDL_LoadWAV_RW() as possible.
    6.26 +
    6.27 +    This file by Ryan C. Gordon (icculus@linuxgames.com).
    6.28 +
    6.29 +    Heavily borrowed from sox v12.17.1's voc.c.
    6.30 +        (http://www.freshmeat.net/projects/sox/)
    6.31 +*/
    6.32 +
    6.33 +/* $Id$ */
    6.34 +
    6.35 +/* Don't call this directly; use Mix_LoadWAV_RW() for now. */
    6.36 +SDL_AudioSpec *Mix_LoadVOC_RW (SDL_RWops *src, int freesrc,
    6.37 +        SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);
     7.1 --- a/mixer.c	Fri Sep 07 01:06:20 2001 +0000
     7.2 +++ b/mixer.c	Tue Sep 11 18:24:38 2001 +0000
     7.3 @@ -33,6 +33,12 @@
     7.4  #include "SDL_timer.h"
     7.5  
     7.6  #include "SDL_mixer.h"
     7.7 +#include "load_aiff.h"
     7.8 +#include "load_voc.h"
     7.9 +
    7.10 +/* Magic numbers for various audio file formats */
    7.11 +#define WAVE		0x45564157		/* "WAVE" */
    7.12 +#define FORM		0x4d524f46		/* "FORM" */
    7.13  
    7.14  static int audio_opened = 0;
    7.15  
    7.16 @@ -284,22 +290,18 @@
    7.17   *             generic setup, then call the correct file format loader.
    7.18   */
    7.19  
    7.20 -#ifdef VOC_SAMPLES
    7.21 -SDL_AudioSpec *Mix_LoadVOC_RW (SDL_RWops *src, int freesrc,
    7.22 -		SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);
    7.23 -#endif
    7.24 -
    7.25  /* Load a wave file */
    7.26  Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
    7.27  {
    7.28 +	Uint32 magic;
    7.29  	Mix_Chunk *chunk;
    7.30 -	SDL_AudioSpec wavespec;
    7.31 +	SDL_AudioSpec wavespec, *loaded;
    7.32  	SDL_AudioCVT wavecvt;
    7.33  	int samplesize;
    7.34  
    7.35  	/* rcg06012001 Make sure src is valid */
    7.36  	if ( ! src ) {
    7.37 -		SDL_SetError("Mix_LoadWAV_RW with NULL SDL_RWops");
    7.38 +		SDL_SetError("Mix_LoadWAV_RW with NULL src");
    7.39  		return(NULL);
    7.40  	}
    7.41  
    7.42 @@ -322,22 +324,30 @@
    7.43  		return(NULL);
    7.44  	}
    7.45  
    7.46 -	/* rcg06012001 Handle Creative Labs .VOC format chunks. */
    7.47 -#ifdef VOC_SAMPLES
    7.48 -	if ( Mix_LoadVOC_RW(src, 0,
    7.49 -		&wavespec, (Uint8 **)&chunk->abuf, &chunk->alen) == NULL ) {
    7.50 -#endif
    7.51 -	/* Load the WAV file into the chunk */
    7.52 -	if ( SDL_LoadWAV_RW(src, freesrc,
    7.53 -		&wavespec, (Uint8 **)&chunk->abuf, &chunk->alen) == NULL ) {
    7.54 +	/* Find out what kind of audio file this is */
    7.55 +	magic = SDL_ReadLE32(src);
    7.56 +	/* Seek backwards for compatibility with older loaders */
    7.57 +	SDL_RWseek(src, -sizeof(Uint32), SEEK_CUR);
    7.58 +
    7.59 +	switch (magic) {
    7.60 +		case WAVE:
    7.61 +			loaded = SDL_LoadWAV_RW(src, freesrc, &wavespec,
    7.62 +					(Uint8 **)&chunk->abuf, &chunk->alen);
    7.63 +			break;
    7.64 +		case FORM:
    7.65 +			loaded = Mix_LoadAIFF_RW(src, freesrc, &wavespec,
    7.66 +					(Uint8 **)&chunk->abuf, &chunk->alen);
    7.67 +			break;
    7.68 +		default:
    7.69 +			loaded = Mix_LoadVOC_RW(src, freesrc, &wavespec,
    7.70 +					(Uint8 **)&chunk->abuf, &chunk->alen);
    7.71 +			break;
    7.72 +	}
    7.73 +	if ( !loaded ) {
    7.74  		free(chunk);
    7.75  		return(NULL);
    7.76  	}
    7.77  
    7.78 -#ifdef VOC_SAMPLES
    7.79 -	}
    7.80 -#endif
    7.81 -
    7.82  #if 0
    7.83  	PrintFormat("Audio device", &mixer);
    7.84  	PrintFormat("-- Wave file", &wavespec);
     8.1 --- a/voc.c	Fri Sep 07 01:06:20 2001 +0000
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,463 +0,0 @@
     8.4 -/*
     8.5 -    SDL_mixer:  An audio mixer library based on the SDL library
     8.6 -    Copyright (C) 1997-1999  Sam Lantinga
     8.7 -
     8.8 -    This library is free software; you can redistribute it and/or
     8.9 -    modify it under the terms of the GNU Library General Public
    8.10 -    License as published by the Free Software Foundation; either
    8.11 -    version 2 of the License, or (at your option) any later version.
    8.12 -
    8.13 -    This library is distributed in the hope that it will be useful,
    8.14 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.16 -    Library General Public License for more details.
    8.17 -
    8.18 -    You should have received a copy of the GNU Library General Public
    8.19 -    License along with this library; if not, write to the Free
    8.20 -    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.21 -
    8.22 -    This is the source needed to decode a Creative Labs VOC file into a
    8.23 -    waveform. It's pretty straightforward once you get going. The only
    8.24 -    externally-callable function is Mix_LoadVOC_RW(), which is meant to
    8.25 -    act as identically to SDL_LoadWAV_RW() as possible.
    8.26 -
    8.27 -    This file by Ryan C. Gordon (icculus@linuxgames.com).
    8.28 -
    8.29 -    Heavily borrowed from sox v12.17.1's voc.c.
    8.30 -        (http://www.freshmeat.net/projects/sox/)
    8.31 -*/
    8.32 -
    8.33 -/* $Id$ */
    8.34 -
    8.35 -#include <stdio.h>
    8.36 -#include <stdlib.h>
    8.37 -#include <string.h>
    8.38 -
    8.39 -#include "SDL_mutex.h"
    8.40 -#include "SDL_endian.h"
    8.41 -#include "SDL_timer.h"
    8.42 -
    8.43 -#include "SDL_mixer.h"
    8.44 -
    8.45 -#ifdef VOC_SAMPLES
    8.46 -
    8.47 -/* Private data for VOC file */
    8.48 -typedef struct vocstuff {
    8.49 -	Uint32	rest;			/* bytes remaining in current block */
    8.50 -	Uint32	rate;			/* rate code (byte) of this chunk */
    8.51 -	int 	silent;		/* sound or silence? */
    8.52 -	Uint32	srate;			/* rate code (byte) of silence */
    8.53 -	Uint32	blockseek;		/* start of current output block */
    8.54 -	Uint32	samples;		/* number of samples output */
    8.55 -	Uint32	size;		/* word length of data */
    8.56 -	int 	channels;	/* number of sound channels */
    8.57 -	int     extended;       /* Has an extended block been read? */
    8.58 -} vs_t;
    8.59 -
    8.60 -/* Size field */ 
    8.61 -/* SJB: note that the 1st 3 are sometimes used as sizeof(type) */
    8.62 -#define	ST_SIZE_BYTE	1
    8.63 -#define ST_SIZE_8BIT	1
    8.64 -#define	ST_SIZE_WORD	2
    8.65 -#define ST_SIZE_16BIT	2
    8.66 -#define	ST_SIZE_DWORD	4
    8.67 -#define ST_SIZE_32BIT	4
    8.68 -#define	ST_SIZE_FLOAT	5
    8.69 -#define ST_SIZE_DOUBLE	6
    8.70 -#define ST_SIZE_IEEE	7	/* IEEE 80-bit floats. */
    8.71 -
    8.72 -/* Style field */
    8.73 -#define ST_ENCODING_UNSIGNED	1 /* unsigned linear: Sound Blaster */
    8.74 -#define ST_ENCODING_SIGN2	2 /* signed linear 2's comp: Mac */
    8.75 -#define	ST_ENCODING_ULAW	3 /* U-law signed logs: US telephony, SPARC */
    8.76 -#define ST_ENCODING_ALAW	4 /* A-law signed logs: non-US telephony */
    8.77 -#define ST_ENCODING_ADPCM	5 /* Compressed PCM */
    8.78 -#define ST_ENCODING_IMA_ADPCM	6 /* Compressed PCM */
    8.79 -#define ST_ENCODING_GSM		7 /* GSM 6.10 33-byte frame lossy compression */
    8.80 -
    8.81 -#define	VOC_TERM	0
    8.82 -#define	VOC_DATA	1
    8.83 -#define	VOC_CONT	2
    8.84 -#define	VOC_SILENCE	3
    8.85 -#define	VOC_MARKER	4
    8.86 -#define	VOC_TEXT	5
    8.87 -#define	VOC_LOOP	6
    8.88 -#define	VOC_LOOPEND	7
    8.89 -#define VOC_EXTENDED    8
    8.90 -#define VOC_DATA_16	9
    8.91 -
    8.92 -
    8.93 -static inline int voc_check_header(SDL_RWops *src)
    8.94 -{
    8.95 -    /* VOC magic header */
    8.96 -    Uint8  signature[20];  /* "Creative Voice File\032" */
    8.97 -    Uint16 datablockofs;
    8.98 -
    8.99 -    SDL_RWseek(src, 0, SEEK_SET);
   8.100 -
   8.101 -    if (SDL_RWread(src, signature, sizeof (signature), 1) != 1)
   8.102 -        return(0);
   8.103 -
   8.104 -    if (memcmp(signature, "Creative Voice File\032", sizeof (signature)) != 0) {
   8.105 -        SDL_SetError("Unrecognized file type (not VOC)");
   8.106 -        return(0);
   8.107 -    }
   8.108 -
   8.109 -        /* get the offset where the first datablock is located */
   8.110 -    if (SDL_RWread(src, &datablockofs, sizeof (Uint16), 1) != 1)
   8.111 -        return(0);
   8.112 -
   8.113 -    datablockofs = SDL_SwapLE16(datablockofs);
   8.114 -
   8.115 -    if (SDL_RWseek(src, datablockofs, SEEK_SET) != datablockofs)
   8.116 -        return(0);
   8.117 -
   8.118 -    return(1);  /* success! */
   8.119 -} /* voc_check_header */
   8.120 -
   8.121 -
   8.122 -/* Read next block header, save info, leave position at start of data */
   8.123 -static int voc_get_block(SDL_RWops *src, vs_t *v, SDL_AudioSpec *spec)
   8.124 -{
   8.125 -    Uint8 bits24[3];
   8.126 -    Uint8 uc, block;
   8.127 -    Uint32 sblen;
   8.128 -    Uint16 new_rate_short;
   8.129 -    Uint32 new_rate_long;
   8.130 -    Uint8 trash[6];
   8.131 -    Uint16 period;
   8.132 -    int i;
   8.133 -
   8.134 -    v->silent = 0;
   8.135 -    while (v->rest == 0)
   8.136 -    {
   8.137 -        if (SDL_RWread(src, &block, sizeof (block), 1) != 1)
   8.138 -            return 1;  /* assume that's the end of the file. */
   8.139 -
   8.140 -        if (block == VOC_TERM)
   8.141 -            return 1;
   8.142 -
   8.143 -        if (SDL_RWread(src, bits24, sizeof (bits24), 1) != 1)
   8.144 -            return 1;  /* assume that's the end of the file. */
   8.145 -        
   8.146 -        /* Size is an 24-bit value. Ugh. */
   8.147 -        sblen = ( (bits24[0]) | (bits24[1] << 8) | (bits24[2] << 16) );
   8.148 -
   8.149 -        switch(block)
   8.150 -        {
   8.151 -            case VOC_DATA:
   8.152 -                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   8.153 -                    return 0;
   8.154 -
   8.155 -                /* When DATA block preceeded by an EXTENDED     */
   8.156 -                /* block, the DATA blocks rate value is invalid */
   8.157 -                if (!v->extended)
   8.158 -                {
   8.159 -                    if (uc == 0)
   8.160 -                    {
   8.161 -                        SDL_SetError("VOC Sample rate is zero?");
   8.162 -                        return 0;
   8.163 -                    }
   8.164 -
   8.165 -                    if ((v->rate != -1) && (uc != v->rate))
   8.166 -                    {
   8.167 -                        SDL_SetError("VOC sample rate codes differ");
   8.168 -                        return 0;
   8.169 -                    }
   8.170 -
   8.171 -                    v->rate = uc;
   8.172 -                    spec->freq = 1000000.0/(256 - v->rate);
   8.173 -                    v->channels = 1;
   8.174 -                }
   8.175 -
   8.176 -                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   8.177 -                    return 0;
   8.178 -
   8.179 -                if (uc != 0)
   8.180 -                {
   8.181 -                    SDL_SetError("VOC decoder only interprets 8-bit data");
   8.182 -                    return 0;
   8.183 -                }
   8.184 -
   8.185 -                v->extended = 0;
   8.186 -                v->rest = sblen - 2;
   8.187 -                v->size = ST_SIZE_BYTE;
   8.188 -                return 1;
   8.189 -
   8.190 -            case VOC_DATA_16:
   8.191 -                if (SDL_RWread(src, &new_rate_long, sizeof (new_rate_long), 1) != 1)
   8.192 -                    return 0;
   8.193 -                new_rate_long = SDL_SwapLE32(new_rate_long);
   8.194 -                if (new_rate_long == 0)
   8.195 -                {
   8.196 -                    SDL_SetError("VOC Sample rate is zero?");
   8.197 -                    return 0;
   8.198 -                }
   8.199 -                if ((v->rate != -1) && (new_rate_long != v->rate))
   8.200 -                {
   8.201 -                    SDL_SetError("VOC sample rate codes differ");
   8.202 -                    return 0;
   8.203 -                }
   8.204 -                v->rate = new_rate_long;
   8.205 -                spec->freq = new_rate_long;
   8.206 -
   8.207 -                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   8.208 -                    return 0;
   8.209 -
   8.210 -                switch (uc)
   8.211 -                {
   8.212 -                    case 8:  v->size = ST_SIZE_BYTE; break;
   8.213 -                    case 16: v->size = ST_SIZE_WORD; break;
   8.214 -                    default:
   8.215 -                        SDL_SetError("VOC with unknown data size");
   8.216 -                        return 0;
   8.217 -                }
   8.218 -
   8.219 -                if (SDL_RWread(src, &v->channels, sizeof (Uint8), 1) != 1)
   8.220 -                    return 0;
   8.221 -
   8.222 -                if (SDL_RWread(src, trash, sizeof (Uint8), 6) != 6)
   8.223 -                    return 0;
   8.224 -
   8.225 -                v->rest = sblen - 12;
   8.226 -                return 1;
   8.227 -
   8.228 -            case VOC_CONT:
   8.229 -                v->rest = sblen;
   8.230 -                return 1;
   8.231 -
   8.232 -            case VOC_SILENCE:
   8.233 -                if (SDL_RWread(src, &period, sizeof (period), 1) != 1)
   8.234 -                    return 0;
   8.235 -                period = SDL_SwapLE16(period);
   8.236 -
   8.237 -                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   8.238 -                    return 0;
   8.239 -                if (uc == 0)
   8.240 -                {
   8.241 -                    SDL_SetError("VOC silence sample rate is zero");
   8.242 -                    return 0;
   8.243 -                }
   8.244 -
   8.245 -                /*
   8.246 -                 * Some silence-packed files have gratuitously
   8.247 -                 * different sample rate codes in silence.
   8.248 -                 * Adjust period.
   8.249 -                 */
   8.250 -                if ((v->rate != -1) && (uc != v->rate))
   8.251 -                    period = (period * (256 - uc))/(256 - v->rate);
   8.252 -                else
   8.253 -                    v->rate = uc;
   8.254 -                v->rest = period;
   8.255 -                v->silent = 1;
   8.256 -                return 1;
   8.257 -
   8.258 -            case VOC_LOOP:
   8.259 -            case VOC_LOOPEND:
   8.260 -                for(i = 0; i < sblen; i++)   /* skip repeat loops. */
   8.261 -                {
   8.262 -                    if (SDL_RWread(src, trash, sizeof (Uint8), 1) != 1)
   8.263 -                        return 0;
   8.264 -                }
   8.265 -                break;
   8.266 -
   8.267 -            case VOC_EXTENDED:
   8.268 -                /* An Extended block is followed by a data block */
   8.269 -                /* Set this byte so we know to use the rate      */
   8.270 -                /* value from the extended block and not the     */
   8.271 -                /* data block.                     */
   8.272 -                v->extended = 1;
   8.273 -                if (SDL_RWread(src, &new_rate_short, sizeof (new_rate_short), 1) != 1)
   8.274 -                    return 0;
   8.275 -                new_rate_short = SDL_SwapLE16(new_rate_short);
   8.276 -                if (new_rate_short == 0)
   8.277 -                {
   8.278 -                   SDL_SetError("VOC sample rate is zero");
   8.279 -                   return 0;
   8.280 -                }
   8.281 -                if ((v->rate != -1) && (new_rate_short != v->rate))
   8.282 -                {
   8.283 -                   SDL_SetError("VOC sample rate codes differ");
   8.284 -                   return 0;
   8.285 -                }
   8.286 -                v->rate = new_rate_short;
   8.287 -
   8.288 -                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   8.289 -                    return 0;
   8.290 -
   8.291 -                if (uc != 0)
   8.292 -                {
   8.293 -                    SDL_SetError("VOC decoder only interprets 8-bit data");
   8.294 -                    return 0;
   8.295 -                }
   8.296 -
   8.297 -                if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
   8.298 -                    return 0;
   8.299 -
   8.300 -                if (uc)
   8.301 -                    spec->channels = 2;  /* Stereo */
   8.302 -                /* Needed number of channels before finishing
   8.303 -                   compute for rate */
   8.304 -                spec->freq = (256000000L/(65536L - v->rate))/spec->channels;
   8.305 -                /* An extended block must be followed by a data */
   8.306 -                /* block to be valid so loop back to top so it  */
   8.307 -                /* can be grabed.                */
   8.308 -                continue;
   8.309 -
   8.310 -            case VOC_MARKER:
   8.311 -                if (SDL_RWread(src, trash, sizeof (Uint8), 2) != 2)
   8.312 -                    return 0;
   8.313 -
   8.314 -                /* Falling! Falling! */
   8.315 -
   8.316 -            default:  /* text block or other krapola. */
   8.317 -                for(i = 0; i < sblen; i++)
   8.318 -                {
   8.319 -                    if (SDL_RWread(src, &trash, sizeof (Uint8), 1) != 1)
   8.320 -                        return 0;
   8.321 -                }
   8.322 -
   8.323 -                if (block == VOC_TEXT)
   8.324 -                    continue;    /* get next block */
   8.325 -        }
   8.326 -    }
   8.327 -
   8.328 -    return 1;
   8.329 -}
   8.330 -
   8.331 -
   8.332 -static int voc_read(SDL_RWops *src, vs_t *v, Uint8 *buf, SDL_AudioSpec *spec)
   8.333 -{
   8.334 -    int done = 0;
   8.335 -    Uint8 silence = 0x80;
   8.336 -
   8.337 -    if (v->rest == 0)
   8.338 -    {
   8.339 -        if (!voc_get_block(src, v, spec))
   8.340 -            return 0;
   8.341 -    }
   8.342 -
   8.343 -    if (v->rest == 0)
   8.344 -        return 0;
   8.345 -
   8.346 -    if (v->silent)
   8.347 -    {
   8.348 -        if (v->size == ST_SIZE_WORD)
   8.349 -            silence = 0x00;
   8.350 -
   8.351 -        /* Fill in silence */
   8.352 -        memset(buf, silence, v->rest);
   8.353 -        done = v->rest;
   8.354 -        v->rest = 0;
   8.355 -    }
   8.356 -
   8.357 -    else
   8.358 -    {
   8.359 -        done = SDL_RWread(src, buf, 1, v->rest);
   8.360 -        v->rest -= done;
   8.361 -        if (v->size == ST_SIZE_WORD)
   8.362 -        {
   8.363 -            done >>= 1;
   8.364 -            #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
   8.365 -                for (; v->rest > 0; v->rest -= 2)
   8.366 -                {
   8.367 -                    *((Uint16 *) buf) = SDL_SwapLE16(*((Uint16 *) buf));
   8.368 -                    ((Uint16 *) buf)++;
   8.369 -                }
   8.370 -            #endif
   8.371 -        }
   8.372 -    }
   8.373 -
   8.374 -    return done;
   8.375 -} /* voc_read */
   8.376 -
   8.377 -
   8.378 -/* don't call this directly; use Mix_LoadWAV_RW() for now. */
   8.379 -SDL_AudioSpec *Mix_LoadVOC_RW (SDL_RWops *src, int freesrc,
   8.380 -        SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
   8.381 -{
   8.382 -    vs_t v;
   8.383 -    int was_error = 1;
   8.384 -    int samplesize;
   8.385 -    Uint8 *fillptr;
   8.386 -    void *ptr;
   8.387 -
   8.388 -    if ( (!src) || (!audio_buf) || (!audio_len) )   /* sanity checks. */
   8.389 -        goto done;
   8.390 -
   8.391 -    if ( !voc_check_header(src) )
   8.392 -        goto done;
   8.393 -
   8.394 -    v.rate = -1;
   8.395 -    v.rest = 0;
   8.396 -    v.extended = 0;
   8.397 -    *audio_buf = NULL;
   8.398 -    *audio_len = 0;
   8.399 -    memset(spec, '\0', sizeof (SDL_AudioSpec));
   8.400 -
   8.401 -    if (!voc_get_block(src, &v, spec))
   8.402 -        goto done;
   8.403 -
   8.404 -    if (v.rate == -1)
   8.405 -    {
   8.406 -        SDL_SetError("VOC data had no sound!");
   8.407 -        goto done;
   8.408 -    }
   8.409 -
   8.410 -    spec->format = ((v.size == ST_SIZE_WORD) ? AUDIO_S16 : AUDIO_U8);
   8.411 -    if (spec->channels == 0)
   8.412 -        spec->channels = v.channels;
   8.413 -
   8.414 -    *audio_len = v.rest;
   8.415 -    *audio_buf = malloc(v.rest);
   8.416 -    if (*audio_buf == NULL)
   8.417 -        goto done;
   8.418 -
   8.419 -    fillptr = *audio_buf;
   8.420 -
   8.421 -    while (voc_read(src, &v, fillptr, spec) > 0)
   8.422 -    {
   8.423 -        if (!voc_get_block(src, &v, spec))
   8.424 -            goto done;
   8.425 -
   8.426 -        *audio_len += v.rest;
   8.427 -        ptr = realloc(*audio_buf, *audio_len);
   8.428 -        if (ptr == NULL)
   8.429 -        {
   8.430 -            free(*audio_buf);
   8.431 -            *audio_buf = NULL;
   8.432 -            *audio_len = 0;
   8.433 -            goto done;
   8.434 -        }
   8.435 -
   8.436 -        *audio_buf = ptr;
   8.437 -        fillptr = ((Uint8 *) ptr) + (*audio_len - v.rest);
   8.438 -    }
   8.439 -
   8.440 -    spec->samples = (*audio_len / v.size);
   8.441 -
   8.442 -    was_error = 0;  /* success, baby! */
   8.443 -
   8.444 -    /* Don't return a buffer that isn't a multiple of samplesize */
   8.445 -    samplesize = ((spec->format & 0xFF)/8)*spec->channels;
   8.446 -    *audio_len &= ~(samplesize-1);
   8.447 -
   8.448 -done:
   8.449 -    if (src)
   8.450 -    {
   8.451 -        if (freesrc)
   8.452 -            SDL_RWclose(src);
   8.453 -        else
   8.454 -            SDL_RWseek(src, 0, SEEK_SET);
   8.455 -    }
   8.456 -
   8.457 -    if ( was_error )
   8.458 -        spec = NULL;
   8.459 -
   8.460 -    return(spec);
   8.461 -} /* Mix_LoadVOC_RW */
   8.462 -
   8.463 -#endif /* VOC_SAMPLES */
   8.464 -
   8.465 -/* end of voc.c ... */
   8.466 -
     9.1 --- a/wave.h	Fri Sep 07 01:06:20 2001 +0000
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,51 +0,0 @@
     9.4 -/*
     9.5 -    Taken with permission from SDL_wave.h, part of the SDL library,
     9.6 -    available at: http://www.devolution.com/~slouken/SDL 
     9.7 -    and placed under the same license as this mixer library.
     9.8 -*/
     9.9 -
    9.10 -/* WAVE files are little-endian */
    9.11 -
    9.12 -/*******************************************/
    9.13 -/* Define values for Microsoft WAVE format */
    9.14 -/*******************************************/
    9.15 -#define RIFF		0x46464952		/* "RIFF" */
    9.16 -#define WAVE		0x45564157		/* "WAVE" */
    9.17 -#define FACT		0x74636166		/* "fact" */
    9.18 -#define LIST		0x5453494c		/* "LIST" */
    9.19 -#define FMT		0x20746D66		/* "fmt " */
    9.20 -#define DATA		0x61746164		/* "data" */
    9.21 -#define PCM_CODE	1
    9.22 -#define ADPCM_CODE	2
    9.23 -#define WAVE_MONO	1
    9.24 -#define WAVE_STEREO	2
    9.25 -
    9.26 -/* Normally, these three chunks come consecutively in a WAVE file */
    9.27 -typedef struct WaveFMT {
    9.28 -/* Not saved in the chunk we read:
    9.29 -	Uint32	FMTchunk;
    9.30 -	Uint32	fmtlen;
    9.31 -*/
    9.32 -	Uint16	encoding;	
    9.33 -	Uint16	channels;		/* 1 = mono, 2 = stereo */
    9.34 -	Uint32	frequency;		/* One of 11025, 22050, or 44100 Hz */
    9.35 -	Uint32	byterate;		/* Average bytes per second */
    9.36 -	Uint16	blockalign;		/* Bytes per sample block */
    9.37 -	Uint16	bitspersample;		/* One of 8, 12, 16, or 4 for ADPCM */
    9.38 -} WaveFMT;
    9.39 -
    9.40 -/* The general chunk found in the WAVE file */
    9.41 -typedef struct Chunk {
    9.42 -	Uint32 magic;
    9.43 -	Uint32 length;
    9.44 -	Uint8 *data;			/* Data includes magic and length */
    9.45 -} Chunk;
    9.46 -
    9.47 -/*********************************************/
    9.48 -/* Define values for AIFF (IFF audio) format */
    9.49 -/*********************************************/
    9.50 -#define FORM		0x4d524f46		/* "FORM" */
    9.51 -#define AIFF		0x46464941		/* "AIFF" */
    9.52 -#define SSND		0x444e5353		/* "SSND" */
    9.53 -#define COMM		0x4d4d4f43		/* "COMM" */
    9.54 -
    10.1 --- a/wavestream.c	Fri Sep 07 01:06:20 2001 +0000
    10.2 +++ b/wavestream.c	Tue Sep 11 18:24:38 2001 +0000
    10.3 @@ -32,9 +32,60 @@
    10.4  #include "SDL_rwops.h"
    10.5  #include "SDL_endian.h"
    10.6  
    10.7 -#include "wave.h"
    10.8  #include "wavestream.h"
    10.9  
   10.10 +/*
   10.11 +    Taken with permission from SDL_wave.h, part of the SDL library,
   10.12 +    available at: http://www.libsdl.org/
   10.13 +    and placed under the same license as this mixer library.
   10.14 +*/
   10.15 +
   10.16 +/* WAVE files are little-endian */
   10.17 +
   10.18 +/*******************************************/
   10.19 +/* Define values for Microsoft WAVE format */
   10.20 +/*******************************************/
   10.21 +#define RIFF		0x46464952		/* "RIFF" */
   10.22 +#define WAVE		0x45564157		/* "WAVE" */
   10.23 +#define FACT		0x74636166		/* "fact" */
   10.24 +#define LIST		0x5453494c		/* "LIST" */
   10.25 +#define FMT		0x20746D66		/* "fmt " */
   10.26 +#define DATA		0x61746164		/* "data" */
   10.27 +#define PCM_CODE	1
   10.28 +#define ADPCM_CODE	2
   10.29 +#define WAVE_MONO	1
   10.30 +#define WAVE_STEREO	2
   10.31 +
   10.32 +/* Normally, these three chunks come consecutively in a WAVE file */
   10.33 +typedef struct WaveFMT {
   10.34 +/* Not saved in the chunk we read:
   10.35 +	Uint32	FMTchunk;
   10.36 +	Uint32	fmtlen;
   10.37 +*/
   10.38 +	Uint16	encoding;	
   10.39 +	Uint16	channels;		/* 1 = mono, 2 = stereo */
   10.40 +	Uint32	frequency;		/* One of 11025, 22050, or 44100 Hz */
   10.41 +	Uint32	byterate;		/* Average bytes per second */
   10.42 +	Uint16	blockalign;		/* Bytes per sample block */
   10.43 +	Uint16	bitspersample;		/* One of 8, 12, 16, or 4 for ADPCM */
   10.44 +} WaveFMT;
   10.45 +
   10.46 +/* The general chunk found in the WAVE file */
   10.47 +typedef struct Chunk {
   10.48 +	Uint32 magic;
   10.49 +	Uint32 length;
   10.50 +	Uint8 *data;			/* Data includes magic and length */
   10.51 +} Chunk;
   10.52 +
   10.53 +/*********************************************/
   10.54 +/* Define values for AIFF (IFF audio) format */
   10.55 +/*********************************************/
   10.56 +#define FORM		0x4d524f46		/* "FORM" */
   10.57 +#define AIFF		0x46464941		/* "AIFF" */
   10.58 +#define SSND		0x444e5353		/* "SSND" */
   10.59 +#define COMM		0x4d4d4f43		/* "COMM" */
   10.60 +
   10.61 +
   10.62  /* Currently we only support a single stream at a time */
   10.63  static WAVStream *theWave = NULL;
   10.64