Wolfenstein 3D:

- Added sound!
- Added Linux makefile
- Added _KOLIBRI definition
- Removed not working parameters from --help in KolibriOS

git-svn-id: svn://kolibrios.org@8645 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
turbocat 2021-03-23 06:51:33 +00:00
parent ef8c93c6e4
commit 127b85086b
37 changed files with 10610 additions and 311 deletions

View File

@ -3,21 +3,64 @@ LD = kos32-ld
SDK_DIR = $(abspath ../../sdk)
CFLAGS = -c -fno-ident -O2 -fomit-frame-pointer -fno-ident -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32
CFLAGS = -c -fno-ident -O2 -fomit-frame-pointer -fno-ident -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32 -D_KOLIBRI
LDFLAGS = -static -S -nostdlib -T $(SDK_DIR)/sources/newlib/app.lds --image-base 0
INCLUDES = -I$(SDK_DIR)/sources/newlib/libc/include -I$(SDK_DIR)/sources/SDL-1.2.2_newlib/include -I.
INCLUDES = -I$(SDK_DIR)/sources/newlib/libc/include -I$(SDK_DIR)/sources/SDL-1.2.2_newlib/include -I. -I SDL_mixer
LIBPATH = -L $(SDK_DIR)/lib -L /home/autobuild/tools/win32/mingw32/lib
OBJECTS = wl_cloudsky.o wl_debug.o id_sd.o wl_play.o id_vl.o wl_act2.o wl_floorceiling.o wl_dir3dspr.o wl_state.o wl_atmos.o id_in.o signon.o wl_parallax.o wl_agent.o sdl_winmain.o wl_inter.o wl_text.o id_pm.o wl_draw.o wl_menu.o wl_game.o wl_act1.o wl_main.o wl_shade.o id_us_1.o id_vh.o id_ca.o joystick_stub.o kolibri.o
OBJECTS += wl_cloudsky.o
OBJECTS += wl_debug.o
OBJECTS += id_sd.o
OBJECTS += wl_play.o
OBJECTS += id_vl.o
OBJECTS += wl_act2.o
OBJECTS += wl_floorceiling.o
OBJECTS += wl_dir3dspr.o
OBJECTS += wl_state.o
OBJECTS += wl_atmos.o
OBJECTS += id_in.o
OBJECTS += signon.o
OBJECTS += wl_parallax.o
OBJECTS += wl_agent.o
OBJECTS += sdl_winmain.o
OBJECTS += wl_inter.o
OBJECTS += wl_text.o
OBJECTS += id_pm.o
OBJECTS += wl_draw.o
OBJECTS += wl_menu.o
OBJECTS += wl_game.o
OBJECTS += wl_act1.o
OBJECTS += wl_main.o
OBJECTS += wl_shade.o
OBJECTS += id_us_1.o
OBJECTS += id_vh.o
OBJECTS += id_ca.o
OBJECTS += joystick_stub.o
OBJECTS += kolibri.o
OBJECTS += mame/fmopl.o
default: $(OBJECTS)
kos32-ld $(LDFLAGS) $(LIBPATH) --subsystem native -o wolf3d $(OBJECTS) -lSDLn -lsound -lstdc++ -lsupc++ -lgcc -lc.dll
objcopy wolf3d -O binary
kpack --nologo wolf3d
SDL_OBJ += SDL/SDL_wave.o
SDL_OBJ += SDL/SDL_audiocvt.o
SDL_OBJ += SDL/SDL_mixer.o
SDL_MIX_OBJ += SDL_mixer/mixer.o
SDL_MIX_OBJ += SDL_mixer/music.o
SDL_MIX_OBJ += SDL_mixer/load_aiff.o
SDL_MIX_OBJ += SDL_mixer/load_voc.o
SDL_MIX_OBJ += SDL_mixer/effects_internal.o
SDL_MIX_OBJ += SDL_mixer/effect_position.o
default: $(OBJECTS) $(SDL_MIX_OBJ) $(SDL_OBJ)
kos32-ld $(LDFLAGS) $(LIBPATH) --subsystem native -o bin/wolf3d $(OBJECTS) $(SDL_MIX_OBJ) $(SDL_OBJ) -lSDLn -lsound -lstdc++ -lsupc++ -lgcc -lc.dll
objcopy bin/wolf3d -O binary
kpack --nologo bin/wolf3d
%.o : %.cpp
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $<
%.o : %.c
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $<
clean:
rm *.o
rm *.o SDL_mixer/*.o mame/*.o SDL/*.o *.d SDL_mixer/*.d mame/*.d SDL/*.d

View File

@ -0,0 +1,126 @@
CONFIG ?= config.default
-include $(CONFIG)
BINARY ?= bin/wolf3d
PREFIX ?= /usr/local
MANPREFIX ?= $(PREFIX)/share/man/
MANPAGE ?= man6/wolf4sdl.6
DATADIR ?= $(PREFIX)/share/games/wolf3d/
INSTALL ?= install
INSTALL_PROGRAM ?= $(INSTALL) -m 555 -s
INSTALL_MAN ?= $(INSTALL) -m 444
INSTALL_DATA ?= $(INSTALL) -m 444
SDL_CONFIG ?= sdl-config
CFLAGS_SDL ?= $(shell $(SDL_CONFIG) --cflags)
LDFLAGS_SDL ?= $(shell $(SDL_CONFIG) --libs)
CFLAGS += $(CFLAGS_SDL)
#CFLAGS += -Wall
#CFLAGS += -W
CFLAGS += -Wpointer-arith
CFLAGS += -Wreturn-type
CFLAGS += -Wwrite-strings
CFLAGS += -Wcast-align
ifdef DATADIR
CFLAGS += -DDATADIR=\"$(DATADIR)\"
endif
CCFLAGS += $(CFLAGS)
CCFLAGS += -std=gnu99
CCFLAGS += -Werror-implicit-function-declaration
CCFLAGS += -Wimplicit-int
CCFLAGS += -Wsequence-point
CXXFLAGS += $(CFLAGS)
LDFLAGS += $(LDFLAGS_SDL)
SRCS :=
SRCS += mame/fmopl.cpp
SRCS += id_ca.cpp
SRCS += id_in.cpp
SRCS += id_pm.cpp
SRCS += id_sd.cpp
SRCS += id_us_1.cpp
SRCS += id_vh.cpp
SRCS += id_vl.cpp
SRCS += signon.cpp
SRCS += wl_act1.cpp
SRCS += wl_act2.cpp
SRCS += wl_agent.cpp
SRCS += wl_atmos.cpp
SRCS += wl_cloudsky.cpp
SRCS += wl_debug.cpp
SRCS += wl_draw.cpp
SRCS += wl_floorceiling.cpp
SRCS += wl_game.cpp
SRCS += wl_inter.cpp
SRCS += wl_main.cpp
SRCS += wl_menu.cpp
SRCS += wl_parallax.cpp
SRCS += wl_play.cpp
SRCS += wl_state.cpp
SRCS += wl_text.cpp
SRCS += SDL_mixer/mixer.c
SRCS += SDL_mixer/music.c
SRCS += SDL_mixer/load_aiff.c
SRCS += SDL_mixer/load_voc.c
SRCS += SDL_mixer/effects_internal.c
SRCS += SDL_mixer/effect_position.c
DEPS = $(filter %.d, $(SRCS:.c=.d) $(SRCS:.cpp=.d))
OBJS = $(filter %.o, $(SRCS:.c=.o) $(SRCS:.cpp=.o))
.SUFFIXES:
.SUFFIXES: .c .cpp .d .o
Q ?= @
all: $(BINARY)
ifndef NO_DEPS
depend: $(DEPS)
ifeq ($(findstring $(MAKECMDGOALS), clean depend Data),)
-include $(DEPS)
endif
endif
$(BINARY): $(OBJS)
@echo '===> LD $@'
$(Q)$(CXX) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $@
.c.o:
@echo '===> CC $<'
$(Q)$(CC) $(CCFLAGS) -c $< -o $@
.cpp.o:
@echo '===> CXX $<'
$(Q)$(CXX) $(CXXFLAGS) -c $< -o $@
.c.d:
@echo '===> DEP $<'
$(Q)$(CC) $(CCFLAGS) -MM $< | sed 's#^$(@F:%.d=%.o):#$@ $(@:%.d=%.o):#' > $@
.cpp.d:
@echo '===> DEP $<'
$(Q)$(CXX) $(CXXFLAGS) -MM $< | sed 's#^$(@F:%.d=%.o):#$@ $(@:%.d=%.o):#' > $@
clean distclean:
@echo '===> CLEAN'
$(Q)rm -fr $(DEPS) $(OBJS) $(BINARY)
install: $(BINARY)
@echo '===> INSTALL'
$(Q)$(INSTALL) -d $(PREFIX)/bin
$(Q)$(INSTALL_PROGRAM) $(BINARY) $(PREFIX)/bin
$(Q)$(INSTALL_MAN) $(MANPAGE) $(MANPREFIX)/man6

View 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);
}

View 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;
}
}

View 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 */

View 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 */

View 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;

View File

