forked from KolibriOS/kolibrios
libSDL(newlibc)
- Added SDL_audiocvt, SDL_mixer, SDL_wave; - Added ability to get screen resolutions. git-svn-id: svn://kolibrios.org@9561 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
a218cacd34
commit
9770ba3b5d
@ -42,6 +42,7 @@ static char rcsid =
|
|||||||
#include "SDL_events.h"
|
#include "SDL_events.h"
|
||||||
#include "SDL_video.h"
|
#include "SDL_video.h"
|
||||||
#include "SDL_byteorder.h"
|
#include "SDL_byteorder.h"
|
||||||
|
#include "SDL_stdinc.h"
|
||||||
#include "SDL_version.h"
|
#include "SDL_version.h"
|
||||||
|
|
||||||
#include "begin_code.h"
|
#include "begin_code.h"
|
||||||
|
@ -96,6 +96,10 @@ extern DECLSPEC SDL_RWops * SDL_RWFromMem(void *mem, int size);
|
|||||||
extern DECLSPEC SDL_RWops * SDL_AllocRW(void);
|
extern DECLSPEC SDL_RWops * SDL_AllocRW(void);
|
||||||
extern DECLSPEC void SDL_FreeRW(SDL_RWops *area);
|
extern DECLSPEC void SDL_FreeRW(SDL_RWops *area);
|
||||||
|
|
||||||
|
#define RW_SEEK_SET SEEK_SET /**< Seek from the beginning of data */
|
||||||
|
#define RW_SEEK_CUR SEEK_CUR /**< Seek relative to current read point */
|
||||||
|
#define RW_SEEK_END SEEK_END /**< Seek relative to the end of data */
|
||||||
|
|
||||||
/* Macros to easily read and write from an SDL_RWops structure */
|
/* Macros to easily read and write from an SDL_RWops structure */
|
||||||
#define SDL_RWseek(ctx, offset, whence) (ctx)->seek(ctx, offset, whence)
|
#define SDL_RWseek(ctx, offset, whence) (ctx)->seek(ctx, offset, whence)
|
||||||
#define SDL_RWtell(ctx) (ctx)->seek(ctx, 0, SEEK_CUR)
|
#define SDL_RWtell(ctx) (ctx)->seek(ctx, 0, SEEK_CUR)
|
||||||
|
112
contrib/sdk/sources/SDL-1.2.2_newlib/include/SDL_stdinc.h
Normal file
112
contrib/sdk/sources/SDL-1.2.2_newlib/include/SDL_stdinc.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
SDL - Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2012 Sam Lantinga
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Sam Lantinga
|
||||||
|
slouken@libsdl.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file SDL_stdinc.h
|
||||||
|
* This is a general header that includes C language support
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SDL_stdinc_h
|
||||||
|
#define _SDL_stdinc_h
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/** The number of elements in an array */
|
||||||
|
#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0]))
|
||||||
|
|
||||||
|
/* Use proper C++ casts when compiled as C++ to be compatible with the option
|
||||||
|
-Wold-style-cast of GCC (and -Werror=old-style-cast in GCC 4.2 and above. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define SDL_reinterpret_cast(type, expression) reinterpret_cast<type>(expression)
|
||||||
|
#define SDL_static_cast(type, expression) static_cast<type>(expression)
|
||||||
|
#else
|
||||||
|
#define SDL_reinterpret_cast(type, expression) ((type)(expression))
|
||||||
|
#define SDL_static_cast(type, expression) ((type)(expression))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DUMMY_ENUM_VALUE
|
||||||
|
} SDL_DUMMY_ENUM;
|
||||||
|
|
||||||
|
#include "begin_code.h"
|
||||||
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SDL_malloc malloc
|
||||||
|
#define SDL_calloc calloc
|
||||||
|
#define SDL_realloc realloc
|
||||||
|
#define SDL_free free
|
||||||
|
#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count))
|
||||||
|
#define SDL_stack_free(data) SDL_free(data)
|
||||||
|
#define SDL_qsort qsort
|
||||||
|
#define SDL_abs abs
|
||||||
|
#define SDL_min(x, y) (((x) < (y)) ? (x) : (y))
|
||||||
|
#define SDL_max(x, y) (((x) > (y)) ? (x) : (y))
|
||||||
|
#define SDL_isdigit(X) isdigit(X)
|
||||||
|
#define SDL_isspace(X) isspace(X)
|
||||||
|
#define SDL_toupper(X) toupper(X)
|
||||||
|
#define SDL_tolower(X) tolower(X)
|
||||||
|
#define SDL_memset memset
|
||||||
|
#define SDL_memmove memmove
|
||||||
|
#define SDL_memcmp memcmp
|
||||||
|
#define SDL_strlen strlen
|
||||||
|
#define SDL_strlcpy strlcpy
|
||||||
|
#define SDL_strlcat strlcat
|
||||||
|
#define SDL_strdup strdup
|
||||||
|
#define SDL_strrev _strrev
|
||||||
|
#define SDL_strupr _strupr
|
||||||
|
#define SDL_strlwr _strlwr
|
||||||
|
#define SDL_strchr strchr
|
||||||
|
#define SDL_strrchr strrchr
|
||||||
|
#define SDL_strstr strstr
|
||||||
|
#define SDL_itoa itoa
|
||||||
|
#define SDL_ltoa _ltoa
|
||||||
|
#define SDL_uitoa _uitoa
|
||||||
|
#define SDL_ultoa _ultoa
|
||||||
|
#define SDL_strtol strtol
|
||||||
|
#define SDL_strtoul strtoul
|
||||||
|
#define SDL_strtod strtod
|
||||||
|
#define SDL_atoi atoi
|
||||||
|
#define SDL_atof atof
|
||||||
|
#define SDL_strcmp strcmp
|
||||||
|
#define SDL_strncmp strncmp
|
||||||
|
#define SDL_sscanf sscanf
|
||||||
|
#define SDL_snprintf snprintf
|
||||||
|
#define SDL_vsnprintf vsnprintf
|
||||||
|
|
||||||
|
/* Ends C function definitions when using C++ */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#include "close_code.h"
|
||||||
|
|
||||||
|
#endif /* _SDL_stdinc_h */
|
@ -38,12 +38,12 @@ typedef enum {
|
|||||||
SDL_FALSE = 0,
|
SDL_FALSE = 0,
|
||||||
SDL_TRUE = 1
|
SDL_TRUE = 1
|
||||||
} SDL_bool;
|
} SDL_bool;
|
||||||
typedef unsigned char Uint8;
|
typedef unsigned char Uint8;
|
||||||
typedef signed char Sint8;
|
typedef signed char Sint8;
|
||||||
typedef unsigned short Uint16;
|
typedef unsigned short Uint16;
|
||||||
typedef signed short Sint16;
|
typedef signed short Sint16;
|
||||||
typedef unsigned int Uint32;
|
typedef unsigned int Uint32;
|
||||||
typedef signed int Sint32;
|
typedef signed int Sint32;
|
||||||
|
|
||||||
/* Figure out how to support 64-bit datatypes */
|
/* Figure out how to support 64-bit datatypes */
|
||||||
#if !defined(__STRICT_ANSI__)
|
#if !defined(__STRICT_ANSI__)
|
||||||
|
@ -168,6 +168,8 @@ typedef struct {
|
|||||||
Uint32 UnusedBits3 :16;
|
Uint32 UnusedBits3 :16;
|
||||||
Uint32 video_mem; /* The total amount of video memory (in K) */
|
Uint32 video_mem; /* The total amount of video memory (in K) */
|
||||||
SDL_PixelFormat *vfmt; /* Value: The format of the video surface */
|
SDL_PixelFormat *vfmt; /* Value: The format of the video surface */
|
||||||
|
Uint32 current_h; /* Current screen width */
|
||||||
|
Uint32 current_w; /* Current screen height */
|
||||||
} SDL_VideoInfo;
|
} SDL_VideoInfo;
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,6 +48,29 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def SDLCALL
|
||||||
|
* By default SDL uses the C calling convention
|
||||||
|
*/
|
||||||
|
#ifndef SDLCALL
|
||||||
|
# if defined(__WIN32__) && !defined(__GNUC__)
|
||||||
|
# define SDLCALL __cdecl
|
||||||
|
# elif defined(__OS2__)
|
||||||
|
# if defined (__GNUC__) && __GNUC__ < 4
|
||||||
|
# /* Added support for GCC-EMX <v4.x */
|
||||||
|
# /* this is needed for XFree86/OS2 developement */
|
||||||
|
# /* F. Ambacher(anakor@snafu.de) 05.2008 */
|
||||||
|
# define SDLCALL _cdecl
|
||||||
|
# else
|
||||||
|
# /* On other compilers on OS/2, we use the _System calling convention */
|
||||||
|
# /* to be compatible with every compiler */
|
||||||
|
# define SDLCALL _System
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define SDLCALL
|
||||||
|
# endif
|
||||||
|
#endif /* SDLCALL */
|
||||||
|
|
||||||
/* Force structure packing at 4 byte alignment.
|
/* Force structure packing at 4 byte alignment.
|
||||||
This is necessary if the header is included in code which has structure
|
This is necessary if the header is included in code which has structure
|
||||||
packing set to an alternate value, say for loading structures from disk.
|
packing set to an alternate value, say for loading structures from disk.
|
||||||
|
@ -8,7 +8,7 @@ LIBNAME=libSDL
|
|||||||
SDK_DIR:= $(abspath ../../..)
|
SDK_DIR:= $(abspath ../../..)
|
||||||
|
|
||||||
LDFLAGS+= -shared -s -T dll.lds --entry _DllStartup --image-base=0 --out-implib $(LIBNAME).dll.a
|
LDFLAGS+= -shared -s -T dll.lds --entry _DllStartup --image-base=0 --out-implib $(LIBNAME).dll.a
|
||||||
LDFLAGS+= -L/home/max/autobuild/tools/win32/mingw32/lib
|
LDFLAGS+= -L../../../lib
|
||||||
|
|
||||||
endian_OBJS = endian/SDL_endian.o
|
endian_OBJS = endian/SDL_endian.o
|
||||||
file_OBJS = file/SDL_rwops.o
|
file_OBJS = file/SDL_rwops.o
|
||||||
@ -29,15 +29,18 @@ video_OBJS = video/SDL_blit_0.o video/SDL_blit_1.o video/SDL_blit_A.o \
|
|||||||
video/SDL_video.o video/SDL_yuv.o video/SDL_yuv_mmx.o \
|
video/SDL_video.o video/SDL_yuv.o video/SDL_yuv_mmx.o \
|
||||||
video/SDL_yuv_sw.o video/menuetos/SDL_menuetevents.o \
|
video/SDL_yuv_sw.o video/menuetos/SDL_menuetevents.o \
|
||||||
video/menuetos/SDL_menuetvideo.o
|
video/menuetos/SDL_menuetvideo.o
|
||||||
audio_OBJS = audio/SDL_kolibri_audio.o
|
audio_OBJS = audio/SDL_kolibri_audio.o audio/SDL_audiocvt.o audio/SDL_mixer.o audio/SDL_wave.o
|
||||||
|
|
||||||
curr_OBJS = SDL.o SDL_error.o SDL_fatal.o SDL_getenv.o
|
curr_OBJS = SDL.o SDL_error.o SDL_fatal.o SDL_getenv.o
|
||||||
|
|
||||||
OBJS = $(endian_OBJS) $(file_OBJS) $(hermes_OBJS) $(thread_OBJS) \
|
OBJS = $(endian_OBJS) $(file_OBJS) $(hermes_OBJS) $(thread_OBJS) \
|
||||||
$(timer_OBJS) $(event_OBJS) $(video_OBJS) $(curr_OBJS) $(audio_OBJS)
|
$(timer_OBJS) $(event_OBJS) $(video_OBJS) $(curr_OBJS) $(audio_OBJS)
|
||||||
|
|
||||||
CFLAGS = -c -O2 -D_REENTRANT -I../include -I SYSCALL/include -I. -DPACKAGE=\"SDL\" -DVERSION=\"1.2.2\" \
|
CFLAGS = -c -O2 -mpreferred-stack-boundary=2 -fno-ident -fomit-frame-pointer -fno-stack-check \
|
||||||
-fexpensive-optimizations -Wall -DENABLE_AUDIO -UDISABLE_AUDIO -DDISABLE_JOYSTICK \
|
-fno-stack-protector -mno-stack-arg-probe -fno-exceptions -fno-asynchronous-unwind-tables \
|
||||||
|
-ffast-math -mno-ms-bitfields -march=pentium-mmx -fexpensive-optimizations \
|
||||||
|
-D_REENTRANT -I../include -I SYSCALL/include -I. -DPACKAGE=\"SDL\" -DVERSION=\"1.2.2\" \
|
||||||
|
-Wall -DENABLE_AUDIO -UDISABLE_AUDIO -DDISABLE_JOYSTICK \
|
||||||
-DDISABLE_CDROM -DDISABLE_THREADS -DENABLE_TIMERS \
|
-DDISABLE_CDROM -DDISABLE_THREADS -DENABLE_TIMERS \
|
||||||
-DUSE_ASMBLIT -Ihermes -Iaudio -Ivideo -Ievents \
|
-DUSE_ASMBLIT -Ihermes -Iaudio -Ivideo -Ievents \
|
||||||
-Ijoystick -Icdrom -Ithread -Itimer -Iendian -Ifile -DENABLE_KOLIBRIOS \
|
-Ijoystick -Icdrom -Ithread -Itimer -Iendian -Ifile -DENABLE_KOLIBRIOS \
|
||||||
@ -45,22 +48,22 @@ CFLAGS = -c -O2 -D_REENTRANT -I../include -I SYSCALL/include -I. -DPACKAGE=\"SDL
|
|||||||
-D__KOLIBRIOS__ -DDEBUG_VIDEO -UWIN32 -U_Win32 -U_WIN32 -U__MINGW32__ \
|
-D__KOLIBRIOS__ -DDEBUG_VIDEO -UWIN32 -U_Win32 -U_WIN32 -U__MINGW32__ \
|
||||||
-I../../newlib/libc/include/
|
-I../../newlib/libc/include/
|
||||||
|
|
||||||
all: $(LIBNAME).dll $(LIBNAME).a
|
all: $(LIBNAME).a $(LIBNAME).dll
|
||||||
|
|
||||||
install: $(LIBNAME)
|
install: $(LIBNAME)
|
||||||
mv -f $(LIBNAME) $(SDK_DIR)/lib
|
mv -f $(LIBNAME) $(SDK_DIR)/lib
|
||||||
|
|
||||||
$(LIBNAME).a: $(OBJS)
|
$(LIBNAME).a: $(OBJS)
|
||||||
$(MAKE) -C SYSCALL/src
|
$(MAKE) -C SYSCALL/src
|
||||||
$(AR) -crs $(LIBNAME).a $(OBJS) SYSCALL/src/os.o
|
$(AR) -crs ../../../lib/$(LIBNAME).a $(OBJS) SYSCALL/src/os.o
|
||||||
|
|
||||||
$(LIBNAME).dll: libSDL.def $(OBJS)
|
$(LIBNAME).dll: $(OBJS)
|
||||||
$(LD) $(LDFLAGS) -o $@ libSDL.def $(OBJS) SYSCALL/src/os.o $(LIBS) -ldll -lsound -lc.dll
|
$(LD) $(LDFLAGS) -o $@ $(OBJS) SYSCALL/src/os.o $(LIBS) -ldll -lsound -lc.dll
|
||||||
$(STRIP) $@
|
$(STRIP) -S $@
|
||||||
|
|
||||||
|
|
||||||
%.o : %.asm Makefile
|
%.o : %.asm Makefile
|
||||||
nasm -f coff $<
|
nasm -Ihermes -f coff $<
|
||||||
|
|
||||||
%.o : %.c Makefile
|
%.o : %.c Makefile
|
||||||
$(CC) $(CFLAGS) -o $@ $<
|
$(CC) $(CFLAGS) -o $@ $<
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
Sam Lantinga
|
Sam Lantinga
|
||||||
slouken@devolution.com
|
slouken@devolution.com
|
||||||
*/
|
*/
|
||||||
|
////////////////////
|
||||||
#ifdef SAVE_RCSID
|
#ifdef SAVE_RCSID
|
||||||
static char rcsid =
|
static char rcsid =
|
||||||
"@(#) $Id: SDL_error_c.h,v 1.2 2001/04/26 16:50:17 hercules Exp $";
|
"@(#) $Id: SDL_error_c.h,v 1.2 2001/04/26 16:50:17 hercules Exp $";
|
||||||
|
642
contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_audiocvt.c
Normal file
642
contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_audiocvt.c
Normal file
@ -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);
|
||||||
|
}
|
218
contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_mixer.c
Normal file
218
contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_mixer.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
150
contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_sysaudio.h
Normal file
150
contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_sysaudio.h
Normal file
@ -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 */
|
591
contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_wave.c
Normal file
591
contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_wave.c
Normal file
@ -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 */
|
65
contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_wave.h
Normal file
65
contrib/sdk/sources/SDL-1.2.2_newlib/src/audio/SDL_wave.h
Normal file
@ -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;
|
||||||
|
|
@ -1,226 +0,0 @@
|
|||||||
EXPORTS
|
|
||||||
SDL_ReadBE16
|
|
||||||
SDL_ReadBE32
|
|
||||||
SDL_ReadBE64
|
|
||||||
SDL_ReadLE16
|
|
||||||
SDL_ReadLE32
|
|
||||||
SDL_ReadLE64
|
|
||||||
SDL_WriteBE16
|
|
||||||
SDL_WriteBE32
|
|
||||||
SDL_WriteBE64
|
|
||||||
SDL_WriteLE16
|
|
||||||
SDL_WriteLE32
|
|
||||||
SDL_WriteLE64
|
|
||||||
SDL_AllocRW
|
|
||||||
SDL_FreeRW
|
|
||||||
SDL_RWFromFile
|
|
||||||
SDL_RWFromFP
|
|
||||||
SDL_RWFromMem
|
|
||||||
SDL_CondBroadcast
|
|
||||||
SDL_CondSignal
|
|
||||||
SDL_CondWait
|
|
||||||
SDL_CondWaitTimeout
|
|
||||||
SDL_CreateCond
|
|
||||||
SDL_DestroyCond
|
|
||||||
SDL_CreateMutex
|
|
||||||
SDL_DestroyMutex
|
|
||||||
SDL_mutexP
|
|
||||||
SDL_mutexV
|
|
||||||
SDL_CreateSemaphore
|
|
||||||
SDL_DestroySemaphore
|
|
||||||
SDL_SemPost
|
|
||||||
SDL_SemTryWait
|
|
||||||
SDL_SemValue
|
|
||||||
SDL_SemWait
|
|
||||||
SDL_SemWaitTimeout
|
|
||||||
SDL_SYS_CreateThread
|
|
||||||
SDL_SYS_KillThread
|
|
||||||
SDL_SYS_SetupThread
|
|
||||||
SDL_SYS_WaitThread
|
|
||||||
SDL_ThreadID
|
|
||||||
SDL_CreateThread
|
|
||||||
SDL_GetErrBuf
|
|
||||||
SDL_GetThreadID
|
|
||||||
SDL_KillThread
|
|
||||||
SDL_RunThread
|
|
||||||
SDL_ThreadsInit
|
|
||||||
SDL_ThreadsQuit
|
|
||||||
SDL_WaitThread
|
|
||||||
SDL_AddTimer
|
|
||||||
SDL_RemoveTimer
|
|
||||||
SDL_SetTimer
|
|
||||||
SDL_SetTimerThreaded
|
|
||||||
SDL_ThreadedTimerCheck
|
|
||||||
SDL_TimerInit
|
|
||||||
SDL_TimerQuit
|
|
||||||
SDL_Delay
|
|
||||||
SDL_GetTicks
|
|
||||||
SDL_StartTicks
|
|
||||||
SDL_SYS_StartTimer
|
|
||||||
SDL_SYS_StopTimer
|
|
||||||
SDL_SYS_TimerInit
|
|
||||||
SDL_SYS_TimerQuit
|
|
||||||
SDL_AppActiveInit
|
|
||||||
SDL_GetAppState
|
|
||||||
SDL_PrivateAppActive
|
|
||||||
SDL_EventState
|
|
||||||
SDL_EventThreadID
|
|
||||||
SDL_GetEventFilter
|
|
||||||
SDL_Lock_EventThread
|
|
||||||
SDL_PeepEvents
|
|
||||||
SDL_PollEvent
|
|
||||||
SDL_PrivateSysWMEvent
|
|
||||||
SDL_PumpEvents
|
|
||||||
SDL_PushEvent
|
|
||||||
SDL_SetEventFilter
|
|
||||||
SDL_StartEventLoop
|
|
||||||
SDL_StopEventLoop
|
|
||||||
SDL_Unlock_EventThread
|
|
||||||
SDL_WaitEvent
|
|
||||||
SDL_PrivateExpose
|
|
||||||
SDL_CheckKeyRepeat
|
|
||||||
SDL_EnableKeyRepeat
|
|
||||||
SDL_EnableUNICODE
|
|
||||||
SDL_GetKeyName
|
|
||||||
SDL_GetKeyState
|
|
||||||
SDL_GetModState
|
|
||||||
SDL_KeyboardInit
|
|
||||||
SDL_PrivateKeyboard
|
|
||||||
SDL_ResetKeyboard
|
|
||||||
SDL_SetModState
|
|
||||||
SDL_GetMouseState
|
|
||||||
SDL_GetRelativeMouseState
|
|
||||||
SDL_MouseInit
|
|
||||||
SDL_PrivateMouseButton
|
|
||||||
SDL_PrivateMouseMotion
|
|
||||||
SDL_PrivateQuit
|
|
||||||
SDL_QuitInit
|
|
||||||
SDL_PrivateResize
|
|
||||||
SDL_CalculateBlit0
|
|
||||||
SDL_CalculateBlit1
|
|
||||||
SDL_CalculateAlphaBlit
|
|
||||||
SDL_CalculateBlit
|
|
||||||
SDL_CalculateBlitN
|
|
||||||
SDL_LoadBMP_RW
|
|
||||||
SDL_SaveBMP_RW
|
|
||||||
SDL_CreateCursor
|
|
||||||
SDL_CursorInit
|
|
||||||
SDL_CursorPaletteChanged
|
|
||||||
SDL_CursorQuit
|
|
||||||
SDL_DrawCursor
|
|
||||||
SDL_DrawCursorNoLock
|
|
||||||
SDL_EraseCursor
|
|
||||||
SDL_EraseCursorNoLock
|
|
||||||
SDL_FreeCursor
|
|
||||||
SDL_GetCursor
|
|
||||||
SDL_MouseRect
|
|
||||||
SDL_MoveCursor
|
|
||||||
SDL_ResetCursor
|
|
||||||
SDL_SetCursor
|
|
||||||
SDL_ShowCursor
|
|
||||||
SDL_WarpMouse
|
|
||||||
SDL_GetGamma
|
|
||||||
SDL_GetGammaRamp
|
|
||||||
SDL_SetGamma
|
|
||||||
SDL_SetGammaRamp
|
|
||||||
SDL_AllocBlitMap
|
|
||||||
SDL_AllocFormat
|
|
||||||
SDL_ApplyGamma
|
|
||||||
SDL_CalculatePitch
|
|
||||||
SDL_DitherColors
|
|
||||||
SDL_FindColor
|
|
||||||
SDL_FormatChanged
|
|
||||||
SDL_FreeBlitMap
|
|
||||||
SDL_FreeFormat
|
|
||||||
SDL_GetRGB
|
|
||||||
SDL_GetRGBA
|
|
||||||
SDL_InvalidateMap
|
|
||||||
SDL_MapRGB
|
|
||||||
SDL_MapRGBA
|
|
||||||
SDL_MapSurface
|
|
||||||
SDL_ReallocFormat
|
|
||||||
SDL_RLEAlphaBlit
|
|
||||||
SDL_RLEBlit
|
|
||||||
SDL_RLESurface
|
|
||||||
SDL_UnRLESurface
|
|
||||||
SDL_SoftStretch
|
|
||||||
SDL_ConvertSurface
|
|
||||||
SDL_CreateRGBSurface
|
|
||||||
SDL_CreateRGBSurfaceFrom
|
|
||||||
SDL_FillRect
|
|
||||||
SDL_FreeSurface
|
|
||||||
SDL_GetClipRect
|
|
||||||
SDL_LockSurface
|
|
||||||
SDL_LowerBlit
|
|
||||||
SDL_SetAlpha
|
|
||||||
SDL_SetClipRect
|
|
||||||
SDL_SetColorKey
|
|
||||||
SDL_UnlockSurface
|
|
||||||
SDL_UpperBlit
|
|
||||||
SDL_DisplayFormat
|
|
||||||
SDL_DisplayFormatAlpha
|
|
||||||
SDL_Flip
|
|
||||||
SDL_GetVideoInfo
|
|
||||||
SDL_GetVideoSurface
|
|
||||||
SDL_GetWMInfo
|
|
||||||
SDL_GL_GetAttribute
|
|
||||||
SDL_GL_GetProcAddress
|
|
||||||
SDL_GL_LoadLibrary
|
|
||||||
SDL_GL_Lock
|
|
||||||
SDL_GL_SetAttribute
|
|
||||||
SDL_GL_SwapBuffers
|
|
||||||
SDL_GL_Unlock
|
|
||||||
SDL_GL_UpdateRects
|
|
||||||
SDL_GL_UpdateRectsLock
|
|
||||||
SDL_ListModes
|
|
||||||
SDL_SetColors
|
|
||||||
SDL_SetPalette
|
|
||||||
SDL_SetVideoMode
|
|
||||||
SDL_UpdateRect
|
|
||||||
SDL_UpdateRects
|
|
||||||
SDL_VideoDriverName
|
|
||||||
SDL_VideoInit
|
|
||||||
SDL_VideoModeOK
|
|
||||||
SDL_VideoQuit
|
|
||||||
SDL_WM_GetCaption
|
|
||||||
SDL_WM_GrabInput
|
|
||||||
SDL_WM_IconifyWindow
|
|
||||||
SDL_WM_SetCaption
|
|
||||||
SDL_WM_SetIcon
|
|
||||||
SDL_WM_ToggleFullScreen
|
|
||||||
SDL_CreateYUVOverlay
|
|
||||||
SDL_DisplayYUVOverlay
|
|
||||||
SDL_FreeYUVOverlay
|
|
||||||
SDL_LockYUVOverlay
|
|
||||||
SDL_UnlockYUVOverlay
|
|
||||||
SDL_CreateYUV_SW
|
|
||||||
SDL_DisplayYUV_SW
|
|
||||||
SDL_FreeYUV_SW
|
|
||||||
SDL_LockYUV_SW
|
|
||||||
SDL_UnlockYUV_SW
|
|
||||||
SDL_Init
|
|
||||||
SDL_InitSubSystem
|
|
||||||
SDL_Linked_Version
|
|
||||||
SDL_Quit
|
|
||||||
SDL_QuitSubSystem
|
|
||||||
SDL_WasInit
|
|
||||||
SDL_ClearError
|
|
||||||
SDL_Error
|
|
||||||
SDL_GetError
|
|
||||||
SDL_GetErrorMsg
|
|
||||||
SDL_GetErrorMsgUNICODE
|
|
||||||
SDL_printf
|
|
||||||
SDL_SetError
|
|
||||||
SDL_InstallParachute
|
|
||||||
SDL_printf_error
|
|
||||||
SDL_UninstallParachute
|
|
||||||
SDL_getenv
|
|
||||||
SDL_putenv
|
|
||||||
SDL_AudioDriverName
|
|
||||||
SDL_AudioInit
|
|
||||||
SDL_AudioQuit
|
|
||||||
SDL_CloseAudio
|
|
||||||
SDL_LockAudio
|
|
||||||
SDL_OpenAudio
|
|
||||||
SDL_PauseAudio
|
|
||||||
SDL_UnlockAudio
|
|
@ -114,6 +114,31 @@ static int lock_count = 0;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef union{
|
||||||
|
unsigned val;
|
||||||
|
struct{
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
};
|
||||||
|
}ksys_pos_t;
|
||||||
|
|
||||||
|
static inline
|
||||||
|
ksys_pos_t _ksys_screen_size()
|
||||||
|
{
|
||||||
|
ksys_pos_t size;
|
||||||
|
ksys_pos_t size_tmp;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"int $0x40"
|
||||||
|
:"=a"(size_tmp)
|
||||||
|
:"a"(14)
|
||||||
|
:"memory"
|
||||||
|
);
|
||||||
|
size.x = size_tmp.y;
|
||||||
|
size.y = size_tmp.x;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the video and event subsystems -- determine native pixel format
|
* Initialize the video and event subsystems -- determine native pixel format
|
||||||
*/
|
*/
|
||||||
@ -235,6 +260,10 @@ int SDL_VideoInit (const char *driver_name, Uint32 flags)
|
|||||||
#endif
|
#endif
|
||||||
video->info.vfmt = SDL_VideoSurface->format;
|
video->info.vfmt = SDL_VideoSurface->format;
|
||||||
|
|
||||||
|
ksys_pos_t screen_s = _ksys_screen_size();
|
||||||
|
video->info.current_h = screen_s.y;
|
||||||
|
video->info.current_w = screen_s.x;
|
||||||
|
|
||||||
/* Start the event loop */
|
/* Start the event loop */
|
||||||
if ( SDL_StartEventLoop(flags) < 0 ) {
|
if ( SDL_StartEventLoop(flags) < 0 ) {
|
||||||
SDL_VideoQuit();
|
SDL_VideoQuit();
|
||||||
|
Loading…
Reference in New Issue
Block a user