/contrib/games/opentyrian/SDL/SDL_audiocvt.c |
---|
0,0 → 1,642 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_audiocvt.c,v 1.2 2001/04/26 16:50:17 hercules Exp $"; |
#endif |
/* Functions for audio drivers to perform runtime conversion of audio format */ |
#include <stdio.h> |
#include "SDL_error.h" |
#include "SDL_audio.h" |
/* Effectively mix right and left channels into a single channel */ |
void SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format) |
{ |
int i; |
Sint32 sample; |
#ifdef DEBUG_CONVERT |
fprintf(stderr, "Converting to mono\n"); |
#endif |
switch (format&0x8018) { |
case AUDIO_U8: { |
Uint8 *src, *dst; |
src = cvt->buf; |
dst = cvt->buf; |
for ( i=cvt->len_cvt/2; i; --i ) { |
sample = src[0] + src[1]; |
if ( sample > 255 ) { |
*dst = 255; |
} else { |
*dst = sample; |
} |
src += 2; |
dst += 1; |
} |
} |
break; |
case AUDIO_S8: { |
Sint8 *src, *dst; |
src = (Sint8 *)cvt->buf; |
dst = (Sint8 *)cvt->buf; |
for ( i=cvt->len_cvt/2; i; --i ) { |
sample = src[0] + src[1]; |
if ( sample > 127 ) { |
*dst = 127; |
} else |
if ( sample < -128 ) { |
*dst = -128; |
} else { |
*dst = sample; |
} |
src += 2; |
dst += 1; |
} |
} |
break; |
case AUDIO_U16: { |
Uint8 *src, *dst; |
src = cvt->buf; |
dst = cvt->buf; |
if ( (format & 0x1000) == 0x1000 ) { |
for ( i=cvt->len_cvt/4; i; --i ) { |
sample = (Uint16)((src[0]<<8)|src[1])+ |
(Uint16)((src[2]<<8)|src[3]); |
if ( sample > 65535 ) { |
dst[0] = 0xFF; |
dst[1] = 0xFF; |
} else { |
dst[1] = (sample&0xFF); |
sample >>= 8; |
dst[0] = (sample&0xFF); |
} |
src += 4; |
dst += 2; |
} |
} else { |
for ( i=cvt->len_cvt/4; i; --i ) { |
sample = (Uint16)((src[1]<<8)|src[0])+ |
(Uint16)((src[3]<<8)|src[2]); |
if ( sample > 65535 ) { |
dst[0] = 0xFF; |
dst[1] = 0xFF; |
} else { |
dst[0] = (sample&0xFF); |
sample >>= 8; |
dst[1] = (sample&0xFF); |
} |
src += 4; |
dst += 2; |
} |
} |
} |
break; |
case AUDIO_S16: { |
Uint8 *src, *dst; |
src = cvt->buf; |
dst = cvt->buf; |
if ( (format & 0x1000) == 0x1000 ) { |
for ( i=cvt->len_cvt/4; i; --i ) { |
sample = (Sint16)((src[0]<<8)|src[1])+ |
(Sint16)((src[2]<<8)|src[3]); |
if ( sample > 32767 ) { |
dst[0] = 0x7F; |
dst[1] = 0xFF; |
} else |
if ( sample < -32768 ) { |
dst[0] = 0x80; |
dst[1] = 0x00; |
} else { |
dst[1] = (sample&0xFF); |
sample >>= 8; |
dst[0] = (sample&0xFF); |
} |
src += 4; |
dst += 2; |
} |
} else { |
for ( i=cvt->len_cvt/4; i; --i ) { |
sample = (Sint16)((src[1]<<8)|src[0])+ |
(Sint16)((src[3]<<8)|src[2]); |
if ( sample > 32767 ) { |
dst[1] = 0x7F; |
dst[0] = 0xFF; |
} else |
if ( sample < -32768 ) { |
dst[1] = 0x80; |
dst[0] = 0x00; |
} else { |
dst[0] = (sample&0xFF); |
sample >>= 8; |
dst[1] = (sample&0xFF); |
} |
src += 4; |
dst += 2; |
} |
} |
} |
break; |
} |
cvt->len_cvt /= 2; |
if ( cvt->filters[++cvt->filter_index] ) { |
cvt->filters[cvt->filter_index](cvt, format); |
} |
} |
/* Duplicate a mono channel to both stereo channels */ |
void SDL_ConvertStereo(SDL_AudioCVT *cvt, Uint16 format) |
{ |
int i; |
#ifdef DEBUG_CONVERT |
fprintf(stderr, "Converting to stereo\n"); |
#endif |
if ( (format & 0xFF) == 16 ) { |
Uint16 *src, *dst; |
src = (Uint16 *)(cvt->buf+cvt->len_cvt); |
dst = (Uint16 *)(cvt->buf+cvt->len_cvt*2); |
for ( i=cvt->len_cvt/2; i; --i ) { |
dst -= 2; |
src -= 1; |
dst[0] = src[0]; |
dst[1] = src[0]; |
} |
} else { |
Uint8 *src, *dst; |
src = cvt->buf+cvt->len_cvt; |
dst = cvt->buf+cvt->len_cvt*2; |
for ( i=cvt->len_cvt; i; --i ) { |
dst -= 2; |
src -= 1; |
dst[0] = src[0]; |
dst[1] = src[0]; |
} |
} |
cvt->len_cvt *= 2; |
if ( cvt->filters[++cvt->filter_index] ) { |
cvt->filters[cvt->filter_index](cvt, format); |
} |
} |
/* Convert 8-bit to 16-bit - LSB */ |
void SDL_Convert16LSB(SDL_AudioCVT *cvt, Uint16 format) |
{ |
int i; |
Uint8 *src, *dst; |
#ifdef DEBUG_CONVERT |
fprintf(stderr, "Converting to 16-bit LSB\n"); |
#endif |
src = cvt->buf+cvt->len_cvt; |
dst = cvt->buf+cvt->len_cvt*2; |
for ( i=cvt->len_cvt; i; --i ) { |
src -= 1; |
dst -= 2; |
dst[1] = *src; |
dst[0] = 0; |
} |
format = ((format & ~0x0008) | AUDIO_U16LSB); |
cvt->len_cvt *= 2; |
if ( cvt->filters[++cvt->filter_index] ) { |
cvt->filters[cvt->filter_index](cvt, format); |
} |
} |
/* Convert 8-bit to 16-bit - MSB */ |
void SDL_Convert16MSB(SDL_AudioCVT *cvt, Uint16 format) |
{ |
int i; |
Uint8 *src, *dst; |
#ifdef DEBUG_CONVERT |
fprintf(stderr, "Converting to 16-bit MSB\n"); |
#endif |
src = cvt->buf+cvt->len_cvt; |
dst = cvt->buf+cvt->len_cvt*2; |
for ( i=cvt->len_cvt; i; --i ) { |
src -= 1; |
dst -= 2; |
dst[0] = *src; |
dst[1] = 0; |
} |
format = ((format & ~0x0008) | AUDIO_U16MSB); |
cvt->len_cvt *= 2; |
if ( cvt->filters[++cvt->filter_index] ) { |
cvt->filters[cvt->filter_index](cvt, format); |
} |
} |
/* Convert 16-bit to 8-bit */ |
void SDL_Convert8(SDL_AudioCVT *cvt, Uint16 format) |
{ |
int i; |
Uint8 *src, *dst; |
#ifdef DEBUG_CONVERT |
fprintf(stderr, "Converting to 8-bit\n"); |
#endif |
src = cvt->buf; |
dst = cvt->buf; |
if ( (format & 0x1000) != 0x1000 ) { /* Little endian */ |
++src; |
} |
for ( i=cvt->len_cvt/2; i; --i ) { |
*dst = *src; |
src += 2; |
dst += 1; |
} |
format = ((format & ~0x9010) | AUDIO_U8); |
cvt->len_cvt /= 2; |
if ( cvt->filters[++cvt->filter_index] ) { |
cvt->filters[cvt->filter_index](cvt, format); |
} |
} |
/* Toggle signed/unsigned */ |
void SDL_ConvertSign(SDL_AudioCVT *cvt, Uint16 format) |
{ |
int i; |
Uint8 *data; |
#ifdef DEBUG_CONVERT |
fprintf(stderr, "Converting audio signedness\n"); |
#endif |
data = cvt->buf; |
if ( (format & 0xFF) == 16 ) { |
if ( (format & 0x1000) != 0x1000 ) { /* Little endian */ |
++data; |
} |
for ( i=cvt->len_cvt/2; i; --i ) { |
*data ^= 0x80; |
data += 2; |
} |
} else { |
for ( i=cvt->len_cvt; i; --i ) { |
*data++ ^= 0x80; |
} |
} |
format = (format ^ 0x8000); |
if ( cvt->filters[++cvt->filter_index] ) { |
cvt->filters[cvt->filter_index](cvt, format); |
} |
} |
/* Toggle endianness */ |
void SDL_ConvertEndian(SDL_AudioCVT *cvt, Uint16 format) |
{ |
int i; |
Uint8 *data, tmp; |
#ifdef DEBUG_CONVERT |
fprintf(stderr, "Converting audio endianness\n"); |
#endif |
data = cvt->buf; |
for ( i=cvt->len_cvt/2; i; --i ) { |
tmp = data[0]; |
data[0] = data[1]; |
data[1] = tmp; |
data += 2; |
} |
format = (format ^ 0x1000); |
if ( cvt->filters[++cvt->filter_index] ) { |
cvt->filters[cvt->filter_index](cvt, format); |
} |
} |
/* Convert rate up by multiple of 2 */ |
void SDL_RateMUL2(SDL_AudioCVT *cvt, Uint16 format) |
{ |
int i; |
Uint8 *src, *dst; |
#ifdef DEBUG_CONVERT |
fprintf(stderr, "Converting audio rate * 2\n"); |
#endif |
src = cvt->buf+cvt->len_cvt; |
dst = cvt->buf+cvt->len_cvt*2; |
switch (format & 0xFF) { |
case 8: |
for ( i=cvt->len_cvt; i; --i ) { |
src -= 1; |
dst -= 2; |
dst[0] = src[0]; |
dst[1] = src[0]; |
} |
break; |
case 16: |
for ( i=cvt->len_cvt/2; i; --i ) { |
src -= 2; |
dst -= 4; |
dst[0] = src[0]; |
dst[1] = src[1]; |
dst[2] = src[0]; |
dst[3] = src[1]; |
} |
break; |
} |
cvt->len_cvt *= 2; |
if ( cvt->filters[++cvt->filter_index] ) { |
cvt->filters[cvt->filter_index](cvt, format); |
} |
} |
/* Convert rate down by multiple of 2 */ |
void SDL_RateDIV2(SDL_AudioCVT *cvt, Uint16 format) |
{ |
int i; |
Uint8 *src, *dst; |
#ifdef DEBUG_CONVERT |
fprintf(stderr, "Converting audio rate / 2\n"); |
#endif |
src = cvt->buf; |
dst = cvt->buf; |
switch (format & 0xFF) { |
case 8: |
for ( i=cvt->len_cvt/2; i; --i ) { |
dst[0] = src[0]; |
src += 2; |
dst += 1; |
} |
break; |
case 16: |
for ( i=cvt->len_cvt/4; i; --i ) { |
dst[0] = src[0]; |
dst[1] = src[1]; |
src += 4; |
dst += 2; |
} |
break; |
} |
cvt->len_cvt /= 2; |
if ( cvt->filters[++cvt->filter_index] ) { |
cvt->filters[cvt->filter_index](cvt, format); |
} |
} |
/* Very slow rate conversion routine */ |
void SDL_RateSLOW(SDL_AudioCVT *cvt, Uint16 format) |
{ |
double ipos; |
int i, clen; |
#ifdef DEBUG_CONVERT |
fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0/cvt->rate_incr); |
#endif |
clen = (int)((double)cvt->len_cvt / cvt->rate_incr); |
if ( cvt->rate_incr > 1.0 ) { |
switch (format & 0xFF) { |
case 8: { |
Uint8 *output; |
output = cvt->buf; |
ipos = 0.0; |
for ( i=clen; i; --i ) { |
*output = cvt->buf[(int)ipos]; |
ipos += cvt->rate_incr; |
output += 1; |
} |
} |
break; |
case 16: { |
Uint16 *output; |
clen &= ~1; |
output = (Uint16 *)cvt->buf; |
ipos = 0.0; |
for ( i=clen/2; i; --i ) { |
*output=((Uint16 *)cvt->buf)[(int)ipos]; |
ipos += cvt->rate_incr; |
output += 1; |
} |
} |
break; |
} |
} else { |
switch (format & 0xFF) { |
case 8: { |
Uint8 *output; |
output = cvt->buf+clen; |
ipos = (double)cvt->len_cvt; |
for ( i=clen; i; --i ) { |
ipos -= cvt->rate_incr; |
output -= 1; |
*output = cvt->buf[(int)ipos]; |
} |
} |
break; |
case 16: { |
Uint16 *output; |
clen &= ~1; |
output = (Uint16 *)(cvt->buf+clen); |
ipos = (double)cvt->len_cvt/2; |
for ( i=clen/2; i; --i ) { |
ipos -= cvt->rate_incr; |
output -= 1; |
*output=((Uint16 *)cvt->buf)[(int)ipos]; |
} |
} |
break; |
} |
} |
cvt->len_cvt = clen; |
if ( cvt->filters[++cvt->filter_index] ) { |
cvt->filters[cvt->filter_index](cvt, format); |
} |
} |
int SDL_ConvertAudio(SDL_AudioCVT *cvt) |
{ |
/* Make sure there's data to convert */ |
if ( cvt->buf == NULL ) { |
SDL_SetError("No buffer allocated for conversion"); |
return(-1); |
} |
/* Return okay if no conversion is necessary */ |
cvt->len_cvt = cvt->len; |
if ( cvt->filters[0] == NULL ) { |
return(0); |
} |
/* Set up the conversion and go! */ |
cvt->filter_index = 0; |
cvt->filters[0](cvt, cvt->src_format); |
return(0); |
} |
/* Creates a set of audio filters to convert from one format to another. |
Returns -1 if the format conversion is not supported, or 1 if the |
audio filter is set up. |
*/ |
int SDL_BuildAudioCVT(SDL_AudioCVT *cvt, |
Uint16 src_format, Uint8 src_channels, int src_rate, |
Uint16 dst_format, Uint8 dst_channels, int dst_rate) |
{ |
/* Start off with no conversion necessary */ |
cvt->needed = 0; |
cvt->filter_index = 0; |
cvt->filters[0] = NULL; |
cvt->len_mult = 1; |
cvt->len_ratio = 1.0; |
/* First filter: Endian conversion from src to dst */ |
if ( (src_format & 0x1000) != (dst_format & 0x1000) |
&& ((src_format & 0xff) != 8) ) { |
cvt->filters[cvt->filter_index++] = SDL_ConvertEndian; |
} |
/* Second filter: Sign conversion -- signed/unsigned */ |
if ( (src_format & 0x8000) != (dst_format & 0x8000) ) { |
cvt->filters[cvt->filter_index++] = SDL_ConvertSign; |
} |
/* Next filter: Convert 16 bit <--> 8 bit PCM */ |
if ( (src_format & 0xFF) != (dst_format & 0xFF) ) { |
switch (dst_format&0x10FF) { |
case AUDIO_U8: |
cvt->filters[cvt->filter_index++] = |
SDL_Convert8; |
cvt->len_ratio /= 2; |
break; |
case AUDIO_U16LSB: |
cvt->filters[cvt->filter_index++] = |
SDL_Convert16LSB; |
cvt->len_mult *= 2; |
cvt->len_ratio *= 2; |
break; |
case AUDIO_U16MSB: |
cvt->filters[cvt->filter_index++] = |
SDL_Convert16MSB; |
cvt->len_mult *= 2; |
cvt->len_ratio *= 2; |
break; |
} |
} |
/* Last filter: Mono/Stereo conversion */ |
if ( src_channels != dst_channels ) { |
while ( (src_channels*2) <= dst_channels ) { |
cvt->filters[cvt->filter_index++] = |
SDL_ConvertStereo; |
cvt->len_mult *= 2; |
src_channels *= 2; |
cvt->len_ratio *= 2; |
} |
/* This assumes that 4 channel audio is in the format: |
Left {front/back} + Right {front/back} |
so converting to L/R stereo works properly. |
*/ |
while ( ((src_channels%2) == 0) && |
((src_channels/2) >= dst_channels) ) { |
cvt->filters[cvt->filter_index++] = |
SDL_ConvertMono; |
src_channels /= 2; |
cvt->len_ratio /= 2; |
} |
if ( src_channels != dst_channels ) { |
/* Uh oh.. */; |
} |
} |
/* Do rate conversion */ |
cvt->rate_incr = 0.0; |
if ( (src_rate/100) != (dst_rate/100) ) { |
Uint32 hi_rate, lo_rate; |
int len_mult; |
double len_ratio; |
void (*rate_cvt)(SDL_AudioCVT *cvt, Uint16 format); |
if ( src_rate > dst_rate ) { |
hi_rate = src_rate; |
lo_rate = dst_rate; |
rate_cvt = SDL_RateDIV2; |
len_mult = 1; |
len_ratio = 0.5; |
} else { |
hi_rate = dst_rate; |
lo_rate = src_rate; |
rate_cvt = SDL_RateMUL2; |
len_mult = 2; |
len_ratio = 2.0; |
} |
/* If hi_rate = lo_rate*2^x then conversion is easy */ |
while ( ((lo_rate*2)/100) <= (hi_rate/100) ) { |
cvt->filters[cvt->filter_index++] = rate_cvt; |
cvt->len_mult *= len_mult; |
lo_rate *= 2; |
cvt->len_ratio *= len_ratio; |
} |
/* We may need a slow conversion here to finish up */ |
if ( (lo_rate/100) != (hi_rate/100) ) { |
#if 1 |
/* The problem with this is that if the input buffer is |
say 1K, and the conversion rate is say 1.1, then the |
output buffer is 1.1K, which may not be an acceptable |
buffer size for the audio driver (not a power of 2) |
*/ |
/* For now, punt and hope the rate distortion isn't great. |
*/ |
#else |
if ( src_rate < dst_rate ) { |
cvt->rate_incr = (double)lo_rate/hi_rate; |
cvt->len_mult *= 2; |
cvt->len_ratio /= cvt->rate_incr; |
} else { |
cvt->rate_incr = (double)hi_rate/lo_rate; |
cvt->len_ratio *= cvt->rate_incr; |
} |
cvt->filters[cvt->filter_index++] = SDL_RateSLOW; |
#endif |
} |
} |
/* Set up the filter information */ |
if ( cvt->filter_index != 0 ) { |
cvt->needed = 1; |
cvt->src_format = src_format; |
cvt->dst_format = dst_format; |
cvt->len = 0; |
cvt->buf = NULL; |
cvt->filters[cvt->filter_index] = NULL; |
} |
return(cvt->needed); |
} |
/contrib/games/opentyrian/SDL/SDL_mixer.c |
---|
0,0 → 1,218 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_mixer.c,v 1.2 2001/04/26 16:50:17 hercules Exp $"; |
#endif |
/* This provides the default mixing callback for the SDL audio routines */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_audio.h" |
#include "SDL_mutex.h" |
#include "SDL_timer.h" |
#include "SDL_sysaudio.h" |
SDL_AudioDevice *current_audio = NULL; |
/* This table is used to add two sound values together and pin |
* the value to avoid overflow. (used with permission from ARDI) |
* Changed to use 0xFE instead of 0xFF for better sound quality. |
*/ |
static const Uint8 mix8[] = |
{ |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, |
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, |
0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, |
0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, |
0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, |
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, |
0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, |
0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, |
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, |
0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, |
0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, |
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, |
0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, |
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, |
0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, |
0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, |
0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, |
0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, |
0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, |
0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, |
0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, |
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, |
0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, |
0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, |
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE |
}; |
/* The volume ranges from 0 - 128 */ |
#define ADJUST_VOLUME(s, v) (s = (s*v)/SDL_MIX_MAXVOLUME) |
#define ADJUST_VOLUME_U8(s, v) (s = (((s-128)*v)/SDL_MIX_MAXVOLUME)+128) |
void SDL_MixAudio (Uint8 *dst, const Uint8 *src, Uint32 len, int volume) |
{ |
Uint16 format; |
if ( volume == 0 ) { |
return; |
} |
/* Mix the user-level audio format */ |
if ( current_audio ) { |
if ( current_audio->convert.needed ) { |
format = current_audio->convert.src_format; |
} else { |
format = current_audio->spec.format; |
} |
} else { |
format = AUDIO_S16; |
} |
format = AUDIO_S16; |
switch (format) { |
case AUDIO_U8: { |
Uint8 src_sample; |
while ( len-- ) { |
src_sample = *src; |
ADJUST_VOLUME_U8(src_sample, volume); |
*dst = mix8[*dst+src_sample]; |
++dst; |
++src; |
} |
} |
break; |
case AUDIO_S8: { |
Sint8 *dst8, *src8; |
Sint8 src_sample; |
int dst_sample; |
const int max_audioval = ((1<<(8-1))-1); |
const int min_audioval = -(1<<(8-1)); |
src8 = (Sint8 *)src; |
dst8 = (Sint8 *)dst; |
while ( len-- ) { |
src_sample = *src8; |
ADJUST_VOLUME(src_sample, volume); |
dst_sample = *dst8 + src_sample; |
if ( dst_sample > max_audioval ) { |
*dst8 = max_audioval; |
} else |
if ( dst_sample < min_audioval ) { |
*dst8 = min_audioval; |
} else { |
*dst8 = dst_sample; |
} |
++dst8; |
++src8; |
} |
} |
break; |
case AUDIO_S16LSB: { |
Sint16 src1, src2; |
int dst_sample; |
const int max_audioval = ((1<<(16-1))-1); |
const int min_audioval = -(1<<(16-1)); |
len /= 2; |
while ( len-- ) { |
src1 = ((src[1])<<8|src[0]); |
ADJUST_VOLUME(src1, volume); |
src2 = ((dst[1])<<8|dst[0]); |
src += 2; |
dst_sample = src1+src2; |
if ( dst_sample > max_audioval ) { |
dst_sample = max_audioval; |
} else |
if ( dst_sample < min_audioval ) { |
dst_sample = min_audioval; |
} |
dst[0] = dst_sample&0xFF; |
dst_sample >>= 8; |
dst[1] = dst_sample&0xFF; |
dst += 2; |
} |
} |
break; |
case AUDIO_S16MSB: { |
Sint16 src1, src2; |
int dst_sample; |
const int max_audioval = ((1<<(16-1))-1); |
const int min_audioval = -(1<<(16-1)); |
len /= 2; |
while ( len-- ) { |
src1 = ((src[0])<<8|src[1]); |
ADJUST_VOLUME(src1, volume); |
src2 = ((dst[0])<<8|dst[1]); |
src += 2; |
dst_sample = src1+src2; |
if ( dst_sample > max_audioval ) { |
dst_sample = max_audioval; |
} else |
if ( dst_sample < min_audioval ) { |
dst_sample = min_audioval; |
} |
dst[1] = dst_sample&0xFF; |
dst_sample >>= 8; |
dst[0] = dst_sample&0xFF; |
dst += 2; |
} |
} |
break; |
default: /* If this happens... FIXME! */ |
SDL_SetError("SDL_MixAudio(): unknown audio format"); |
return; |
} |
} |
/contrib/games/opentyrian/SDL/SDL_sysaudio.h |
---|
0,0 → 1,150 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_sysaudio.h,v 1.8 2001/07/23 02:58:42 slouken Exp $"; |
#endif |
#ifndef _SDL_sysaudio_h |
#define _SDL_sysaudio_h |
#include "SDL_mutex.h" |
#include "SDL_thread.h" |
/* The SDL audio driver */ |
typedef struct SDL_AudioDevice SDL_AudioDevice; |
/* Define the SDL audio driver structure */ |
#define _THIS SDL_AudioDevice *_this |
#ifndef _STATUS |
#define _STATUS SDL_status *status |
#endif |
struct SDL_AudioDevice { |
/* * * */ |
/* The name of this audio driver */ |
const char *name; |
/* * * */ |
/* The description of this audio driver */ |
const char *desc; |
/* * * */ |
/* Public driver functions */ |
int (*OpenAudio)(_THIS, SDL_AudioSpec *spec); |
void (*ThreadInit)(_THIS); /* Called by audio thread at start */ |
void (*WaitAudio)(_THIS); |
void (*PlayAudio)(_THIS); |
Uint8 *(*GetAudioBuf)(_THIS); |
void (*WaitDone)(_THIS); |
void (*CloseAudio)(_THIS); |
/* * * */ |
/* Data common to all devices */ |
/* The current audio specification (shared with audio thread) */ |
SDL_AudioSpec spec; |
/* An audio conversion block for audio format emulation */ |
SDL_AudioCVT convert; |
/* Current state flags */ |
int enabled; |
int paused; |
int opened; |
/* Fake audio buffer for when the audio hardware is busy */ |
Uint8 *fake_stream; |
/* A semaphore for locking the mixing buffers */ |
SDL_mutex *mixer_lock; |
/* A thread to feed the audio device */ |
SDL_Thread *thread; |
Uint32 threadid; |
/* * * */ |
/* Data private to this driver */ |
struct SDL_PrivateAudioData *hidden; |
/* * * */ |
/* The function used to dispose of this structure */ |
void (*free)(_THIS); |
}; |
#undef _THIS |
typedef struct AudioBootStrap { |
const char *name; |
const char *desc; |
int (*available)(void); |
SDL_AudioDevice *(*create)(int devindex); |
} AudioBootStrap; |
#ifdef OPENBSD_AUDIO_SUPPORT |
extern AudioBootStrap OPENBSD_AUDIO_bootstrap; |
#endif |
#ifdef OSS_SUPPORT |
extern AudioBootStrap DSP_bootstrap; |
extern AudioBootStrap DMA_bootstrap; |
#endif |
#ifdef ALSA_SUPPORT |
extern AudioBootStrap ALSA_bootstrap; |
#endif |
#if (defined(unix) && !defined(__CYGWIN32__)) && \ |
!defined(OSS_SUPPORT) && !defined(ALSA_SUPPORT) |
extern AudioBootStrap AUDIO_bootstrap; |
#endif |
#ifdef ARTSC_SUPPORT |
extern AudioBootStrap ARTSC_bootstrap; |
#endif |
#ifdef ESD_SUPPORT |
extern AudioBootStrap ESD_bootstrap; |
#endif |
#ifdef NAS_SUPPORT |
extern AudioBootStrap NAS_bootstrap; |
#endif |
#ifdef ENABLE_DIRECTX |
extern AudioBootStrap DSOUND_bootstrap; |
#endif |
#ifdef ENABLE_WINDIB |
extern AudioBootStrap WAVEOUT_bootstrap; |
#endif |
#ifdef _AIX |
extern AudioBootStrap Paud_bootstrap; |
#endif |
#ifdef __BEOS__ |
extern AudioBootStrap BAUDIO_bootstrap; |
#endif |
#if defined(macintosh) || TARGET_API_MAC_CARBON |
extern AudioBootStrap SNDMGR_bootstrap; |
#endif |
#ifdef ENABLE_AHI |
extern AudioBootStrap AHI_bootstrap; |
#endif |
#ifdef DISKAUD_SUPPORT |
extern AudioBootStrap DISKAUD_bootstrap; |
#endif |
/* This is the current audio device */ |
extern SDL_AudioDevice *current_audio; |
#endif /* _SDL_sysaudio_h */ |
/contrib/games/opentyrian/SDL/SDL_wave.c |
---|
0,0 → 1,591 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_wave.c,v 1.2 2001/04/26 16:50:17 hercules Exp $"; |
#endif |
#ifndef DISABLE_FILE |
/* Microsoft WAVE file loading routines */ |
#include <stdlib.h> |
#include <string.h> |
#include "SDL_error.h" |
#include "SDL_audio.h" |
#include "SDL_wave.h" |
#include "SDL_endian.h" |
#ifndef NELEMS |
#define NELEMS(array) ((sizeof array)/(sizeof array[0])) |
#endif |
static int ReadChunk(SDL_RWops *src, Chunk *chunk); |
struct MS_ADPCM_decodestate { |
Uint8 hPredictor; |
Uint16 iDelta; |
Sint16 iSamp1; |
Sint16 iSamp2; |
}; |
static struct MS_ADPCM_decoder { |
WaveFMT wavefmt; |
Uint16 wSamplesPerBlock; |
Uint16 wNumCoef; |
Sint16 aCoeff[7][2]; |
/* * * */ |
struct MS_ADPCM_decodestate state[2]; |
} MS_ADPCM_state; |
static int InitMS_ADPCM(WaveFMT *format) |
{ |
Uint8 *rogue_feel; |
Uint16 extra_info; |
int i; |
/* Set the rogue pointer to the MS_ADPCM specific data */ |
MS_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding); |
MS_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels); |
MS_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency); |
MS_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate); |
MS_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign); |
MS_ADPCM_state.wavefmt.bitspersample = |
SDL_SwapLE16(format->bitspersample); |
rogue_feel = (Uint8 *)format+sizeof(*format); |
if ( sizeof(*format) == 16 ) { |
extra_info = ((rogue_feel[1]<<8)|rogue_feel[0]); |
rogue_feel += sizeof(Uint16); |
} |
MS_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]); |
rogue_feel += sizeof(Uint16); |
MS_ADPCM_state.wNumCoef = ((rogue_feel[1]<<8)|rogue_feel[0]); |
rogue_feel += sizeof(Uint16); |
if ( MS_ADPCM_state.wNumCoef != 7 ) { |
SDL_SetError("Unknown set of MS_ADPCM coefficients"); |
return(-1); |
} |
for ( i=0; i<MS_ADPCM_state.wNumCoef; ++i ) { |
MS_ADPCM_state.aCoeff[i][0] = ((rogue_feel[1]<<8)|rogue_feel[0]); |
rogue_feel += sizeof(Uint16); |
MS_ADPCM_state.aCoeff[i][1] = ((rogue_feel[1]<<8)|rogue_feel[0]); |
rogue_feel += sizeof(Uint16); |
} |
return(0); |
} |
static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state, |
Uint8 nybble, Sint16 *coeff) |
{ |
const Sint32 max_audioval = ((1<<(16-1))-1); |
const Sint32 min_audioval = -(1<<(16-1)); |
const Sint32 adaptive[] = { |
230, 230, 230, 230, 307, 409, 512, 614, |
768, 614, 512, 409, 307, 230, 230, 230 |
}; |
Sint32 new_sample, delta; |
new_sample = ((state->iSamp1 * coeff[0]) + |
(state->iSamp2 * coeff[1]))/256; |
if ( nybble & 0x08 ) { |
new_sample += state->iDelta * (nybble-0x10); |
} else { |
new_sample += state->iDelta * nybble; |
} |
if ( new_sample < min_audioval ) { |
new_sample = min_audioval; |
} else |
if ( new_sample > max_audioval ) { |
new_sample = max_audioval; |
} |
delta = ((Sint32)state->iDelta * adaptive[nybble])/256; |
if ( delta < 16 ) { |
delta = 16; |
} |
state->iDelta = delta; |
state->iSamp2 = state->iSamp1; |
state->iSamp1 = new_sample; |
return(new_sample); |
} |
static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) |
{ |
struct MS_ADPCM_decodestate *state[2]; |
Uint8 *freeable, *encoded, *decoded; |
Sint32 encoded_len, samplesleft; |
Sint8 nybble, stereo; |
Sint16 *coeff[2]; |
Sint32 new_sample; |
/* Allocate the proper sized output buffer */ |
encoded_len = *audio_len; |
encoded = *audio_buf; |
freeable = *audio_buf; |
*audio_len = (encoded_len/MS_ADPCM_state.wavefmt.blockalign) * |
MS_ADPCM_state.wSamplesPerBlock* |
MS_ADPCM_state.wavefmt.channels*sizeof(Sint16); |
*audio_buf = (Uint8 *)malloc(*audio_len); |
if ( *audio_buf == NULL ) { |
SDL_Error(SDL_ENOMEM); |
return(-1); |
} |
decoded = *audio_buf; |
/* Get ready... Go! */ |
stereo = (MS_ADPCM_state.wavefmt.channels == 2); |
state[0] = &MS_ADPCM_state.state[0]; |
state[1] = &MS_ADPCM_state.state[stereo]; |
while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) { |
/* Grab the initial information for this block */ |
state[0]->hPredictor = *encoded++; |
if ( stereo ) { |
state[1]->hPredictor = *encoded++; |
} |
state[0]->iDelta = ((encoded[1]<<8)|encoded[0]); |
encoded += sizeof(Sint16); |
if ( stereo ) { |
state[1]->iDelta = ((encoded[1]<<8)|encoded[0]); |
encoded += sizeof(Sint16); |
} |
state[0]->iSamp1 = ((encoded[1]<<8)|encoded[0]); |
encoded += sizeof(Sint16); |
if ( stereo ) { |
state[1]->iSamp1 = ((encoded[1]<<8)|encoded[0]); |
encoded += sizeof(Sint16); |
} |
state[0]->iSamp2 = ((encoded[1]<<8)|encoded[0]); |
encoded += sizeof(Sint16); |
if ( stereo ) { |
state[1]->iSamp2 = ((encoded[1]<<8)|encoded[0]); |
encoded += sizeof(Sint16); |
} |
coeff[0] = MS_ADPCM_state.aCoeff[state[0]->hPredictor]; |
coeff[1] = MS_ADPCM_state.aCoeff[state[1]->hPredictor]; |
/* Store the two initial samples we start with */ |
decoded[0] = state[0]->iSamp2&0xFF; |
decoded[1] = state[0]->iSamp2>>8; |
decoded += 2; |
if ( stereo ) { |
decoded[0] = state[1]->iSamp2&0xFF; |
decoded[1] = state[1]->iSamp2>>8; |
decoded += 2; |
} |
decoded[0] = state[0]->iSamp1&0xFF; |
decoded[1] = state[0]->iSamp1>>8; |
decoded += 2; |
if ( stereo ) { |
decoded[0] = state[1]->iSamp1&0xFF; |
decoded[1] = state[1]->iSamp1>>8; |
decoded += 2; |
} |
/* Decode and store the other samples in this block */ |
samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)* |
MS_ADPCM_state.wavefmt.channels; |
while ( samplesleft > 0 ) { |
nybble = (*encoded)>>4; |
new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]); |
decoded[0] = new_sample&0xFF; |
new_sample >>= 8; |
decoded[1] = new_sample&0xFF; |
decoded += 2; |
nybble = (*encoded)&0x0F; |
new_sample = MS_ADPCM_nibble(state[1],nybble,coeff[1]); |
decoded[0] = new_sample&0xFF; |
new_sample >>= 8; |
decoded[1] = new_sample&0xFF; |
decoded += 2; |
++encoded; |
samplesleft -= 2; |
} |
encoded_len -= MS_ADPCM_state.wavefmt.blockalign; |
} |
free(freeable); |
return(0); |
} |
struct IMA_ADPCM_decodestate { |
Sint32 sample; |
Sint8 index; |
}; |
static struct IMA_ADPCM_decoder { |
WaveFMT wavefmt; |
Uint16 wSamplesPerBlock; |
/* * * */ |
struct IMA_ADPCM_decodestate state[2]; |
} IMA_ADPCM_state; |
static int InitIMA_ADPCM(WaveFMT *format) |
{ |
Uint8 *rogue_feel; |
Uint16 extra_info; |
/* Set the rogue pointer to the IMA_ADPCM specific data */ |
IMA_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding); |
IMA_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels); |
IMA_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency); |
IMA_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate); |
IMA_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign); |
IMA_ADPCM_state.wavefmt.bitspersample = |
SDL_SwapLE16(format->bitspersample); |
rogue_feel = (Uint8 *)format+sizeof(*format); |
if ( sizeof(*format) == 16 ) { |
extra_info = ((rogue_feel[1]<<8)|rogue_feel[0]); |
rogue_feel += sizeof(Uint16); |
} |
IMA_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]); |
return(0); |
} |
static Sint32 IMA_ADPCM_nibble(struct IMA_ADPCM_decodestate *state,Uint8 nybble) |
{ |
const Sint32 max_audioval = ((1<<(16-1))-1); |
const Sint32 min_audioval = -(1<<(16-1)); |
const int index_table[16] = { |
-1, -1, -1, -1, |
2, 4, 6, 8, |
-1, -1, -1, -1, |
2, 4, 6, 8 |
}; |
const Sint32 step_table[89] = { |
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, |
34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, |
143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, |
449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, |
1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, |
3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, |
9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, |
22385, 24623, 27086, 29794, 32767 |
}; |
Sint32 delta, step; |
/* Compute difference and new sample value */ |
step = step_table[state->index]; |
delta = step >> 3; |
if ( nybble & 0x04 ) delta += step; |
if ( nybble & 0x02 ) delta += (step >> 1); |
if ( nybble & 0x01 ) delta += (step >> 2); |
if ( nybble & 0x08 ) delta = -delta; |
state->sample += delta; |
/* Update index value */ |
state->index += index_table[nybble]; |
if ( state->index > 88 ) { |
state->index = 88; |
} else |
if ( state->index < 0 ) { |
state->index = 0; |
} |
/* Clamp output sample */ |
if ( state->sample > max_audioval ) { |
state->sample = max_audioval; |
} else |
if ( state->sample < min_audioval ) { |
state->sample = min_audioval; |
} |
return(state->sample); |
} |
/* Fill the decode buffer with a channel block of data (8 samples) */ |
static void Fill_IMA_ADPCM_block(Uint8 *decoded, Uint8 *encoded, |
int channel, int numchannels, struct IMA_ADPCM_decodestate *state) |
{ |
int i; |
Sint8 nybble; |
Sint32 new_sample; |
decoded += (channel * 2); |
for ( i=0; i<4; ++i ) { |
nybble = (*encoded)&0x0F; |
new_sample = IMA_ADPCM_nibble(state, nybble); |
decoded[0] = new_sample&0xFF; |
new_sample >>= 8; |
decoded[1] = new_sample&0xFF; |
decoded += 2 * numchannels; |
nybble = (*encoded)>>4; |
new_sample = IMA_ADPCM_nibble(state, nybble); |
decoded[0] = new_sample&0xFF; |
new_sample >>= 8; |
decoded[1] = new_sample&0xFF; |
decoded += 2 * numchannels; |
++encoded; |
} |
} |
static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len) |
{ |
struct IMA_ADPCM_decodestate *state; |
Uint8 *freeable, *encoded, *decoded; |
Sint32 encoded_len, samplesleft; |
int c, channels; |
/* Check to make sure we have enough variables in the state array */ |
channels = IMA_ADPCM_state.wavefmt.channels; |
if ( channels > NELEMS(IMA_ADPCM_state.state) ) { |
SDL_SetError("IMA ADPCM decoder can only handle %d channels", |
NELEMS(IMA_ADPCM_state.state)); |
return(-1); |
} |
state = IMA_ADPCM_state.state; |
/* Allocate the proper sized output buffer */ |
encoded_len = *audio_len; |
encoded = *audio_buf; |
freeable = *audio_buf; |
*audio_len = (encoded_len/IMA_ADPCM_state.wavefmt.blockalign) * |
IMA_ADPCM_state.wSamplesPerBlock* |
IMA_ADPCM_state.wavefmt.channels*sizeof(Sint16); |
*audio_buf = (Uint8 *)malloc(*audio_len); |
if ( *audio_buf == NULL ) { |
SDL_Error(SDL_ENOMEM); |
return(-1); |
} |
decoded = *audio_buf; |
/* Get ready... Go! */ |
while ( encoded_len >= IMA_ADPCM_state.wavefmt.blockalign ) { |
/* Grab the initial information for this block */ |
for ( c=0; c<channels; ++c ) { |
/* Fill the state information for this block */ |
state[c].sample = ((encoded[1]<<8)|encoded[0]); |
encoded += 2; |
if ( state[c].sample & 0x8000 ) { |
state[c].sample -= 0x10000; |
} |
state[c].index = *encoded++; |
/* Reserved byte in buffer header, should be 0 */ |
if ( *encoded++ != 0 ) { |
/* Uh oh, corrupt data? Buggy code? */; |
} |
/* Store the initial sample we start with */ |
decoded[0] = state[c].sample&0xFF; |
decoded[1] = state[c].sample>>8; |
decoded += 2; |
} |
/* Decode and store the other samples in this block */ |
samplesleft = (IMA_ADPCM_state.wSamplesPerBlock-1)*channels; |
while ( samplesleft > 0 ) { |
for ( c=0; c<channels; ++c ) { |
Fill_IMA_ADPCM_block(decoded, encoded, |
c, channels, &state[c]); |
encoded += 4; |
samplesleft -= 8; |
} |
decoded += (channels * 8 * 2); |
} |
encoded_len -= IMA_ADPCM_state.wavefmt.blockalign; |
} |
free(freeable); |
return(0); |
} |
SDL_AudioSpec * SDL_LoadWAV_RW (SDL_RWops *src, int freesrc, |
SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) |
{ |
int was_error; |
Chunk chunk; |
int lenread; |
int MS_ADPCM_encoded, IMA_ADPCM_encoded; |
int samplesize; |
/* WAV magic header */ |
Uint32 RIFFchunk; |
Uint32 wavelen; |
Uint32 WAVEmagic; |
/* FMT chunk */ |
WaveFMT *format = NULL; |
/* Make sure we are passed a valid data source */ |
was_error = 0; |
if ( src == NULL ) { |
was_error = 1; |
goto done; |
} |
/* Check the magic header */ |
RIFFchunk = SDL_ReadLE32(src); |
wavelen = SDL_ReadLE32(src); |
WAVEmagic = SDL_ReadLE32(src); |
if ( (RIFFchunk != RIFF) || (WAVEmagic != WAVE) ) { |
SDL_SetError("Unrecognized file type (not WAVE)"); |
was_error = 1; |
goto done; |
} |
/* Read the audio data format chunk */ |
chunk.data = NULL; |
do { |
if ( chunk.data != NULL ) { |
free(chunk.data); |
} |
lenread = ReadChunk(src, &chunk); |
if ( lenread < 0 ) { |
was_error = 1; |
goto done; |
} |
} while ( (chunk.magic == FACT) || (chunk.magic == LIST) ); |
/* Decode the audio data format */ |
format = (WaveFMT *)chunk.data; |
if ( chunk.magic != FMT ) { |
SDL_SetError("Complex WAVE files not supported"); |
was_error = 1; |
goto done; |
} |
MS_ADPCM_encoded = IMA_ADPCM_encoded = 0; |
switch (SDL_SwapLE16(format->encoding)) { |
case PCM_CODE: |
/* We can understand this */ |
break; |
case MS_ADPCM_CODE: |
/* Try to understand this */ |
if ( InitMS_ADPCM(format) < 0 ) { |
was_error = 1; |
goto done; |
} |
MS_ADPCM_encoded = 1; |
break; |
case IMA_ADPCM_CODE: |
/* Try to understand this */ |
if ( InitIMA_ADPCM(format) < 0 ) { |
was_error = 1; |
goto done; |
} |
IMA_ADPCM_encoded = 1; |
break; |
default: |
SDL_SetError("Unknown WAVE data format: 0x%.4x", |
SDL_SwapLE16(format->encoding)); |
was_error = 1; |
goto done; |
} |
memset(spec, 0, (sizeof *spec)); |
spec->freq = SDL_SwapLE32(format->frequency); |
switch (SDL_SwapLE16(format->bitspersample)) { |
case 4: |
if ( MS_ADPCM_encoded || IMA_ADPCM_encoded ) { |
spec->format = AUDIO_S16; |
} else { |
was_error = 1; |
} |
break; |
case 8: |
spec->format = AUDIO_U8; |
break; |
case 16: |
spec->format = AUDIO_S16; |
break; |
default: |
was_error = 1; |
break; |
} |
if ( was_error ) { |
SDL_SetError("Unknown %d-bit PCM data format", |
SDL_SwapLE16(format->bitspersample)); |
goto done; |
} |
spec->channels = (Uint8)SDL_SwapLE16(format->channels); |
spec->samples = 4096; /* Good default buffer size */ |
/* Read the audio data chunk */ |
*audio_buf = NULL; |
do { |
if ( *audio_buf != NULL ) { |
free(*audio_buf); |
} |
lenread = ReadChunk(src, &chunk); |
if ( lenread < 0 ) { |
was_error = 1; |
goto done; |
} |
*audio_len = lenread; |
*audio_buf = chunk.data; |
} while ( chunk.magic != DATA ); |
if ( MS_ADPCM_encoded ) { |
if ( MS_ADPCM_decode(audio_buf, audio_len) < 0 ) { |
was_error = 1; |
goto done; |
} |
} |
if ( IMA_ADPCM_encoded ) { |
if ( IMA_ADPCM_decode(audio_buf, audio_len) < 0 ) { |
was_error = 1; |
goto done; |
} |
} |
/* Don't return a buffer that isn't a multiple of samplesize */ |
samplesize = ((spec->format & 0xFF)/8)*spec->channels; |
*audio_len &= ~(samplesize-1); |
done: |
if ( format != NULL ) { |
free(format); |
} |
if ( freesrc && src ) { |
SDL_RWclose(src); |
} |
if ( was_error ) { |
spec = NULL; |
} |
return(spec); |
} |
/* Since the WAV memory is allocated in the shared library, it must also |
be freed here. (Necessary under Win32, VC++) |
*/ |
void SDL_FreeWAV(Uint8 *audio_buf) |
{ |
if ( audio_buf != NULL ) { |
free(audio_buf); |
} |
} |
static int ReadChunk(SDL_RWops *src, Chunk *chunk) |
{ |
chunk->magic = SDL_ReadLE32(src); |
chunk->length = SDL_ReadLE32(src); |
chunk->data = (Uint8 *)malloc(chunk->length); |
if ( chunk->data == NULL ) { |
SDL_Error(SDL_ENOMEM); |
return(-1); |
} |
if ( SDL_RWread(src, chunk->data, chunk->length, 1) != 1 ) { |
SDL_Error(SDL_EFREAD); |
free(chunk->data); |
return(-1); |
} |
return(chunk->length); |
} |
#endif /* ENABLE_FILE */ |
/contrib/games/opentyrian/SDL/SDL_wave.h |
---|
0,0 → 1,65 |
/* |
SDL - Simple DirectMedia Layer |
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Library General Public |
License as published by the Free Software Foundation; either |
version 2 of the License, or (at your option) any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Library General Public License for more details. |
You should have received a copy of the GNU Library General Public |
License along with this library; if not, write to the Free |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Sam Lantinga |
slouken@devolution.com |
*/ |
#ifdef SAVE_RCSID |
static char rcsid = |
"@(#) $Id: SDL_wave.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; |
#endif |
/* WAVE files are little-endian */ |
/*******************************************/ |
/* Define values for Microsoft WAVE format */ |
/*******************************************/ |
#define RIFF 0x46464952 /* "RIFF" */ |
#define WAVE 0x45564157 /* "WAVE" */ |
#define FACT 0x74636166 /* "fact" */ |
#define LIST 0x5453494c /* "LIST" */ |
#define FMT 0x20746D66 /* "fmt " */ |
#define DATA 0x61746164 /* "data" */ |
#define PCM_CODE 0x0001 |
#define MS_ADPCM_CODE 0x0002 |
#define IMA_ADPCM_CODE 0x0011 |
#define WAVE_MONO 1 |
#define WAVE_STEREO 2 |
/* Normally, these three chunks come consecutively in a WAVE file */ |
typedef struct WaveFMT { |
/* Not saved in the chunk we read: |
Uint32 FMTchunk; |
Uint32 fmtlen; |
*/ |
Uint16 encoding; |
Uint16 channels; /* 1 = mono, 2 = stereo */ |
Uint32 frequency; /* One of 11025, 22050, or 44100 Hz */ |
Uint32 byterate; /* Average bytes per second */ |
Uint16 blockalign; /* Bytes per sample block */ |
Uint16 bitspersample; /* One of 8, 12, 16, or 4 for ADPCM */ |
} WaveFMT; |
/* The general chunk found in the WAVE file */ |
typedef struct Chunk { |
Uint32 magic; |
Uint32 length; |
Uint8 *data; /* Data includes magic and length */ |
} Chunk; |
/contrib/games/opentyrian/SDL/joystick_stub.c |
---|
0,0 → 1,153 |
/// JOYSTICK STUB FOR Wolfenstein 3D port to KolibriOS |
/// Ported by maxcodehack and turbocat2001 |
/* Set up for C function definitions, even when using C++ */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** @file SDL_joystick.h |
* @note In order to use these functions, SDL_Init() must have been called |
* with the SDL_INIT_JOYSTICK flag. This causes SDL to scan the system |
* for joysticks, and load appropriate drivers. |
*/ |
/** The joystick structure used to identify an SDL joystick */ |
struct _SDL_Joystick; |
typedef struct _SDL_Joystick SDL_Joystick; |
/* Function prototypes */ |
/** |
* Count the number of joysticks attached to the system |
*/ |
int SDL_NumJoysticks(void){}; |
/** |
* Get the implementation dependent name of a joystick. |
* |
* This can be called before any joysticks are opened. |
* If no name can be found, this function returns NULL. |
*/ |
const char * SDL_JoystickName(int device_index){}; |
/** |
* Open a joystick for use. |
* |
* @param[in] device_index |
* The index passed as an argument refers to |
* the N'th joystick on the system. This index is the value which will |
* identify this joystick in future joystick events. |
* |
* @return This function returns a joystick identifier, or NULL if an error occurred. |
*/ |
SDL_Joystick * SDL_JoystickOpen(int device_index){}; |
/** |
* Returns 1 if the joystick has been opened, or 0 if it has not. |
*/ |
int SDL_JoystickOpened(int device_index){}; |
/** |
* Get the device index of an opened joystick. |
*/ |
int SDL_JoystickIndex(SDL_Joystick *joystick){}; |
/** |
* Get the number of general axis controls on a joystick |
*/ |
int SDL_JoystickNumAxes(SDL_Joystick *joystick){}; |
/** |
* Get the number of trackballs on a joystick |
* |
* Joystick trackballs have only relative motion events associated |
* with them and their state cannot be polled. |
*/ |
int SDL_JoystickNumBalls(SDL_Joystick *joystick){}; |
/** |
* Get the number of POV hats on a joystick |
*/ |
int SDL_JoystickNumHats(SDL_Joystick *joystick){}; |
/** |
* Get the number of buttons on a joystick |
*/ |
int SDL_JoystickNumButtons(SDL_Joystick *joystick){}; |
/** |
* Update the current state of the open joysticks. |
* |
* This is called automatically by the event loop if any joystick |
* events are enabled. |
*/ |
void SDL_JoystickUpdate(void){}; |
/** |
* Enable/disable joystick event polling. |
* |
* If joystick events are disabled, you must call SDL_JoystickUpdate() |
* yourself and check the state of the joystick when you want joystick |
* information. |
* |
* @param[in] state The state can be one of SDL_QUERY, SDL_ENABLE or SDL_IGNORE. |
*/ |
int SDL_JoystickEventState(int state){}; |
/** |
* Get the current state of an axis control on a joystick |
* |
* @param[in] axis The axis indices start at index 0. |
* |
* @return The state is a value ranging from -32768 to 32767. |
*/ |
int SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis){}; |
/** |
* @name Hat Positions |
* The return value of SDL_JoystickGetHat() is one of the following positions: |
*/ |
/*@{*/ |
#define SDL_HAT_CENTERED 0x00 |
#define SDL_HAT_UP 0x01 |
#define SDL_HAT_RIGHT 0x02 |
#define SDL_HAT_DOWN 0x04 |
#define SDL_HAT_LEFT 0x08 |
#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP) |
#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN) |
#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP) |
#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN) |
/*@}*/ |
/** |
* Get the current state of a POV hat on a joystick |
* |
* @param[in] hat The hat indices start at index 0. |
*/ |
int SDL_JoystickGetHat(SDL_Joystick *joystick, int hat){}; |
/** |
* Get the ball axis change since the last poll |
* |
* @param[in] ball The ball indices start at index 0. |
* |
* @return This returns 0, or -1 if you passed it invalid parameters. |
*/ |
int SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy){}; |
/** |
* Get the current state of a button on a joystick |
* |
* @param[in] button The button indices start at index 0. |
*/ |
int SDL_JoystickGetButton(SDL_Joystick *joystick, int button){}; |
/** |
* Close a joystick previously opened with SDL_JoystickOpen() |
*/ |
void SDL_JoystickClose(SDL_Joystick *joystick){}; |
/* Ends C function definitions when using C++ */ |
#ifdef __cplusplus |
} |
#endif |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/contrib/games/opentyrian/SDL/uSDL.c |
---|
0,0 → 1,53 |
#include <SDL.h> |
#include <stdlib.h> |
#include <string.h> |
#define asm_inline __asm__ __volatile__ |
#pragma pack(push,1) |
typedef union{ |
unsigned val; |
struct{ |
short h; |
short w; |
}; |
}ksys_screen_t; |
#pragma pack(pop) |
static inline |
void _ksys_change_window(int new_x, int new_y, int new_w, int new_h) |
{ |
asm_inline( |
"int $0x40" |
::"a"(67), "b"(new_x), "c"(new_y), "d"(new_w),"S"(new_h) |
); |
} |
static inline |
ksys_screen_t _ksys_screen_size() |
{ |
ksys_screen_t size; |
asm_inline( |
"int $0x40" |
:"=a"(size) |
:"a"(14) |
:"memory" |
); |
return size; |
} |
void uSDL_SetWinCenter(unsigned w, unsigned h){ |
ksys_screen_t screen_size= _ksys_screen_size(); |
int new_x = screen_size.w/2-w/2; |
int new_y = screen_size.h/2-h/2; |
_ksys_change_window(new_x, new_y, -1, -1); |
} |
void uSDL_Delay(unsigned ms){ |
unsigned start = SDL_GetTicks(); |
do{ |
asm_inline("int $0x40" :: "a"(5),"b"(1)); |
}while (SDL_GetTicks()-start < ms); |
} |