@ -0,0 +1,642 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id$ */
#ifndef _SDL_MIXER_H
#define _SDL_MIXER_H
#include "SDL_types.h"
#include "SDL_rwops.h"
#include "SDL_audio.h"
#include "SDL_endian.h"
#include "SDL_version.h"
#include "begin_code.h"
#define SDLCALL
#define RW_SEEK_SET SEEK_SET
#define SDL_free free
#define SDL_malloc malloc
#define SDL_realloc realloc
#define SDL_calloc calloc
#define SDL_abs abs
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
*/
#define SDL_MIXER_MAJOR_VERSION 1
#define SDL_MIXER_MINOR_VERSION 2
#define SDL_MIXER_PATCHLEVEL 12
/* This macro can be used to fill a version structure with the compile-time
* version of the SDL_mixer library.
*/
#define SDL_MIXER_VERSION(X) \
{ \
(X)->major = SDL_MIXER_MAJOR_VERSION; \
(X)->minor = SDL_MIXER_MINOR_VERSION; \
(X)->patch = SDL_MIXER_PATCHLEVEL; \
}
/* Backwards compatibility */
#define MIX_MAJOR_VERSION SDL_MIXER_MAJOR_VERSION
#define MIX_MINOR_VERSION SDL_MIXER_MINOR_VERSION
#define MIX_PATCHLEVEL SDL_MIXER_PATCHLEVEL
#define MIX_VERSION(X) SDL_MIXER_VERSION(X)
/* This function gets the version of the dynamically linked SDL_mixer library.
it should NOT be used to fill a version structure, instead you should
use the SDL_MIXER_VERSION() macro.
*/
extern DECLSPEC const SDL_version * SDLCALL Mix_Linked_Version(void);
typedef enum
{
MIX_INIT_FLAC = 0x00000001,
MIX_INIT_MOD = 0x00000002,
MIX_INIT_MP3 = 0x00000004,
MIX_INIT_OGG = 0x00000008,
MIX_INIT_FLUIDSYNTH = 0x00000010
} MIX_InitFlags;
/* Loads dynamic libraries and prepares them for use. Flags should be
one or more flags from MIX_InitFlags OR'd together.
It returns the flags successfully initialized, or 0 on failure.
*/
extern DECLSPEC int SDLCALL Mix_Init(int flags);
/* Unloads libraries loaded with Mix_Init */
extern DECLSPEC void SDLCALL Mix_Quit(void);
/* The default mixer has 8 simultaneous mixing channels */
#ifndef MIX_CHANNELS
#define MIX_CHANNELS 8
#endif
/* Good default values for a PC soundcard */
#define MIX_DEFAULT_FREQUENCY 22050
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
#define MIX_DEFAULT_FORMAT AUDIO_S16LSB
#else
#define MIX_DEFAULT_FORMAT AUDIO_S16MSB
#endif
#define MIX_DEFAULT_CHANNELS 2
#define MIX_MAX_VOLUME 128 /* Volume of a chunk */
/* The internal format for an audio chunk */
typedef struct Mix_Chunk {
int allocated;
Uint8 *abuf;
Uint32 alen;
Uint8 volume; /* Per-sample volume, 0-128 */
} Mix_Chunk;
/* The different fading types supported */
typedef enum {
MIX_NO_FADING,
MIX_FADING_OUT,
MIX_FADING_IN
} Mix_Fading;
typedef enum {
MUS_NONE,
MUS_CMD,
MUS_WAV,
MUS_MOD,
MUS_MID,
MUS_OGG,
MUS_MP3,
MUS_MP3_MAD,
MUS_FLAC,
MUS_MODPLUG
} Mix_MusicType;
/* The internal format for a music chunk interpreted via mikmod */
typedef struct _Mix_Music Mix_Music;
/* Open the mixer with a certain audio format */
extern DECLSPEC int SDLCALL Mix_OpenAudio(int frequency, Uint16 format, int channels,
int chunksize);
/* Dynamically change the number of channels managed by the mixer.
If decreasing the number of channels, the upper channels are
stopped.
This function returns the new number of allocated channels.
*/
extern DECLSPEC int SDLCALL Mix_AllocateChannels(int numchans);
/* Find out what the actual audio device parameters are.
This function returns 1 if the audio has been opened, 0 otherwise.
*/
extern DECLSPEC int SDLCALL Mix_QuerySpec(int *frequency,Uint16 *format,int *channels);
/* Load a wave file or a music (.mod .s3m .it .xm) file */
extern DECLSPEC Mix_Chunk * SDLCALL Mix_LoadWAV_RW(SDL_RWops *src, int freesrc);
#define Mix_LoadWAV(file) Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1)
extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS(const char *file);
/* Load a music file from an SDL_RWop object (Ogg and MikMod specific currently)
Matt Campbell (matt@campbellhome.dhs.org) April 2000 */
extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS_RW(SDL_RWops *rw);
/* Load a music file from an SDL_RWop object assuming a specific format */
extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUSType_RW(SDL_RWops *rw, Mix_MusicType type, int freesrc);
/* Load a wave file of the mixer format from a memory buffer */
extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_WAV(Uint8 *mem);
/* Load raw audio data of the mixer format from a memory buffer */
extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_RAW(Uint8 *mem, Uint32 len);
/* Free an audio chunk previously loaded */
extern DECLSPEC void SDLCALL Mix_FreeChunk(Mix_Chunk *chunk);
extern DECLSPEC void SDLCALL Mix_FreeMusic(Mix_Music *music);
/* Get a list of chunk/music decoders that this build of SDL_mixer provides.
This list can change between builds AND runs of the program, if external
libraries that add functionality become available.
You must successfully call Mix_OpenAudio() before calling these functions.
This API is only available in SDL_mixer 1.2.9 and later.
// usage...
int i;
const int total = Mix_GetNumChunkDecoders();
for (i = 0; i < total; i++)
printf("Supported chunk decoder: [%s]\n", Mix_GetChunkDecoder(i));
Appearing in this list doesn't promise your specific audio file will
decode...but it's handy to know if you have, say, a functioning Timidity
install.
These return values are static, read-only data; do not modify or free it.
The pointers remain valid until you call Mix_CloseAudio().
*/
extern DECLSPEC int SDLCALL Mix_GetNumChunkDecoders(void);
extern DECLSPEC const char * SDLCALL Mix_GetChunkDecoder(int index);
extern DECLSPEC int SDLCALL Mix_GetNumMusicDecoders(void);
extern DECLSPEC const char * SDLCALL Mix_GetMusicDecoder(int index);
/* Find out the music format of a mixer music, or the currently playing
music, if 'music' is NULL.
*/
extern DECLSPEC Mix_MusicType SDLCALL Mix_GetMusicType(const Mix_Music *music);
/* Set a function that is called after all mixing is performed.
This can be used to provide real-time visual display of the audio stream
or add a custom mixer filter for the stream data.
*/
extern DECLSPEC void SDLCALL Mix_SetPostMix(void (*mix_func)
(void *udata, Uint8 *stream, int len), void *arg);
/* Add your own music player or additional mixer function.
If 'mix_func' is NULL, the default music player is re-enabled.
*/
extern DECLSPEC void SDLCALL Mix_HookMusic(void (*mix_func)
(void *udata, Uint8 *stream, int len), void *arg);
/* Add your own callback when the music has finished playing.
This callback is only called if the music finishes naturally.
*/
extern DECLSPEC void SDLCALL Mix_HookMusicFinished(void (*music_finished)(void));
/* Get a pointer to the user data for the current music hook */
extern DECLSPEC void * SDLCALL Mix_GetMusicHookData(void);
/*
* Add your own callback when a channel has finished playing. NULL
* to disable callback. The callback may be called from the mixer's audio
* callback or it could be called as a result of Mix_HaltChannel(), etc.
* do not call SDL_LockAudio() from this callback; you will either be
* inside the audio callback, or SDL_mixer will explicitly lock the audio
* before calling your callback.
*/
extern DECLSPEC void SDLCALL Mix_ChannelFinished(void (*channel_finished)(int channel));
/* Special Effects API by ryan c. gordon. (icculus@icculus.org) */
#define MIX_CHANNEL_POST -2
/* This is the format of a special effect callback:
*
* myeffect(int chan, void *stream, int len, void *udata);
*
* (chan) is the channel number that your effect is affecting. (stream) is
* the buffer of data to work upon. (len) is the size of (stream), and
* (udata) is a user-defined bit of data, which you pass as the last arg of
* Mix_RegisterEffect(), and is passed back unmolested to your callback.
* Your effect changes the contents of (stream) based on whatever parameters
* are significant, or just leaves it be, if you prefer. You can do whatever
* you like to the buffer, though, and it will continue in its changed state
* down the mixing pipeline, through any other effect functions, then finally
* to be mixed with the rest of the channels and music for the final output
* stream.
*
* DO NOT EVER call SDL_LockAudio() from your callback function!
*/
typedef void (*Mix_EffectFunc_t)(int chan, void *stream, int len, void *udata);
/*
* This is a callback that signifies that a channel has finished all its
* loops and has completed playback. This gets called if the buffer
* plays out normally, or if you call Mix_HaltChannel(), implicitly stop
* a channel via Mix_AllocateChannels(), or unregister a callback while
* it's still playing.
*
* DO NOT EVER call SDL_LockAudio() from your callback function!
*/
typedef void (*Mix_EffectDone_t)(int chan, void *udata);
/* Register a special effect function. At mixing time, the channel data is
* copied into a buffer and passed through each registered effect function.
* After it passes through all the functions, it is mixed into the final
* output stream. The copy to buffer is performed once, then each effect
* function performs on the output of the previous effect. Understand that
* this extra copy to a buffer is not performed if there are no effects
* registered for a given chunk, which saves CPU cycles, and any given
* effect will be extra cycles, too, so it is crucial that your code run
* fast. Also note that the data that your function is given is in the
* format of the sound device, and not the format you gave to Mix_OpenAudio(),
* although they may in reality be the same. This is an unfortunate but
* necessary speed concern. Use Mix_QuerySpec() to determine if you can
* handle the data before you register your effect, and take appropriate
* actions.
* You may also specify a callback (Mix_EffectDone_t) that is called when
* the channel finishes playing. This gives you a more fine-grained control
* than Mix_ChannelFinished(), in case you need to free effect-specific
* resources, etc. If you don't need this, you can specify NULL.
* You may set the callbacks before or after calling Mix_PlayChannel().
* Things like Mix_SetPanning() are just internal special effect functions,
* so if you are using that, you've already incurred the overhead of a copy
* to a separate buffer, and that these effects will be in the queue with
* any functions you've registered. The list of registered effects for a
* channel is reset when a chunk finishes playing, so you need to explicitly
* set them with each call to Mix_PlayChannel*().
* You may also register a special effect function that is to be run after
* final mixing occurs. The rules for these callbacks are identical to those
* in Mix_RegisterEffect, but they are run after all the channels and the
* music have been mixed into a single stream, whereas channel-specific
* effects run on a given channel before any other mixing occurs. These
* global effect callbacks are call "posteffects". Posteffects only have
* their Mix_EffectDone_t function called when they are unregistered (since
* the main output stream is never "done" in the same sense as a channel).
* You must unregister them manually when you've had enough. Your callback
* will be told that the channel being mixed is (MIX_CHANNEL_POST) if the
* processing is considered a posteffect.
*
* After all these effects have finished processing, the callback registered
* through Mix_SetPostMix() runs, and then the stream goes to the audio
* device.
*
* DO NOT EVER call SDL_LockAudio() from your callback function!
*
* returns zero if error (no such channel), nonzero if added.
* Error messages can be retrieved from Mix_GetError().
*/
extern DECLSPEC int SDLCALL Mix_RegisterEffect(int chan, Mix_EffectFunc_t f,
Mix_EffectDone_t d, void *arg);
/* You may not need to call this explicitly, unless you need to stop an
* effect from processing in the middle of a chunk's playback.
* Posteffects are never implicitly unregistered as they are for channels,
* but they may be explicitly unregistered through this function by
* specifying MIX_CHANNEL_POST for a channel.
* returns zero if error (no such channel or effect), nonzero if removed.
* Error messages can be retrieved from Mix_GetError().
*/
extern DECLSPEC int SDLCALL Mix_UnregisterEffect(int channel, Mix_EffectFunc_t f);
/* You may not need to call this explicitly, unless you need to stop all
* effects from processing in the middle of a chunk's playback. Note that
* this will also shut off some internal effect processing, since
* Mix_SetPanning() and others may use this API under the hood. This is
* called internally when a channel completes playback.
* Posteffects are never implicitly unregistered as they are for channels,
* but they may be explicitly unregistered through this function by
* specifying MIX_CHANNEL_POST for a channel.
* returns zero if error (no such channel), nonzero if all effects removed.
* Error messages can be retrieved from Mix_GetError().
*/
extern DECLSPEC int SDLCALL Mix_UnregisterAllEffects(int channel);
#define MIX_EFFECTSMAXSPEED "MIX_EFFECTSMAXSPEED"
/*
* These are the internally-defined mixing effects. They use the same API that
* effects defined in the application use, but are provided here as a
* convenience. Some effects can reduce their quality or use more memory in
* the name of speed; to enable this, make sure the environment variable
* MIX_EFFECTSMAXSPEED (see above) is defined before you call
* Mix_OpenAudio().
*/
/* Set the panning of a channel. The left and right channels are specified
* as integers between 0 and 255, quietest to loudest, respectively.
*
* Technically, this is just individual volume control for a sample with
* two (stereo) channels, so it can be used for more than just panning.
* If you want real panning, call it like this:
*
* Mix_SetPanning(channel, left, 255 - left);
*
* ...which isn't so hard.
*
* Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
* the panning will be done to the final mixed stream before passing it on
* to the audio device.
*
* This uses the Mix_RegisterEffect() API internally, and returns without
* registering the effect function if the audio device is not configured
* for stereo output. Setting both (left) and (right) to 255 causes this
* effect to be unregistered, since that is the data's normal state.
*
* returns zero if error (no such channel or Mix_RegisterEffect() fails),
* nonzero if panning effect enabled. Note that an audio device in mono
* mode is a no-op, but this call will return successful in that case.
* Error messages can be retrieved from Mix_GetError().
*/
extern DECLSPEC int SDLCALL Mix_SetPanning(int channel, Uint8 left, Uint8 right);
/* Set the position of a channel. (angle) is an integer from 0 to 360, that
* specifies the location of the sound in relation to the listener. (angle)
* will be reduced as neccesary (540 becomes 180 degrees, -100 becomes 260).
* Angle 0 is due north, and rotates clockwise as the value increases.
* For efficiency, the precision of this effect may be limited (angles 1
* through 7 might all produce the same effect, 8 through 15 are equal, etc).
* (distance) is an integer between 0 and 255 that specifies the space
* between the sound and the listener. The larger the number, the further
* away the sound is. Using 255 does not guarantee that the channel will be
* culled from the mixing process or be completely silent. For efficiency,
* the precision of this effect may be limited (distance 0 through 5 might
* all produce the same effect, 6 through 10 are equal, etc). Setting (angle)
* and (distance) to 0 unregisters this effect, since the data would be
* unchanged.
*
* If you need more precise positional audio, consider using OpenAL for
* spatialized effects instead of SDL_mixer. This is only meant to be a
* basic effect for simple "3D" games.
*
* If the audio device is configured for mono output, then you won't get
* any effectiveness from the angle; however, distance attenuation on the
* channel will still occur. While this effect will function with stereo
* voices, it makes more sense to use voices with only one channel of sound,
* so when they are mixed through this effect, the positioning will sound
* correct. You can convert them to mono through SDL before giving them to
* the mixer in the first place if you like.
*
* Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
* the positioning will be done to the final mixed stream before passing it
* on to the audio device.
*
* This is a convenience wrapper over Mix_SetDistance() and Mix_SetPanning().
*
* returns zero if error (no such channel or Mix_RegisterEffect() fails),
* nonzero if position effect is enabled.
* Error messages can be retrieved from Mix_GetError().
*/
extern DECLSPEC int SDLCALL Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
/* Set the "distance" of a channel. (distance) is an integer from 0 to 255
* that specifies the location of the sound in relation to the listener.
* Distance 0 is overlapping the listener, and 255 is as far away as possible
* A distance of 255 does not guarantee silence; in such a case, you might
* want to try changing the chunk's volume, or just cull the sample from the
* mixing process with Mix_HaltChannel().
* For efficiency, the precision of this effect may be limited (distances 1
* through 7 might all produce the same effect, 8 through 15 are equal, etc).
* (distance) is an integer between 0 and 255 that specifies the space
* between the sound and the listener. The larger the number, the further
* away the sound is.
* Setting (distance) to 0 unregisters this effect, since the data would be
* unchanged.
* If you need more precise positional audio, consider using OpenAL for
* spatialized effects instead of SDL_mixer. This is only meant to be a
* basic effect for simple "3D" games.
*
* Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
* the distance attenuation will be done to the final mixed stream before
* passing it on to the audio device.
*
* This uses the Mix_RegisterEffect() API internally.
*
* returns zero if error (no such channel or Mix_RegisterEffect() fails),
* nonzero if position effect is enabled.
* Error messages can be retrieved from Mix_GetError().
*/
extern DECLSPEC int SDLCALL Mix_SetDistance(int channel, Uint8 distance);
/*
* !!! FIXME : Haven't implemented, since the effect goes past the
* end of the sound buffer. Will have to think about this.
* --ryan.
*/
#if 0
/* Causes an echo effect to be mixed into a sound. (echo) is the amount
* of echo to mix. 0 is no echo, 255 is infinite (and probably not
* what you want).
*
* Setting (channel) to MIX_CHANNEL_POST registers this as a posteffect, and
* the reverbing will be done to the final mixed stream before passing it on
* to the audio device.
*
* This uses the Mix_RegisterEffect() API internally. If you specify an echo
* of zero, the effect is unregistered, as the data is already in that state.
*
* returns zero if error (no such channel or Mix_RegisterEffect() fails),
* nonzero if reversing effect is enabled.
* Error messages can be retrieved from Mix_GetError().
*/
extern no_parse_DECLSPEC int SDLCALL Mix_SetReverb(int channel, Uint8 echo);
#endif
/* Causes a channel to reverse its stereo. This is handy if the user has his
* speakers hooked up backwards, or you would like to have a minor bit of
* psychedelia in your sound code. :) Calling this function with (flip)
* set to non-zero reverses the chunks's usual channels. If (flip) is zero,
* the effect is unregistered.
*
* This uses the Mix_RegisterEffect() API internally, and thus is probably
* more CPU intensive than having the user just plug in his speakers
* correctly. Mix_SetReverseStereo() returns without registering the effect
* function if the audio device is not configured for stereo output.
*
* If you specify MIX_CHANNEL_POST for (channel), then this the effect is used
* on the final mixed stream before sending it on to the audio device (a
* posteffect).
*
* returns zero if error (no such channel or Mix_RegisterEffect() fails),
* nonzero if reversing effect is enabled. Note that an audio device in mono
* mode is a no-op, but this call will return successful in that case.
* Error messages can be retrieved from Mix_GetError().
*/
extern DECLSPEC int SDLCALL Mix_SetReverseStereo(int channel, int flip);
/* end of effects API. --ryan. */
/* Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate
them dynamically to the next sample if requested with a -1 value below.
Returns the number of reserved channels.
*/
extern DECLSPEC int SDLCALL Mix_ReserveChannels(int num);
/* Channel grouping functions */
/* Attach a tag to a channel. A tag can be assigned to several mixer
channels, to form groups of channels.
If 'tag' is -1, the tag is removed (actually -1 is the tag used to
represent the group of all the channels).
Returns true if everything was OK.
*/
extern DECLSPEC int SDLCALL Mix_GroupChannel(int which, int tag);
/* Assign several consecutive channels to a group */
extern DECLSPEC int SDLCALL Mix_GroupChannels(int from, int to, int tag);
/* Finds the first available channel in a group of channels,
returning -1 if none are available.
*/
extern DECLSPEC int SDLCALL Mix_GroupAvailable(int tag);
/* Returns the number of channels in a group. This is also a subtle
way to get the total number of channels when 'tag' is -1
*/
extern DECLSPEC int SDLCALL Mix_GroupCount(int tag);
/* Finds the "oldest" sample playing in a group of channels */
extern DECLSPEC int SDLCALL Mix_GroupOldest(int tag);
/* Finds the "most recent" (i.e. last) sample playing in a group of channels */
extern DECLSPEC int SDLCALL Mix_GroupNewer(int tag);
/* Play an audio chunk on a specific channel.
If the specified channel is -1, play on the first free channel.
If 'loops' is greater than zero, loop the sound that many times.
If 'loops' is -1, loop inifinitely (~65000 times).
Returns which channel was used to play the sound.
*/
#define Mix_PlayChannel(channel,chunk,loops) Mix_PlayChannelTimed(channel,chunk,loops,-1)
/* The same as above, but the sound is played at most 'ticks' milliseconds */
extern DECLSPEC int SDLCALL Mix_PlayChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ticks);
extern DECLSPEC int SDLCALL Mix_PlayMusic(Mix_Music *music, int loops);
/* Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions */
extern DECLSPEC int SDLCALL Mix_FadeInMusic(Mix_Music *music, int loops, int ms);
extern DECLSPEC int SDLCALL Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position);
#define Mix_FadeInChannel(channel,chunk,loops,ms) Mix_FadeInChannelTimed(channel,chunk,loops,ms,-1)
extern DECLSPEC int SDLCALL Mix_FadeInChannelTimed(int channel, Mix_Chunk *chunk, int loops, int ms, int ticks);
/* Set the volume in the range of 0-128 of a specific channel or chunk.
If the specified channel is -1, set volume for all channels.
Returns the original volume.
If the specified volume is -1, just return the current volume.
*/
extern DECLSPEC int SDLCALL Mix_Volume(int channel, int volume);
extern DECLSPEC int SDLCALL Mix_VolumeChunk(Mix_Chunk *chunk, int volume);
extern DECLSPEC int SDLCALL Mix_VolumeMusic(int volume);
/* Halt playing of a particular channel */
extern DECLSPEC int SDLCALL Mix_HaltChannel(int channel);
extern DECLSPEC int SDLCALL Mix_HaltGroup(int tag);
extern DECLSPEC int SDLCALL Mix_HaltMusic(void);
/* Change the expiration delay for a particular channel.
The sample will stop playing after the 'ticks' milliseconds have elapsed,
or remove the expiration if 'ticks' is -1
*/
extern DECLSPEC int SDLCALL Mix_ExpireChannel(int channel, int ticks);
/* Halt a channel, fading it out progressively till it's silent
The ms parameter indicates the number of milliseconds the fading
will take.
*/
extern DECLSPEC int SDLCALL Mix_FadeOutChannel(int which, int ms);
extern DECLSPEC int SDLCALL Mix_FadeOutGroup(int tag, int ms);
extern DECLSPEC int SDLCALL Mix_FadeOutMusic(int ms);
/* Query the fading status of a channel */
extern DECLSPEC Mix_Fading SDLCALL Mix_FadingMusic(void);
extern DECLSPEC Mix_Fading SDLCALL Mix_FadingChannel(int which);
/* Pause/Resume a particular channel */
extern DECLSPEC void SDLCALL Mix_Pause(int channel);
extern DECLSPEC void SDLCALL Mix_Resume(int channel);
extern DECLSPEC int SDLCALL Mix_Paused(int channel);
/* Pause/Resume the music stream */
extern DECLSPEC void SDLCALL Mix_PauseMusic(void);
extern DECLSPEC void SDLCALL Mix_ResumeMusic(void);
extern DECLSPEC void SDLCALL Mix_RewindMusic(void);
extern DECLSPEC int SDLCALL Mix_PausedMusic(void);
/* Set the current position in the music stream.
This returns 0 if successful, or -1 if it failed or isn't implemented.
This function is only implemented for MOD music formats (set pattern
order number) and for OGG, FLAC, MP3_MAD, and MODPLUG music (set
position in seconds), at the moment.
*/
extern DECLSPEC int SDLCALL Mix_SetMusicPosition(double position);
/* Check the status of a specific channel.
If the specified channel is -1, check all channels.
*/
extern DECLSPEC int SDLCALL Mix_Playing(int channel);
extern DECLSPEC int SDLCALL Mix_PlayingMusic(void);
/* Stop music and set external music playback command */
extern DECLSPEC int SDLCALL Mix_SetMusicCMD(const char *command);
/* Synchro value is set by MikMod from modules while playing */
extern DECLSPEC int SDLCALL Mix_SetSynchroValue(int value);
extern DECLSPEC int SDLCALL Mix_GetSynchroValue(void);
/* Set/Get/Iterate SoundFonts paths to use by supported MIDI backends */
extern DECLSPEC int SDLCALL Mix_SetSoundFonts(const char *paths);
extern DECLSPEC const char* SDLCALL Mix_GetSoundFonts(void);
extern DECLSPEC int SDLCALL Mix_EachSoundFont(int (*function)(const char*, void*), void *data);
/* Get the Mix_Chunk currently associated with a mixer channel
Returns NULL if it's an invalid channel, or there's no chunk associated.
*/
extern DECLSPEC Mix_Chunk * SDLCALL Mix_GetChunk(int channel);
/* Close the mixer, halting all playing audio */
extern DECLSPEC void SDLCALL Mix_CloseAudio(void);
/* We'll use SDL for reporting errors */
#define Mix_SetError SDL_SetError
#define Mix_GetError SDL_GetError
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include "close_code.h"
#endif /* _SDL_MIXER_H */

