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 +Torbjörn 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 Torbjörn 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 Torbjörn 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