View File

@ -0,0 +1,66 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
The following file defines all of the functions/objects used to dynamically
link to the libFLAC library.
~ Austen Dicken (admin@cvpcs.org)
*/
#ifdef FLAC_MUSIC
#include <FLAC/stream_decoder.h>
typedef struct {
int loaded;
void *handle;
FLAC__StreamDecoder *(*FLAC__stream_decoder_new)();
void (*FLAC__stream_decoder_delete)(FLAC__StreamDecoder *decoder);
FLAC__StreamDecoderInitStatus (*FLAC__stream_decoder_init_stream)(
FLAC__StreamDecoder *decoder,
FLAC__StreamDecoderReadCallback read_callback,
FLAC__StreamDecoderSeekCallback seek_callback,
FLAC__StreamDecoderTellCallback tell_callback,
FLAC__StreamDecoderLengthCallback length_callback,
FLAC__StreamDecoderEofCallback eof_callback,
FLAC__StreamDecoderWriteCallback write_callback,
FLAC__StreamDecoderMetadataCallback metadata_callback,
FLAC__StreamDecoderErrorCallback error_callback,
void *client_data);
FLAC__bool (*FLAC__stream_decoder_finish)(FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_flush)(FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_process_single)(
FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_process_until_end_of_metadata)(
FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_process_until_end_of_stream)(
FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_seek_absolute)(
FLAC__StreamDecoder *decoder,
FLAC__uint64 sample);
FLAC__StreamDecoderState (*FLAC__stream_decoder_get_state)(
const FLAC__StreamDecoder *decoder);
} flac_loader;
extern flac_loader flac;
#endif /* FLAC_MUSIC */
extern int Mix_InitFLAC();
extern void Mix_QuitFLAC();

View File

@ -0,0 +1,57 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
James Le Cuirot
chewi@aura-online.co.uk
*/
#ifdef USE_FLUIDSYNTH_MIDI
#include <fluidsynth.h>
typedef struct {
int loaded;
void *handle;
int (*delete_fluid_player)(fluid_player_t*);
void (*delete_fluid_settings)(fluid_settings_t*);
int (*delete_fluid_synth)(fluid_synth_t*);
int (*fluid_player_add)(fluid_player_t*, const char*);
int (*fluid_player_add_mem)(fluid_player_t*, const void*, size_t);
int (*fluid_player_get_status)(fluid_player_t*);
int (*fluid_player_play)(fluid_player_t*);
int (*fluid_player_set_loop)(fluid_player_t*, int);
int (*fluid_player_stop)(fluid_player_t*);
int (*fluid_settings_setnum)(fluid_settings_t*, const char*, double);
fluid_settings_t* (*fluid_synth_get_settings)(fluid_synth_t*);
void (*fluid_synth_set_gain)(fluid_synth_t*, float);
int (*fluid_synth_sfload)(fluid_synth_t*, const char*, int);
int (*fluid_synth_write_s16)(fluid_synth_t*, int, void*, int, int, void*, int, int);
fluid_player_t* (*new_fluid_player)(fluid_synth_t*);
fluid_settings_t* (*new_fluid_settings)(void);
fluid_synth_t* (*new_fluid_synth)(fluid_settings_t*);
} fluidsynth_loader;
extern fluidsynth_loader fluidsynth;
#endif /* USE_FLUIDSYNTH_MIDI */
extern int Mix_InitFluidSynth();
extern void Mix_QuitFluidSynth();

View File

@ -0,0 +1,62 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifdef MOD_MUSIC
#include "mikmod.h"
typedef struct {
int loaded;
void *handle;
void (*MikMod_Exit)(void);
CHAR* (*MikMod_InfoDriver)(void);
CHAR* (*MikMod_InfoLoader)(void);
BOOL (*MikMod_Init)(CHAR*);
void (*MikMod_RegisterAllLoaders)(void);
void (*MikMod_RegisterDriver)(struct MDRIVER*);
int* MikMod_errno;
char* (*MikMod_strerror)(int);
BOOL (*Player_Active)(void);
void (*Player_Free)(MODULE*);
MODULE* (*Player_LoadGeneric)(MREADER*,int,BOOL);
void (*Player_SetPosition)(UWORD);
void (*Player_SetVolume)(SWORD);
void (*Player_Start)(MODULE*);
void (*Player_Stop)(void);
ULONG (*VC_WriteBytes)(SBYTE*,ULONG);
struct MDRIVER* drv_nos;
UWORD* md_device;
UWORD* md_mixfreq;
UWORD* md_mode;
UBYTE* md_musicvolume;
UBYTE* md_pansep;
UBYTE* md_reverb;
UBYTE* md_sndfxvolume;
UBYTE* md_volume;
} mikmod_loader;
extern mikmod_loader mikmod;
#endif /* MOD_MUSIC */
extern int Mix_InitMOD();
extern void Mix_QuitMOD();

View File

@ -0,0 +1,47 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifdef MP3_MUSIC
#include "smpeg.h"
typedef struct {
int loaded;
void *handle;
void (*SMPEG_actualSpec)( SMPEG *mpeg, SDL_AudioSpec *spec );
void (*SMPEG_delete)( SMPEG* mpeg );
void (*SMPEG_enableaudio)( SMPEG* mpeg, int enable );
void (*SMPEG_enablevideo)( SMPEG* mpeg, int enable );
SMPEG* (*SMPEG_new_rwops)(SDL_RWops *src, SMPEG_Info* info, int sdl_audio);
void (*SMPEG_play)( SMPEG* mpeg );
int (*SMPEG_playAudio)( SMPEG *mpeg, Uint8 *stream, int len );
void (*SMPEG_rewind)( SMPEG* mpeg );
void (*SMPEG_setvolume)( SMPEG* mpeg, int volume );
void (*SMPEG_skip)( SMPEG* mpeg, float seconds );
SMPEGstatus (*SMPEG_status)( SMPEG* mpeg );
void (*SMPEG_stop)( SMPEG* mpeg );
} smpeg_loader;
extern smpeg_loader smpeg;
#endif /* MUSIC_MP3 */
extern int Mix_InitMP3();
extern void Mix_QuitMP3();

View File

@ -0,0 +1,53 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifdef OGG_MUSIC
#ifdef OGG_USE_TREMOR
#include <tremor/ivorbisfile.h>
#else
#include <vorbis/vorbisfile.h>
#endif
typedef struct {
int loaded;
void *handle;
int (*ov_clear)(OggVorbis_File *vf);
vorbis_info *(*ov_info)(OggVorbis_File *vf,int link);
int (*ov_open_callbacks)(void *datasource, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks);
ogg_int64_t (*ov_pcm_total)(OggVorbis_File *vf,int i);
#ifdef OGG_USE_TREMOR
long (*ov_read)(OggVorbis_File *vf,char *buffer,int length, int *bitstream);
#else
long (*ov_read)(OggVorbis_File *vf,char *buffer,int length, int bigendianp,int word,int sgned,int *bitstream);
#endif
#ifdef OGG_USE_TREMOR
int (*ov_time_seek)(OggVorbis_File *vf,ogg_int64_t pos);
#else
int (*ov_time_seek)(OggVorbis_File *vf,double pos);
#endif
} vorbis_loader;
extern vorbis_loader vorbis;
#endif /* OGG_MUSIC */
extern int Mix_InitOgg();
extern void Mix_QuitOgg();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,124 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
This file by Ryan C. Gordon (icculus@icculus.org)
These are some helper functions for the internal mixer special effects.
*/
/* $Id$ */
/* ------ These are used internally only. Don't touch. ------ */
#include <stdio.h>
#include <stdlib.h>
#include "SDL_mixer.h"
#define __MIX_INTERNAL_EFFECT__
#include "effects_internal.h"
/* Should we favor speed over memory usage and/or quality of output? */
int _Mix_effects_max_speed = 0;
void _Mix_InitEffects(void)
{
_Mix_effects_max_speed = (SDL_getenv(MIX_EFFECTSMAXSPEED) != NULL);
}
void _Mix_DeinitEffects(void)
{
_Eff_PositionDeinit();
}
void *_Eff_volume_table = NULL;
/* Build the volume table for Uint8-format samples.
*
* Each column of the table is a possible sample, while each row of the
* table is a volume. Volume is a Uint8, where 0 is silence and 255 is full
* volume. So _Eff_volume_table[128][mysample] would be the value of
* mysample, at half volume.
*/
void *_Eff_build_volume_table_u8(void)
{
int volume;
int sample;
Uint8 *rc;
if (!_Mix_effects_max_speed) {
return(NULL);
}
if (!_Eff_volume_table) {
rc = SDL_malloc(256 * 256);
if (rc) {
_Eff_volume_table = (void *) rc;
for (volume = 0; volume < 256; volume++) {
for (sample = -128; sample < 128; sample ++) {
*rc = (Uint8)(((float) sample) * ((float) volume / 255.0))
+ 128;
rc++;
}
}
}
}
return(_Eff_volume_table);
}
/* Build the volume table for Sint8-format samples.
*
* Each column of the table is a possible sample, while each row of the
* table is a volume. Volume is a Uint8, where 0 is silence and 255 is full
* volume. So _Eff_volume_table[128][mysample+128] would be the value of
* mysample, at half volume.
*/
void *_Eff_build_volume_table_s8(void)
{
int volume;
int sample;
Sint8 *rc;
if (!_Eff_volume_table) {
rc = SDL_malloc(256 * 256);
if (rc) {
_Eff_volume_table = (void *) rc;
for (volume = 0; volume < 256; volume++) {
for (sample = -128; sample < 128; sample ++) {
*rc = (Sint8)(((float) sample) * ((float) volume / 255.0));
rc++;
}
}
}
}
return(_Eff_volume_table);
}
/* end of effects.c ... */

View File

@ -0,0 +1,60 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id$ */
#ifndef _INCLUDE_EFFECTS_INTERNAL_H_
#define _INCLUDE_EFFECTS_INTERNAL_H_
#ifndef __MIX_INTERNAL_EFFECT__
#error You should not include this file or use these functions.
#endif
#include "SDL_mixer.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
extern int _Mix_effects_max_speed;
extern void *_Eff_volume_table;
void *_Eff_build_volume_table_u8(void);
void *_Eff_build_volume_table_s8(void);
void _Mix_InitEffects(void);
void _Mix_DeinitEffects(void);
void _Eff_PositionDeinit(void);
int _Mix_RegisterEffect_locked(int channel, Mix_EffectFunc_t f,
Mix_EffectDone_t d, void *arg);
int _Mix_UnregisterEffect_locked(int channel, Mix_EffectFunc_t f);
int _Mix_UnregisterAllEffects_locked(int channel);
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,51 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
James Le Cuirot
chewi@aura-online.co.uk
*/
#ifndef _FLUIDSYNTH_H_
#define _FLUIDSYNTH_H_
#ifdef USE_FLUIDSYNTH_MIDI
#include "dynamic_fluidsynth.h"
#include <SDL_rwops.h>
#include <SDL_audio.h>
typedef struct {
SDL_AudioCVT convert;
fluid_synth_t *synth;
fluid_player_t* player;
} FluidSynthMidiSong;
int fluidsynth_init(SDL_AudioSpec *mixer);
FluidSynthMidiSong *fluidsynth_loadsong_RW(SDL_RWops *rw, int freerw);
void fluidsynth_freesong(FluidSynthMidiSong *song);
void fluidsynth_start(FluidSynthMidiSong *song);
void fluidsynth_stop(FluidSynthMidiSong *song);
int fluidsynth_active(FluidSynthMidiSong *song);
void fluidsynth_setvolume(FluidSynthMidiSong *song, int volume);
int fluidsynth_playsome(FluidSynthMidiSong *song, void *stream, int len);
#endif /* USE_FLUIDSYNTH_MIDI */
#endif /* _FLUIDSYNTH_H_ */

View File

@ -0,0 +1,250 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
This is the source needed to decode an AIFF file into a waveform.
It's pretty straightforward once you get going. The only
externally-callable function is Mix_LoadAIFF_RW(), which is meant to
act as identically to SDL_LoadWAV_RW() as possible.
This file by Torbjörn Andersson (torbjorn.andersson@eurotime.se)
8SVX file support added by Marc Le Douarain (mavati@club-internet.fr)
in december 2002.
*/
/* $Id$ */
#include <stdlib.h>
#include <string.h>
#include "SDL_endian.h"
#include "SDL_mixer.h"
#include "load_aiff.h"
/*********************************************/
/* Define values for AIFF (IFF audio) format */
/*********************************************/
#define FORM 0x4d524f46 /* "FORM" */
#define AIFF 0x46464941 /* "AIFF" */
#define SSND 0x444e5353 /* "SSND" */
#define COMM 0x4d4d4f43 /* "COMM" */
#define _8SVX 0x58565338 /* "8SVX" */
#define VHDR 0x52444856 /* "VHDR" */
#define BODY 0x59444F42 /* "BODY" */
/* This function was taken from libsndfile. I don't pretend to fully
* understand it.
*/
static Uint32 SANE_to_Uint32 (Uint8 *sanebuf)
{
/* Is the frequency outside of what we can represent with Uint32? */
if ( (sanebuf[0] & 0x80) || (sanebuf[0] <= 0x3F) || (sanebuf[0] > 0x40)
|| (sanebuf[0] == 0x40 && sanebuf[1] > 0x1C) )
return 0;
return ((sanebuf[2] << 23) | (sanebuf[3] << 15) | (sanebuf[4] << 7)
| (sanebuf[5] >> 1)) >> (29 - sanebuf[1]);
}
/* This function is based on SDL_LoadWAV_RW(). */
SDL_AudioSpec *Mix_LoadAIFF_RW (SDL_RWops *src, int freesrc,
SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
{
int was_error;
int found_SSND;
int found_COMM;
int found_VHDR;
int found_BODY;
long start = 0;
Uint32 chunk_type;
Uint32 chunk_length;
long next_chunk;
/* AIFF magic header */
Uint32 FORMchunk;
Uint32 AIFFmagic;
/* SSND chunk */
Uint32 offset;
Uint32 blocksize;
/* COMM format chunk */
Uint16 channels = 0;
Uint32 numsamples = 0;
Uint16 samplesize = 0;
Uint8 sane_freq[10];
Uint32 frequency = 0;
/* Make sure we are passed a valid data source */
was_error = 0;
if ( src == NULL ) {
was_error = 1;
goto done;
}
FORMchunk = SDL_ReadLE32(src);
chunk_length = SDL_ReadBE32(src);
if ( chunk_length == AIFF ) { /* The FORMchunk has already been read */
AIFFmagic = chunk_length;
chunk_length = FORMchunk;
FORMchunk = FORM;
} else {
AIFFmagic = SDL_ReadLE32(src);
}
if ( (FORMchunk != FORM) || ( (AIFFmagic != AIFF) && (AIFFmagic != _8SVX) ) ) {
SDL_SetError("Unrecognized file type (not AIFF nor 8SVX)");
was_error = 1;
goto done;
}
/* TODO: Better santity-checking. */
found_SSND = 0;
found_COMM = 0;
found_VHDR = 0;
found_BODY = 0;
do {
chunk_type = SDL_ReadLE32(src);
chunk_length = SDL_ReadBE32(src);
next_chunk = SDL_RWtell(src) + chunk_length;
/* Paranoia to avoid infinite loops */
if (chunk_length == 0)
break;
switch (chunk_type) {
case SSND:
found_SSND = 1;
offset = SDL_ReadBE32(src);
blocksize = SDL_ReadBE32(src);
start = SDL_RWtell(src) + offset;
break;
case COMM:
found_COMM = 1;
channels = SDL_ReadBE16(src);
numsamples = SDL_ReadBE32(src);
samplesize = SDL_ReadBE16(src);
SDL_RWread(src, sane_freq, sizeof(sane_freq), 1);
frequency = SANE_to_Uint32(sane_freq);
if (frequency == 0) {
SDL_SetError("Bad AIFF sample frequency");
was_error = 1;
goto done;
}
break;
case VHDR:
found_VHDR = 1;
SDL_ReadBE32(src);
SDL_ReadBE32(src);
SDL_ReadBE32(src);
frequency = SDL_ReadBE16(src);
channels = 1;
samplesize = 8;
break;
case BODY:
found_BODY = 1;
numsamples = chunk_length;
start = SDL_RWtell(src);
break;
default:
break;
}
/* a 0 pad byte can be stored for any odd-length chunk */
if (chunk_length&1)
next_chunk++;
} while ( ( ( (AIFFmagic == AIFF) && ( !found_SSND || !found_COMM ) )
|| ( (AIFFmagic == _8SVX ) && ( !found_VHDR || !found_BODY ) ) )
&& SDL_RWseek(src, next_chunk, RW_SEEK_SET) != 1 );
if ( (AIFFmagic == AIFF) && !found_SSND ) {
SDL_SetError("Bad AIFF (no SSND chunk)");
was_error = 1;
goto done;
}
if ( (AIFFmagic == AIFF) && !found_COMM ) {
SDL_SetError("Bad AIFF (no COMM chunk)");
was_error = 1;
goto done;
}
if ( (AIFFmagic == _8SVX) && !found_VHDR ) {
SDL_SetError("Bad 8SVX (no VHDR chunk)");
was_error = 1;
goto done;
}
if ( (AIFFmagic == _8SVX) && !found_BODY ) {
SDL_SetError("Bad 8SVX (no BODY chunk)");
was_error = 1;
goto done;
}
/* Decode the audio data format */
memset(spec, 0, sizeof(*spec));
spec->freq = frequency;
switch (samplesize) {
case 8:
spec->format = AUDIO_S8;
break;
case 16:
spec->format = AUDIO_S16MSB;
break;
default:
SDL_SetError("Unsupported AIFF samplesize");
was_error = 1;
goto done;
}
spec->channels = (Uint8) channels;
spec->samples = 4096; /* Good default buffer size */
*audio_len = channels * numsamples * (samplesize / 8);
*audio_buf = (Uint8 *)SDL_malloc(*audio_len);
if ( *audio_buf == NULL ) {
SDL_SetError("Out of memory");
return(NULL);
}
SDL_RWseek(src, start, RW_SEEK_SET);
if ( SDL_RWread(src, *audio_buf, *audio_len, 1) != 1 ) {
SDL_SetError("Unable to read audio data");
return(NULL);
}
/* Don't return a buffer that isn't a multiple of samplesize */
*audio_len &= ~((samplesize / 8) - 1);
done:
if ( freesrc && src ) {
SDL_RWclose(src);
}
if ( was_error ) {
spec = NULL;
}
return(spec);
}

View File

@ -0,0 +1,31 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2009 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
This is the source needed to decode an AIFF file into a waveform.
It's pretty straightforward once you get going. The only
externally-callable function is Mix_LoadAIFF_RW(), which is meant to
act as identically to SDL_LoadWAV_RW() as possible.
This file by Torbjörn Andersson (torbjorn.andersson@eurotime.se)
*/
/* $Id$ */
/* Don't call this directly; use Mix_LoadWAV_RW() for now. */
SDL_AudioSpec *Mix_LoadAIFF_RW (SDL_RWops *src, int freesrc,
SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);

View File

@ -0,0 +1,31 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
This is the source needed to decode a FLAC into a waveform.
~ Austen Dicken (admin@cvpcs.org).
*/
/* $Id: $ */
#ifdef FLAC_MUSIC
/* Don't call this directly; use Mix_LoadWAV_RW() for now. */
SDL_AudioSpec *Mix_LoadFLAC_RW (SDL_RWops *src, int freesrc,
SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);
#endif

View File

@ -0,0 +1,31 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
This is the source needed to decode an Ogg Vorbis into a waveform.
This file by Vaclav Slavik (vaclav.slavik@matfyz.cz).
*/
/* $Id$ */
#ifdef OGG_MUSIC
/* Don't call this directly; use Mix_LoadWAV_RW() for now. */
SDL_AudioSpec *Mix_LoadOGG_RW (SDL_RWops *src, int freesrc,
SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);
#endif

View File

@ -0,0 +1,462 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
This is the source needed to decode a Creative Labs VOC file into a
waveform. It's pretty straightforward once you get going. The only
externally-callable function is Mix_LoadVOC_RW(), which is meant to
act as identically to SDL_LoadWAV_RW() as possible.
This file by Ryan C. Gordon (icculus@icculus.org).
Heavily borrowed from sox v12.17.1's voc.c.
(http://www.freshmeat.net/projects/sox/)
*/
/* $Id$ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL_mutex.h"
#include "SDL_endian.h"
#include "SDL_timer.h"
#include "SDL_mixer.h"
#include "load_voc.h"
/* Private data for VOC file */
typedef struct vocstuff {
Uint32 rest; /* bytes remaining in current block */
Uint32 rate; /* rate code (byte) of this chunk */
int silent; /* sound or silence? */
Uint32 srate; /* rate code (byte) of silence */
Uint32 blockseek; /* start of current output block */
Uint32 samples; /* number of samples output */
Uint32 size; /* word length of data */
Uint8 channels; /* number of sound channels */
int has_extended; /* Has an extended block been read? */
} vs_t;
/* Size field */
/* SJB: note that the 1st 3 are sometimes used as sizeof(type) */
#define ST_SIZE_BYTE 1
#define ST_SIZE_8BIT 1
#define ST_SIZE_WORD 2
#define ST_SIZE_16BIT 2
#define ST_SIZE_DWORD 4
#define ST_SIZE_32BIT 4
#define ST_SIZE_FLOAT 5
#define ST_SIZE_DOUBLE 6
#define ST_SIZE_IEEE 7 /* IEEE 80-bit floats. */
/* Style field */
#define ST_ENCODING_UNSIGNED 1 /* unsigned linear: Sound Blaster */
#define ST_ENCODING_SIGN2 2 /* signed linear 2's comp: Mac */
#define ST_ENCODING_ULAW 3 /* U-law signed logs: US telephony, SPARC */
#define ST_ENCODING_ALAW 4 /* A-law signed logs: non-US telephony */
#define ST_ENCODING_ADPCM 5 /* Compressed PCM */
#define ST_ENCODING_IMA_ADPCM 6 /* Compressed PCM */
#define ST_ENCODING_GSM 7 /* GSM 6.10 33-byte frame lossy compression */
#define VOC_TERM 0
#define VOC_DATA 1
#define VOC_CONT 2
#define VOC_SILENCE 3
#define VOC_MARKER 4
#define VOC_TEXT 5
#define VOC_LOOP 6
#define VOC_LOOPEND 7
#define VOC_EXTENDED 8
#define VOC_DATA_16 9
static int voc_check_header(SDL_RWops *src)
{
/* VOC magic header */
Uint8 signature[20]; /* "Creative Voice File\032" */
Uint16 datablockofs;
SDL_RWseek(src, 0, RW_SEEK_SET);
if (SDL_RWread(src, signature, sizeof (signature), 1) != 1)
return(0);
if (memcmp(signature, "Creative Voice File\032", sizeof (signature)) != 0) {
SDL_SetError("Unrecognized file type (not VOC)");
return(0);
}
/* get the offset where the first datablock is located */
if (SDL_RWread(src, &datablockofs, sizeof (Uint16), 1) != 1)
return(0);
datablockofs = SDL_SwapLE16(datablockofs);
if (SDL_RWseek(src, datablockofs, RW_SEEK_SET) != datablockofs)
return(0);
return(1); /* success! */
} /* voc_check_header */
/* Read next block header, save info, leave position at start of data */
static int voc_get_block(SDL_RWops *src, vs_t *v, SDL_AudioSpec *spec)
{
Uint8 bits24[3];
Uint8 uc, block;
Uint32 sblen;
Uint16 new_rate_short;
Uint32 new_rate_long;
Uint8 trash[6];
Uint16 period;
unsigned int i;
v->silent = 0;
while (v->rest == 0)
{
if (SDL_RWread(src, &block, sizeof (block), 1) != 1)
return 1; /* assume that's the end of the file. */
if (block == VOC_TERM)
return 1;
if (SDL_RWread(src, bits24, sizeof (bits24), 1) != 1)
return 1; /* assume that's the end of the file. */
/* Size is an 24-bit value. Ugh. */
sblen = ( (bits24[0]) | (bits24[1] << 8) | (bits24[2] << 16) );
switch(block)
{
case VOC_DATA:
if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
return 0;
/* When DATA block preceeded by an EXTENDED */
/* block, the DATA blocks rate value is invalid */
if (!v->has_extended)
{
if (uc == 0)
{
SDL_SetError("VOC Sample rate is zero?");
return 0;
}
if ((v->rate != -1) && (uc != v->rate))
{
SDL_SetError("VOC sample rate codes differ");
return 0;
}
v->rate = uc;
spec->freq = (Uint16)(1000000.0/(256 - v->rate));
v->channels = 1;
}
if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
return 0;
if (uc != 0)
{
SDL_SetError("VOC decoder only interprets 8-bit data");
return 0;
}
v->has_extended = 0;
v->rest = sblen - 2;
v->size = ST_SIZE_BYTE;
return 1;
case VOC_DATA_16:
if (SDL_RWread(src, &new_rate_long, sizeof (new_rate_long), 1) != 1)
return 0;
new_rate_long = SDL_SwapLE32(new_rate_long);
if (new_rate_long == 0)
{
SDL_SetError("VOC Sample rate is zero?");
return 0;
}
if ((v->rate != -1) && (new_rate_long != v->rate))
{
SDL_SetError("VOC sample rate codes differ");
return 0;
}
v->rate = new_rate_long;
spec->freq = new_rate_long;
if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
return 0;
switch (uc)
{
case 8: v->size = ST_SIZE_BYTE; break;
case 16: v->size = ST_SIZE_WORD; break;
default:
SDL_SetError("VOC with unknown data size");
return 0;
}
if (SDL_RWread(src, &v->channels, sizeof (Uint8), 1) != 1)
return 0;
if (SDL_RWread(src, trash, sizeof (Uint8), 6) != 6)
return 0;
v->rest = sblen - 12;
return 1;
case VOC_CONT:
v->rest = sblen;
return 1;
case VOC_SILENCE:
if (SDL_RWread(src, &period, sizeof (period), 1) != 1)
return 0;
period = SDL_SwapLE16(period);
if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
return 0;
if (uc == 0)
{
SDL_SetError("VOC silence sample rate is zero");
return 0;
}
/*
* Some silence-packed files have gratuitously
* different sample rate codes in silence.
* Adjust period.
*/
if ((v->rate != -1) && (uc != v->rate))
period = (Uint16)((period * (256 - uc))/(256 - v->rate));
else
v->rate = uc;
v->rest = period;
v->silent = 1;
return 1;
case VOC_LOOP:
case VOC_LOOPEND:
for(i = 0; i < sblen; i++) /* skip repeat loops. */
{
if (SDL_RWread(src, trash, sizeof (Uint8), 1) != 1)
return 0;
}
break;
case VOC_EXTENDED:
/* An Extended block is followed by a data block */
/* Set this byte so we know to use the rate */
/* value from the extended block and not the */
/* data block. */
v->has_extended = 1;
if (SDL_RWread(src, &new_rate_short, sizeof (new_rate_short), 1) != 1)
return 0;
new_rate_short = SDL_SwapLE16(new_rate_short);
if (new_rate_short == 0)
{
SDL_SetError("VOC sample rate is zero");
return 0;
}
if ((v->rate != -1) && (new_rate_short != v->rate))
{
SDL_SetError("VOC sample rate codes differ");
return 0;
}
v->rate = new_rate_short;
if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
return 0;
if (uc != 0)
{
SDL_SetError("VOC decoder only interprets 8-bit data");
return 0;
}
if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
return 0;
if (uc)
spec->channels = 2; /* Stereo */
/* Needed number of channels before finishing
compute for rate */
spec->freq = (256000000L/(65536L - v->rate))/spec->channels;
/* An extended block must be followed by a data */
/* block to be valid so loop back to top so it */
/* can be grabed. */
continue;
case VOC_MARKER:
if (SDL_RWread(src, trash, sizeof (Uint8), 2) != 2)
return 0;
/* Falling! Falling! */
default: /* text block or other krapola. */
for(i = 0; i < sblen; i++)
{
if (SDL_RWread(src, &trash, sizeof (Uint8), 1) != 1)
return 0;
}
if (block == VOC_TEXT)
continue; /* get next block */
}
}
return 1;
}
static int voc_read(SDL_RWops *src, vs_t *v, Uint8 *buf, SDL_AudioSpec *spec)
{
int done = 0;
Uint8 silence = 0x80;
if (v->rest == 0)
{
if (!voc_get_block(src, v, spec))
return 0;
}
if (v->rest == 0)
return 0;
if (v->silent)
{
if (v->size == ST_SIZE_WORD)
silence = 0x00;
/* Fill in silence */
memset(buf, silence, v->rest);
done = v->rest;
v->rest = 0;
}
else
{
done = SDL_RWread(src, buf, 1, v->rest);
v->rest -= done;
if (v->size == ST_SIZE_WORD)
{
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
Uint16 *samples = (Uint16 *)buf;
for (; v->rest > 0; v->rest -= 2)
{
*samples = SDL_SwapLE16(*samples);
samples++;
}
#endif
done >>= 1;
}
}
return done;
} /* voc_read */
/* don't call this directly; use Mix_LoadWAV_RW() for now. */
SDL_AudioSpec *Mix_LoadVOC_RW (SDL_RWops *src, int freesrc,
SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
{
vs_t v;
int was_error = 1;
int samplesize;
Uint8 *fillptr;
void *ptr;
if ( (!src) || (!audio_buf) || (!audio_len) ) /* sanity checks. */
goto done;
if ( !voc_check_header(src) )
goto done;
v.rate = -1;
v.rest = 0;
v.has_extended = 0;
*audio_buf = NULL;
*audio_len = 0;
memset(spec, '\0', sizeof (SDL_AudioSpec));
if (!voc_get_block(src, &v, spec))
goto done;
if (v.rate == -1)
{
SDL_SetError("VOC data had no sound!");
goto done;
}
spec->format = ((v.size == ST_SIZE_WORD) ? AUDIO_S16 : AUDIO_U8);
if (spec->channels == 0)
spec->channels = v.channels;
*audio_len = v.rest;
*audio_buf = SDL_malloc(v.rest);
if (*audio_buf == NULL)
goto done;
fillptr = *audio_buf;
while (voc_read(src, &v, fillptr, spec) > 0)
{
if (!voc_get_block(src, &v, spec))
goto done;
*audio_len += v.rest;
ptr = SDL_realloc(*audio_buf, *audio_len);
if (ptr == NULL)
{
SDL_free(*audio_buf);
*audio_buf = NULL;
*audio_len = 0;
goto done;
}
*audio_buf = ptr;
fillptr = ((Uint8 *) ptr) + (*audio_len - v.rest);
}
spec->samples = (Uint16)(*audio_len / v.size);
was_error = 0; /* success, baby! */
/* 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 (src)
{
if (freesrc)
SDL_RWclose(src);
else
SDL_RWseek(src, 0, RW_SEEK_SET);
}
if ( was_error )
spec = NULL;
return(spec);
} /* Mix_LoadVOC_RW */
/* end of load_voc.c ... */

View File

@ -0,0 +1,36 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
This is the source needed to decode a Creative Labs VOC file into a
waveform. It's pretty straightforward once you get going. The only
externally-callable function is Mix_LoadVOC_RW(), which is meant to
act as identically to SDL_LoadWAV_RW() as possible.
This file by Ryan C. Gordon (icculus@icculus.org).
Heavily borrowed from sox v12.17.1's voc.c.
(http://www.freshmeat.net/projects/sox/)
*/
/* $Id$ */
/* Don't call this directly; use Mix_LoadWAV_RW() for now. */
SDL_AudioSpec *Mix_LoadVOC_RW (SDL_RWops *src, int freesrc,
SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* This file supports an external command for playing music */
#ifdef CMD_MUSIC
#include <sys/types.h>
#include <limits.h>
#include <stdio.h>
#if defined(__linux__) && defined(__arm__)
# include <linux/limits.h>
#endif
typedef struct {
char file[PATH_MAX];
char cmd[PATH_MAX];
pid_t pid;
} MusicCMD;
/* Unimplemented */
extern void MusicCMD_SetVolume(int volume);
/* Load a music stream from the given file */
extern MusicCMD *MusicCMD_LoadSong(const char *cmd, const char *file);
/* Start playback of a given music stream */
extern void MusicCMD_Start(MusicCMD *music);
/* Stop playback of a stream previously started with MusicCMD_Start() */
extern void MusicCMD_Stop(MusicCMD *music);
/* Pause playback of a given music stream */
extern void MusicCMD_Pause(MusicCMD *music);
/* Resume playback of a given music stream */
extern void MusicCMD_Resume(MusicCMD *music);
/* Close the given music stream */
extern void MusicCMD_FreeSong(MusicCMD *music);
/* Return non-zero if a stream is currently playing */
extern int MusicCMD_Active(MusicCMD *music);
#endif /* CMD_MUSIC */

View File

@ -0,0 +1,90 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Header to handle loading FLAC music files in SDL.
~ Austen Dicken (admin@cvpcs.org)
*/
/* $Id: $ */
#ifdef FLAC_MUSIC
#include <FLAC/stream_decoder.h>
typedef struct {
FLAC__uint64 sample_size;
unsigned sample_rate;
unsigned channels;
unsigned bits_per_sample;
FLAC__uint64 total_samples;
// the following are used to handle the callback nature of the writer
int max_to_read;
char *data; // pointer to beginning of data array
int data_len; // size of data array
int data_read; // amount of data array used
char *overflow; // pointer to beginning of overflow array
int overflow_len; // size of overflow array
int overflow_read; // amount of overflow array used
} FLAC_Data;
typedef struct {
int playing;
int volume;
int section;
FLAC__StreamDecoder *flac_decoder;
FLAC_Data flac_data;
SDL_RWops *rwops;
int freerw;
SDL_AudioCVT cvt;
int len_available;
Uint8 *snd_available;
} FLAC_music;
/* Initialize the FLAC player, with the given mixer settings
This function returns 0, or -1 if there was an error.
*/
extern int FLAC_init(SDL_AudioSpec *mixer);
/* Set the volume for a FLAC stream */
extern void FLAC_setvolume(FLAC_music *music, int volume);
/* Load an FLAC stream from an SDL_RWops object */
extern FLAC_music *FLAC_new_RW(SDL_RWops *rw, int freerw);
/* Start playback of a given FLAC stream */
extern void FLAC_play(FLAC_music *music);
/* Return non-zero if a stream is currently playing */
extern int FLAC_playing(FLAC_music *music);
/* Play some of a stream previously started with FLAC_play() */
extern int FLAC_playAudio(FLAC_music *music, Uint8 *stream, int len);
/* Stop playback of a stream previously started with FLAC_play() */
extern void FLAC_stop(FLAC_music *music);
/* Close the given FLAC stream */
extern void FLAC_delete(FLAC_music *music);
/* Jump (seek) to a given position (time is in seconds) */
extern void FLAC_jump_to_time(FLAC_music *music, double time);
#endif /* FLAC_MUSIC */

View File

@ -0,0 +1,72 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifdef MP3_MAD_MUSIC
#include "mad.h"
#include "SDL_rwops.h"
#include "SDL_audio.h"
#include "SDL_mixer.h"
#define MAD_INPUT_BUFFER_SIZE (5*8192)
#define MAD_OUTPUT_BUFFER_SIZE 8192
enum {
MS_input_eof = 0x0001,
MS_input_error = 0x0001,
MS_decode_eof = 0x0002,
MS_decode_error = 0x0004,
MS_error_flags = 0x000f,
MS_playing = 0x0100,
MS_cvt_decoded = 0x0200,
};
typedef struct {
SDL_RWops *rw;
int freerw;
struct mad_stream stream;
struct mad_frame frame;
struct mad_synth synth;
int frames_read;
mad_timer_t next_frame_start;
int volume;
int status;
int output_begin, output_end;
SDL_AudioSpec mixer;
SDL_AudioCVT cvt;
unsigned char input_buffer[MAD_INPUT_BUFFER_SIZE + MAD_BUFFER_GUARD];
unsigned char output_buffer[MAD_OUTPUT_BUFFER_SIZE];
} mad_data;
mad_data *mad_openFileRW(SDL_RWops *rw, SDL_AudioSpec *mixer, int freerw);
void mad_closeFile(mad_data *mp3_mad);
void mad_start(mad_data *mp3_mad);
void mad_stop(mad_data *mp3_mad);
int mad_isPlaying(mad_data *mp3_mad);
int mad_getSamples(mad_data *mp3_mad, Uint8 *stream, int len);
void mad_seek(mad_data *mp3_mad, double position);
void mad_setVolume(mad_data *mp3_mad, int volume);
#endif

View File

@ -0,0 +1,62 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id: music_mod.h 4211 2008-12-08 00:27:32Z slouken $ */
#ifdef MOD_MUSIC
/* This file supports MOD tracker music streams */
struct MODULE;
/* Initialize the Ogg Vorbis player, with the given mixer settings
This function returns 0, or -1 if there was an error.
*/
extern int MOD_init(SDL_AudioSpec *mixer);
/* Uninitialize the music players */
extern void MOD_exit(void);
/* Set the volume for a MOD stream */
extern void MOD_setvolume(struct MODULE *music, int volume);
/* Load a MOD stream from an SDL_RWops object */
extern struct MODULE *MOD_new_RW(SDL_RWops *rw, int freerw);
/* Start playback of a given MOD stream */
extern void MOD_play(struct MODULE *music);
/* Return non-zero if a stream is currently playing */
extern int MOD_playing(struct MODULE *music);
/* Play some of a stream previously started with MOD_play() */
extern int MOD_playAudio(struct MODULE *music, Uint8 *stream, int len);
/* Stop playback of a stream previously started with MOD_play() */
extern void MOD_stop(struct MODULE *music);
/* Close the given MOD stream */
extern void MOD_delete(struct MODULE *music);
/* Jump (seek) to a given position (time is in seconds) */
extern void MOD_jump_to_time(struct MODULE *music, double time);
#endif /* MOD_MUSIC */

View File

@ -0,0 +1,42 @@
#ifdef MODPLUG_MUSIC
#include "modplug.h"
#include "SDL_rwops.h"
#include "SDL_audio.h"
#include "SDL_mixer.h"
typedef struct {
ModPlugFile *file;
int playing;
} modplug_data;
int modplug_init(SDL_AudioSpec *mixer);
/* Uninitialize the music players */
void modplug_exit(void);
/* Set the volume for a modplug stream */
void modplug_setvolume(modplug_data *music, int volume);
/* Load a modplug stream from an SDL_RWops object */
modplug_data *modplug_new_RW(SDL_RWops *rw, int freerw);
/* Start playback of a given modplug stream */
void modplug_play(modplug_data *music);
/* Return non-zero if a stream is currently playing */
int modplug_playing(modplug_data *music);
/* Play some of a stream previously started with modplug_play() */
int modplug_playAudio(modplug_data *music, Uint8 *stream, int len);
/* Stop playback of a stream previously started with modplug_play() */
void modplug_stop(modplug_data *music);
/* Close the given modplug stream */
void modplug_delete(modplug_data *music);
/* Jump (seek) to a given position (time is in seconds) */
void modplug_jump_to_time(modplug_data *music, double time);
#endif

View File

@ -0,0 +1,75 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id$ */
#ifdef OGG_MUSIC
/* This file supports Ogg Vorbis music streams */
#ifdef OGG_USE_TREMOR
#include <tremor/ivorbisfile.h>
#else
#include <vorbis/vorbisfile.h>
#endif
typedef struct {
SDL_RWops *rw;
int freerw;
int playing;
int volume;
OggVorbis_File vf;
int section;
SDL_AudioCVT cvt;
int len_available;
Uint8 *snd_available;
} OGG_music;
/* Initialize the Ogg Vorbis player, with the given mixer settings
This function returns 0, or -1 if there was an error.
*/
extern int OGG_init(SDL_AudioSpec *mixer);
/* Set the volume for an OGG stream */
extern void OGG_setvolume(OGG_music *music, int volume);
/* Load an OGG stream from an SDL_RWops object */
extern OGG_music *OGG_new_RW(SDL_RWops *rw, int freerw);
/* Start playback of a given OGG stream */
extern void OGG_play(OGG_music *music);
/* Return non-zero if a stream is currently playing */
extern int OGG_playing(OGG_music *music);
/* Play some of a stream previously started with OGG_play() */
extern int OGG_playAudio(OGG_music *music, Uint8 *stream, int len);
/* Stop playback of a stream previously started with OGG_play() */
extern void OGG_stop(OGG_music *music);
/* Close the given OGG stream */
extern void OGG_delete(OGG_music *music);
/* Jump (seek) to a given position (time is in seconds) */
extern void OGG_jump_to_time(OGG_music *music, double time);
#endif /* OGG_MUSIC */

View File

@ -0,0 +1,60 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* $Id$ */
/* This file supports streaming WAV files, without volume adjustment */
#include <stdio.h>
typedef struct {
SDL_RWops *rw;
SDL_bool freerw;
long start;
long stop;
SDL_AudioCVT cvt;
} WAVStream;
/* Initialize the WAVStream player, with the given mixer settings
This function returns 0, or -1 if there was an error.
*/
extern int WAVStream_Init(SDL_AudioSpec *mixer);
/* Unimplemented */
extern void WAVStream_SetVolume(int volume);
/* Load a WAV stream from an SDL_RWops object */
extern WAVStream *WAVStream_LoadSong_RW(SDL_RWops *rw, const char *magic, int freerw);
/* Start playback of a given WAV stream */
extern void WAVStream_Start(WAVStream *wave);
/* Play some of a stream previously started with WAVStream_Start() */
extern int WAVStream_PlaySome(Uint8 *stream, int len);
/* Stop playback of a stream previously started with WAVStream_Start() */
extern void WAVStream_Stop(void);
/* Close the given WAV stream */
extern void WAVStream_FreeSong(WAVStream *wave);
/* Return non-zero if a stream is currently playing */
extern int WAVStream_Active(void);

View File

@ -0,0 +1,4 @@
-I
../../sdk/sources/SDL-1.2.2_newlib/include
../../sdk/sources/newlib/libc/include
.

File diff suppressed because it is too large Load Diff

View File

@ -1,156 +1,156 @@
//
// ID Engine
// ID_SD.h - Sound Manager Header
// Version for Wolfenstein
// By Jason Blochowiak
//
#ifndef __ID_SD__
#define __ID_SD__
#define alOut(n,b) YM3812Write(oplChip, n, b)
#define TickBase 70 // 70Hz per tick - used as a base for timer 0
typedef enum
{
sdm_Off,
sdm_PC,sdm_AdLib,
} SDMode;
typedef enum
{
smm_Off,smm_AdLib
} SMMode;
typedef enum
{
sds_Off,sds_PC,sds_SoundBlaster
} SDSMode;
typedef struct
{
longword length;
word priority;
} SoundCommon;
#define ORIG_SOUNDCOMMON_SIZE 6
// PC Sound stuff
#define pcTimer 0x42
#define pcTAccess 0x43
#define pcSpeaker 0x61
#define pcSpkBits 3
typedef struct
{
SoundCommon common;
byte data[1];
} PCSound;
// Register addresses
// Operator stuff
#define alChar 0x20
#define alScale 0x40
#define alAttack 0x60
#define alSus 0x80
#define alWave 0xe0
// Channel stuff
#define alFreqL 0xa0
#define alFreqH 0xb0
#define alFeedCon 0xc0
// Global stuff
#define alEffects 0xbd
typedef struct
{
byte mChar,cChar,
mScale,cScale,
mAttack,cAttack,
mSus,cSus,
mWave,cWave,
nConn,
// These are only for Muse - these bytes are really unused
voice,
mode;
byte unused[3];
} Instrument;
#define ORIG_INSTRUMENT_SIZE 16
typedef struct
{
SoundCommon common;
Instrument inst;
byte block;
byte data[1];
} AdLibSound;
#define ORIG_ADLIBSOUND_SIZE (ORIG_SOUNDCOMMON_SIZE + ORIG_INSTRUMENT_SIZE + 2)
//
// Sequencing stuff
//
#define sqMaxTracks 10
typedef struct
{
word length;
word values[1];
} MusicGroup;
typedef struct
{
int valid;
fixed globalsoundx, globalsoundy;
} globalsoundpos;
extern int channelSoundPos[];
// Global variables
extern boolean AdLibPresent,
SoundBlasterPresent,
SoundPositioned;
extern SDMode SoundMode;
extern SDSMode DigiMode;
extern SMMode MusicMode;
extern int DigiMap[];
extern int DigiChannel[];
#define GetTimeCount() ((SDL_GetTicks()*7)/100)
inline void Delay(int wolfticks)
{
if(wolfticks>0) SDL_Delay(wolfticks * 100 / 7);
}
// Function prototypes
extern void SD_Startup(void),
SD_Shutdown(void);
extern int SD_GetChannelForDigi(int which);
extern void SD_PositionSound(int leftvol,int rightvol);
extern boolean SD_PlaySound(soundnames sound);
extern void SD_SetPosition(int channel, int leftvol,int rightvol);
extern void SD_StopSound(void),
SD_WaitSoundDone(void);
extern void SD_StartMusic(int chunk);
extern void SD_ContinueMusic(int chunk, int startoffs);
extern void SD_MusicOn(void),
SD_FadeOutMusic(void);
extern int SD_MusicOff(void);
extern boolean SD_MusicPlaying(void);
extern boolean SD_SetSoundMode(SDMode mode);
extern boolean SD_SetMusicMode(SMMode mode);
extern word SD_SoundPlaying(void);
extern void SD_SetDigiDevice(SDSMode);
extern void SD_PrepareSound(int which);
extern int SD_PlayDigitized(word which,int leftpos,int rightpos);
extern void SD_StopDigitized(void);
#endif
//
// ID Engine
// ID_SD.h - Sound Manager Header
// Version for Wolfenstein
// By Jason Blochowiak
//
#ifndef __ID_SD__
#define __ID_SD__
#define alOut(n,b) YM3812Write(0, n, b)
#define TickBase 70 // 70Hz per tick - used as a base for timer 0
typedef enum
{
sdm_Off,
sdm_PC,sdm_AdLib,
} SDMode;
typedef enum
{
smm_Off,smm_AdLib
} SMMode;
typedef enum
{
sds_Off,sds_PC,sds_SoundBlaster
} SDSMode;
typedef struct
{
longword length;
word priority;
} SoundCommon;
#define ORIG_SOUNDCOMMON_SIZE 6
// PC Sound stuff
#define pcTimer 0x42
#define pcTAccess 0x43
#define pcSpeaker 0x61
#define pcSpkBits 3
typedef struct
{
SoundCommon common;
byte data[1];
} PCSound;
// Register addresses
// Operator stuff
#define alChar 0x20
#define alScale 0x40
#define alAttack 0x60
#define alSus 0x80
#define alWave 0xe0
// Channel stuff
#define alFreqL 0xa0
#define alFreqH 0xb0
#define alFeedCon 0xc0
// Global stuff
#define alEffects 0xbd
typedef struct
{
byte mChar,cChar,
mScale,cScale,
mAttack,cAttack,
mSus,cSus,
mWave,cWave,
nConn,
// These are only for Muse - these bytes are really unused
voice,
mode;
byte unused[3];
} Instrument;
#define ORIG_INSTRUMENT_SIZE 16
typedef struct
{
SoundCommon common;
Instrument inst;
byte block;
byte data[1];
} AdLibSound;
#define ORIG_ADLIBSOUND_SIZE (ORIG_SOUNDCOMMON_SIZE + ORIG_INSTRUMENT_SIZE + 2)
//
// Sequencing stuff
//
#define sqMaxTracks 10
typedef struct
{
word length;
word values[1];
} MusicGroup;
typedef struct
{
int valid;
fixed globalsoundx, globalsoundy;
} globalsoundpos;
extern globalsoundpos channelSoundPos[];
// Global variables
extern boolean AdLibPresent,
SoundBlasterPresent,
SoundPositioned;
extern SDMode SoundMode;
extern SDSMode DigiMode;
extern SMMode MusicMode;
extern int DigiMap[];
extern int DigiChannel[];
#define GetTimeCount() ((SDL_GetTicks()*7)/100)
inline void Delay(int wolfticks)
{
if(wolfticks>0) SDL_Delay(wolfticks * 100 / 7);
}
// Function prototypes
extern void SD_Startup(void),
SD_Shutdown(void);
extern int SD_GetChannelForDigi(int which);
extern void SD_PositionSound(int leftvol,int rightvol);
extern boolean SD_PlaySound(soundnames sound);
extern void SD_SetPosition(int channel, int leftvol,int rightvol);
extern void SD_StopSound(void),
SD_WaitSoundDone(void);
extern void SD_StartMusic(int chunk);
extern void SD_ContinueMusic(int chunk, int startoffs);
extern void SD_MusicOn(void),
SD_FadeOutMusic(void);
extern int SD_MusicOff(void);
extern boolean SD_MusicPlaying(void);
extern boolean SD_SetSoundMode(SDMode mode);
extern boolean SD_SetMusicMode(SMMode mode);
extern word SD_SoundPlaying(void);
extern void SD_SetDigiDevice(SDSMode);
extern void SD_PrepareSound(int which);
extern int SD_PlayDigitized(word which,int leftpos,int rightpos);
extern void SD_StopDigitized(void);
#endif

View File

@ -2,7 +2,7 @@
#include "wl_def.h"
#pragma hdrstop
#define itoa ltoa
LRstruct LevelRatios[LRpack];
int32_t lastBreathTime = 0;

View File

@ -1210,11 +1210,12 @@ static void InitGame()
#if defined _WIN32
putenv("SDL_VIDEODRIVER=directx");
#endif
if(SDL_Init(SDL_INIT_VIDEO /*| SDL_INIT_AUDIO | SDL_INIT_JOYSTICK*/) < 0)
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("Unable to init SDL: %s\n", SDL_GetError());
exit(1);
}
SDL_AudioInit(NULL);
atexit(SDL_Quit);
int numJoysticks = SDL_NumJoysticks();
@ -1232,8 +1233,10 @@ static void InitGame()
#endif
SignonScreen ();
#ifdef _KOLIBRI
kolibri_set_win_center();
#endif
#if defined _WIN32
if(!fullscreen)
{
@ -1886,6 +1889,9 @@ void CheckParameters(int argc, char *argv[])
printf(
"Wolf4SDL v1.7 ($Revision$)\n"
"Ported by Chaos-Software (http://www.chaos-software.de.vu)\n"
#ifdef _KOLIBRI
"Ported for KolibriOS by 'turbocat2001' and 'maxcodehack'\n"
#endif
"Original Wolfenstein 3D by id Software\n\n"
"Usage: Wolf4SDL [options]\n"
"Options:\n"
@ -1896,8 +1902,10 @@ void CheckParameters(int argc, char *argv[])
" --normal Sets the difficulty to normal for tedlevel\n"
" --hard Sets the difficulty to hard for tedlevel\n"
" --nowait Skips intro screens\n"
#ifndef _KOLIBRI
" --windowed[-mouse] Starts the game in a window [and grabs mouse]\n"
" --res <width> <height> Sets the screen resolution\n"
#endif
" (must be multiple of 320x200 or 320x240)\n"
" --resf <w> <h> Sets any screen resolution >= 320x200\n"
" (which may result in graphic errors)\n"
@ -1907,9 +1915,11 @@ void CheckParameters(int argc, char *argv[])
" --nodblbuf Don't use SDL's double buffering\n"
" --extravbls <vbls> Sets a delay after each frame, which may help to\n"
" reduce flickering (unit is currently 8 ms, default: 0)\n"
#ifndef _KOLIBRI
" --joystick <index> Use the index-th joystick if available\n"
" (-1 to disable joystick, default: 0)\n"
" --joystickhat <index> Enables movement with the given coolie hat\n"
#endif
" --samplerate <rate> Sets the sound sample rate (given in Hz, default: %i)\n"
" --audiobuffer <size> Sets the size of the audio buffer (-> sound latency)\n"
" (given in bytes, default: 2048 / (44100 / samplerate))\n"