Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 8644 → Rev 8645

/contrib/games/wolf3d/Makefile
3,21 → 3,64
 
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
/contrib/games/wolf3d/Makefile.linux
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
/contrib/games/wolf3d/SDL/SDL_audiocvt.c
0,0 → 1,642
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
 
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
Sam Lantinga
slouken@devolution.com
*/
 
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_audiocvt.c,v 1.2 2001/04/26 16:50:17 hercules Exp $";
#endif
 
/* Functions for audio drivers to perform runtime conversion of audio format */
 
#include <stdio.h>
 
#include "SDL_error.h"
#include "SDL_audio.h"
 
 
/* Effectively mix right and left channels into a single channel */
void SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format)
{
int i;
Sint32 sample;
 
#ifdef DEBUG_CONVERT
fprintf(stderr, "Converting to mono\n");
#endif
switch (format&0x8018) {
 
case AUDIO_U8: {
Uint8 *src, *dst;
 
src = cvt->buf;
dst = cvt->buf;
for ( i=cvt->len_cvt/2; i; --i ) {
sample = src[0] + src[1];
if ( sample > 255 ) {
*dst = 255;
} else {
*dst = sample;
}
src += 2;
dst += 1;
}
}
break;
 
case AUDIO_S8: {
Sint8 *src, *dst;
 
src = (Sint8 *)cvt->buf;
dst = (Sint8 *)cvt->buf;
for ( i=cvt->len_cvt/2; i; --i ) {
sample = src[0] + src[1];
if ( sample > 127 ) {
*dst = 127;
} else
if ( sample < -128 ) {
*dst = -128;
} else {
*dst = sample;
}
src += 2;
dst += 1;
}
}
break;
 
case AUDIO_U16: {
Uint8 *src, *dst;
 
src = cvt->buf;
dst = cvt->buf;
if ( (format & 0x1000) == 0x1000 ) {
for ( i=cvt->len_cvt/4; i; --i ) {
sample = (Uint16)((src[0]<<8)|src[1])+
(Uint16)((src[2]<<8)|src[3]);
if ( sample > 65535 ) {
dst[0] = 0xFF;
dst[1] = 0xFF;
} else {
dst[1] = (sample&0xFF);
sample >>= 8;
dst[0] = (sample&0xFF);
}
src += 4;
dst += 2;
}
} else {
for ( i=cvt->len_cvt/4; i; --i ) {
sample = (Uint16)((src[1]<<8)|src[0])+
(Uint16)((src[3]<<8)|src[2]);
if ( sample > 65535 ) {
dst[0] = 0xFF;
dst[1] = 0xFF;
} else {
dst[0] = (sample&0xFF);
sample >>= 8;
dst[1] = (sample&0xFF);
}
src += 4;
dst += 2;
}
}
}
break;
 
case AUDIO_S16: {
Uint8 *src, *dst;
 
src = cvt->buf;
dst = cvt->buf;
if ( (format & 0x1000) == 0x1000 ) {
for ( i=cvt->len_cvt/4; i; --i ) {
sample = (Sint16)((src[0]<<8)|src[1])+
(Sint16)((src[2]<<8)|src[3]);
if ( sample > 32767 ) {
dst[0] = 0x7F;
dst[1] = 0xFF;
} else
if ( sample < -32768 ) {
dst[0] = 0x80;
dst[1] = 0x00;
} else {
dst[1] = (sample&0xFF);
sample >>= 8;
dst[0] = (sample&0xFF);
}
src += 4;
dst += 2;
}
} else {
for ( i=cvt->len_cvt/4; i; --i ) {
sample = (Sint16)((src[1]<<8)|src[0])+
(Sint16)((src[3]<<8)|src[2]);
if ( sample > 32767 ) {
dst[1] = 0x7F;
dst[0] = 0xFF;
} else
if ( sample < -32768 ) {
dst[1] = 0x80;
dst[0] = 0x00;
} else {
dst[0] = (sample&0xFF);
sample >>= 8;
dst[1] = (sample&0xFF);
}
src += 4;
dst += 2;
}
}
}
break;
}
cvt->len_cvt /= 2;
if ( cvt->filters[++cvt->filter_index] ) {
cvt->filters[cvt->filter_index](cvt, format);
}
}
 
 
/* Duplicate a mono channel to both stereo channels */
void SDL_ConvertStereo(SDL_AudioCVT *cvt, Uint16 format)
{
int i;
 
#ifdef DEBUG_CONVERT
fprintf(stderr, "Converting to stereo\n");
#endif
if ( (format & 0xFF) == 16 ) {
Uint16 *src, *dst;
 
src = (Uint16 *)(cvt->buf+cvt->len_cvt);
dst = (Uint16 *)(cvt->buf+cvt->len_cvt*2);
for ( i=cvt->len_cvt/2; i; --i ) {
dst -= 2;
src -= 1;
dst[0] = src[0];
dst[1] = src[0];
}
} else {
Uint8 *src, *dst;
 
src = cvt->buf+cvt->len_cvt;
dst = cvt->buf+cvt->len_cvt*2;
for ( i=cvt->len_cvt; i; --i ) {
dst -= 2;
src -= 1;
dst[0] = src[0];
dst[1] = src[0];
}
}
cvt->len_cvt *= 2;
if ( cvt->filters[++cvt->filter_index] ) {
cvt->filters[cvt->filter_index](cvt, format);
}
}
 
/* Convert 8-bit to 16-bit - LSB */
void SDL_Convert16LSB(SDL_AudioCVT *cvt, Uint16 format)
{
int i;
Uint8 *src, *dst;
 
#ifdef DEBUG_CONVERT
fprintf(stderr, "Converting to 16-bit LSB\n");
#endif
src = cvt->buf+cvt->len_cvt;
dst = cvt->buf+cvt->len_cvt*2;
for ( i=cvt->len_cvt; i; --i ) {
src -= 1;
dst -= 2;
dst[1] = *src;
dst[0] = 0;
}
format = ((format & ~0x0008) | AUDIO_U16LSB);
cvt->len_cvt *= 2;
if ( cvt->filters[++cvt->filter_index] ) {
cvt->filters[cvt->filter_index](cvt, format);
}
}
/* Convert 8-bit to 16-bit - MSB */
void SDL_Convert16MSB(SDL_AudioCVT *cvt, Uint16 format)
{
int i;
Uint8 *src, *dst;
 
#ifdef DEBUG_CONVERT
fprintf(stderr, "Converting to 16-bit MSB\n");
#endif
src = cvt->buf+cvt->len_cvt;
dst = cvt->buf+cvt->len_cvt*2;
for ( i=cvt->len_cvt; i; --i ) {
src -= 1;
dst -= 2;
dst[0] = *src;
dst[1] = 0;
}
format = ((format & ~0x0008) | AUDIO_U16MSB);
cvt->len_cvt *= 2;
if ( cvt->filters[++cvt->filter_index] ) {
cvt->filters[cvt->filter_index](cvt, format);
}
}
 
/* Convert 16-bit to 8-bit */
void SDL_Convert8(SDL_AudioCVT *cvt, Uint16 format)
{
int i;
Uint8 *src, *dst;
 
#ifdef DEBUG_CONVERT
fprintf(stderr, "Converting to 8-bit\n");
#endif
src = cvt->buf;
dst = cvt->buf;
if ( (format & 0x1000) != 0x1000 ) { /* Little endian */
++src;
}
for ( i=cvt->len_cvt/2; i; --i ) {
*dst = *src;
src += 2;
dst += 1;
}
format = ((format & ~0x9010) | AUDIO_U8);
cvt->len_cvt /= 2;
if ( cvt->filters[++cvt->filter_index] ) {
cvt->filters[cvt->filter_index](cvt, format);
}
}
 
/* Toggle signed/unsigned */
void SDL_ConvertSign(SDL_AudioCVT *cvt, Uint16 format)
{
int i;
Uint8 *data;
 
#ifdef DEBUG_CONVERT
fprintf(stderr, "Converting audio signedness\n");
#endif
data = cvt->buf;
if ( (format & 0xFF) == 16 ) {
if ( (format & 0x1000) != 0x1000 ) { /* Little endian */
++data;
}
for ( i=cvt->len_cvt/2; i; --i ) {
*data ^= 0x80;
data += 2;
}
} else {
for ( i=cvt->len_cvt; i; --i ) {
*data++ ^= 0x80;
}
}
format = (format ^ 0x8000);
if ( cvt->filters[++cvt->filter_index] ) {
cvt->filters[cvt->filter_index](cvt, format);
}
}
 
/* Toggle endianness */
void SDL_ConvertEndian(SDL_AudioCVT *cvt, Uint16 format)
{
int i;
Uint8 *data, tmp;
 
#ifdef DEBUG_CONVERT
fprintf(stderr, "Converting audio endianness\n");
#endif
data = cvt->buf;
for ( i=cvt->len_cvt/2; i; --i ) {
tmp = data[0];
data[0] = data[1];
data[1] = tmp;
data += 2;
}
format = (format ^ 0x1000);
if ( cvt->filters[++cvt->filter_index] ) {
cvt->filters[cvt->filter_index](cvt, format);
}
}
 
/* Convert rate up by multiple of 2 */
void SDL_RateMUL2(SDL_AudioCVT *cvt, Uint16 format)
{
int i;
Uint8 *src, *dst;
 
#ifdef DEBUG_CONVERT
fprintf(stderr, "Converting audio rate * 2\n");
#endif
src = cvt->buf+cvt->len_cvt;
dst = cvt->buf+cvt->len_cvt*2;
switch (format & 0xFF) {
case 8:
for ( i=cvt->len_cvt; i; --i ) {
src -= 1;
dst -= 2;
dst[0] = src[0];
dst[1] = src[0];
}
break;
case 16:
for ( i=cvt->len_cvt/2; i; --i ) {
src -= 2;
dst -= 4;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[0];
dst[3] = src[1];
}
break;
}
cvt->len_cvt *= 2;
if ( cvt->filters[++cvt->filter_index] ) {
cvt->filters[cvt->filter_index](cvt, format);
}
}
 
/* Convert rate down by multiple of 2 */
void SDL_RateDIV2(SDL_AudioCVT *cvt, Uint16 format)
{
int i;
Uint8 *src, *dst;
 
#ifdef DEBUG_CONVERT
fprintf(stderr, "Converting audio rate / 2\n");
#endif
src = cvt->buf;
dst = cvt->buf;
switch (format & 0xFF) {
case 8:
for ( i=cvt->len_cvt/2; i; --i ) {
dst[0] = src[0];
src += 2;
dst += 1;
}
break;
case 16:
for ( i=cvt->len_cvt/4; i; --i ) {
dst[0] = src[0];
dst[1] = src[1];
src += 4;
dst += 2;
}
break;
}
cvt->len_cvt /= 2;
if ( cvt->filters[++cvt->filter_index] ) {
cvt->filters[cvt->filter_index](cvt, format);
}
}
 
/* Very slow rate conversion routine */
void SDL_RateSLOW(SDL_AudioCVT *cvt, Uint16 format)
{
double ipos;
int i, clen;
 
#ifdef DEBUG_CONVERT
fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0/cvt->rate_incr);
#endif
clen = (int)((double)cvt->len_cvt / cvt->rate_incr);
if ( cvt->rate_incr > 1.0 ) {
switch (format & 0xFF) {
case 8: {
Uint8 *output;
 
output = cvt->buf;
ipos = 0.0;
for ( i=clen; i; --i ) {
*output = cvt->buf[(int)ipos];
ipos += cvt->rate_incr;
output += 1;
}
}
break;
 
case 16: {
Uint16 *output;
 
clen &= ~1;
output = (Uint16 *)cvt->buf;
ipos = 0.0;
for ( i=clen/2; i; --i ) {
*output=((Uint16 *)cvt->buf)[(int)ipos];
ipos += cvt->rate_incr;
output += 1;
}
}
break;
}
} else {
switch (format & 0xFF) {
case 8: {
Uint8 *output;
 
output = cvt->buf+clen;
ipos = (double)cvt->len_cvt;
for ( i=clen; i; --i ) {
ipos -= cvt->rate_incr;
output -= 1;
*output = cvt->buf[(int)ipos];
}
}
break;
 
case 16: {
Uint16 *output;
 
clen &= ~1;
output = (Uint16 *)(cvt->buf+clen);
ipos = (double)cvt->len_cvt/2;
for ( i=clen/2; i; --i ) {
ipos -= cvt->rate_incr;
output -= 1;
*output=((Uint16 *)cvt->buf)[(int)ipos];
}
}
break;
}
}
cvt->len_cvt = clen;
if ( cvt->filters[++cvt->filter_index] ) {
cvt->filters[cvt->filter_index](cvt, format);
}
}
 
int SDL_ConvertAudio(SDL_AudioCVT *cvt)
{
/* Make sure there's data to convert */
if ( cvt->buf == NULL ) {
SDL_SetError("No buffer allocated for conversion");
return(-1);
}
/* Return okay if no conversion is necessary */
cvt->len_cvt = cvt->len;
if ( cvt->filters[0] == NULL ) {
return(0);
}
 
/* Set up the conversion and go! */
cvt->filter_index = 0;
cvt->filters[0](cvt, cvt->src_format);
return(0);
}
 
/* Creates a set of audio filters to convert from one format to another.
Returns -1 if the format conversion is not supported, or 1 if the
audio filter is set up.
*/
int SDL_BuildAudioCVT(SDL_AudioCVT *cvt,
Uint16 src_format, Uint8 src_channels, int src_rate,
Uint16 dst_format, Uint8 dst_channels, int dst_rate)
{
/* Start off with no conversion necessary */
cvt->needed = 0;
cvt->filter_index = 0;
cvt->filters[0] = NULL;
cvt->len_mult = 1;
cvt->len_ratio = 1.0;
 
/* First filter: Endian conversion from src to dst */
if ( (src_format & 0x1000) != (dst_format & 0x1000)
&& ((src_format & 0xff) != 8) ) {
cvt->filters[cvt->filter_index++] = SDL_ConvertEndian;
}
/* Second filter: Sign conversion -- signed/unsigned */
if ( (src_format & 0x8000) != (dst_format & 0x8000) ) {
cvt->filters[cvt->filter_index++] = SDL_ConvertSign;
}
 
/* Next filter: Convert 16 bit <--> 8 bit PCM */
if ( (src_format & 0xFF) != (dst_format & 0xFF) ) {
switch (dst_format&0x10FF) {
case AUDIO_U8:
cvt->filters[cvt->filter_index++] =
SDL_Convert8;
cvt->len_ratio /= 2;
break;
case AUDIO_U16LSB:
cvt->filters[cvt->filter_index++] =
SDL_Convert16LSB;
cvt->len_mult *= 2;
cvt->len_ratio *= 2;
break;
case AUDIO_U16MSB:
cvt->filters[cvt->filter_index++] =
SDL_Convert16MSB;
cvt->len_mult *= 2;
cvt->len_ratio *= 2;
break;
}
}
 
/* Last filter: Mono/Stereo conversion */
if ( src_channels != dst_channels ) {
while ( (src_channels*2) <= dst_channels ) {
cvt->filters[cvt->filter_index++] =
SDL_ConvertStereo;
cvt->len_mult *= 2;
src_channels *= 2;
cvt->len_ratio *= 2;
}
/* This assumes that 4 channel audio is in the format:
Left {front/back} + Right {front/back}
so converting to L/R stereo works properly.
*/
while ( ((src_channels%2) == 0) &&
((src_channels/2) >= dst_channels) ) {
cvt->filters[cvt->filter_index++] =
SDL_ConvertMono;
src_channels /= 2;
cvt->len_ratio /= 2;
}
if ( src_channels != dst_channels ) {
/* Uh oh.. */;
}
}
 
/* Do rate conversion */
cvt->rate_incr = 0.0;
if ( (src_rate/100) != (dst_rate/100) ) {
Uint32 hi_rate, lo_rate;
int len_mult;
double len_ratio;
void (*rate_cvt)(SDL_AudioCVT *cvt, Uint16 format);
 
if ( src_rate > dst_rate ) {
hi_rate = src_rate;
lo_rate = dst_rate;
rate_cvt = SDL_RateDIV2;
len_mult = 1;
len_ratio = 0.5;
} else {
hi_rate = dst_rate;
lo_rate = src_rate;
rate_cvt = SDL_RateMUL2;
len_mult = 2;
len_ratio = 2.0;
}
/* If hi_rate = lo_rate*2^x then conversion is easy */
while ( ((lo_rate*2)/100) <= (hi_rate/100) ) {
cvt->filters[cvt->filter_index++] = rate_cvt;
cvt->len_mult *= len_mult;
lo_rate *= 2;
cvt->len_ratio *= len_ratio;
}
/* We may need a slow conversion here to finish up */
if ( (lo_rate/100) != (hi_rate/100) ) {
#if 1
/* The problem with this is that if the input buffer is
say 1K, and the conversion rate is say 1.1, then the
output buffer is 1.1K, which may not be an acceptable
buffer size for the audio driver (not a power of 2)
*/
/* For now, punt and hope the rate distortion isn't great.
*/
#else
if ( src_rate < dst_rate ) {
cvt->rate_incr = (double)lo_rate/hi_rate;
cvt->len_mult *= 2;
cvt->len_ratio /= cvt->rate_incr;
} else {
cvt->rate_incr = (double)hi_rate/lo_rate;
cvt->len_ratio *= cvt->rate_incr;
}
cvt->filters[cvt->filter_index++] = SDL_RateSLOW;
#endif
}
}
 
/* Set up the filter information */
if ( cvt->filter_index != 0 ) {
cvt->needed = 1;
cvt->src_format = src_format;
cvt->dst_format = dst_format;
cvt->len = 0;
cvt->buf = NULL;
cvt->filters[cvt->filter_index] = NULL;
}
return(cvt->needed);
}
/contrib/games/wolf3d/SDL/SDL_mixer.c
0,0 → 1,218
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
 
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
Sam Lantinga
slouken@devolution.com
*/
 
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_mixer.c,v 1.2 2001/04/26 16:50:17 hercules Exp $";
#endif
 
/* This provides the default mixing callback for the SDL audio routines */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include "SDL_audio.h"
#include "SDL_mutex.h"
#include "SDL_timer.h"
#include "SDL_sysaudio.h"
 
SDL_AudioDevice *current_audio = NULL;
 
/* This table is used to add two sound values together and pin
* the value to avoid overflow. (used with permission from ARDI)
* Changed to use 0xFE instead of 0xFF for better sound quality.
*/
static const Uint8 mix8[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE
};
 
/* The volume ranges from 0 - 128 */
#define ADJUST_VOLUME(s, v) (s = (s*v)/SDL_MIX_MAXVOLUME)
#define ADJUST_VOLUME_U8(s, v) (s = (((s-128)*v)/SDL_MIX_MAXVOLUME)+128)
 
void SDL_MixAudio (Uint8 *dst, const Uint8 *src, Uint32 len, int volume)
{
Uint16 format;
 
if ( volume == 0 ) {
return;
}
/* Mix the user-level audio format */
if ( current_audio ) {
if ( current_audio->convert.needed ) {
format = current_audio->convert.src_format;
} else {
format = current_audio->spec.format;
}
} else {
format = AUDIO_S16;
}
format = AUDIO_S16;
switch (format) {
 
case AUDIO_U8: {
Uint8 src_sample;
 
while ( len-- ) {
src_sample = *src;
ADJUST_VOLUME_U8(src_sample, volume);
*dst = mix8[*dst+src_sample];
++dst;
++src;
}
}
break;
 
case AUDIO_S8: {
Sint8 *dst8, *src8;
Sint8 src_sample;
int dst_sample;
const int max_audioval = ((1<<(8-1))-1);
const int min_audioval = -(1<<(8-1));
 
src8 = (Sint8 *)src;
dst8 = (Sint8 *)dst;
while ( len-- ) {
src_sample = *src8;
ADJUST_VOLUME(src_sample, volume);
dst_sample = *dst8 + src_sample;
if ( dst_sample > max_audioval ) {
*dst8 = max_audioval;
} else
if ( dst_sample < min_audioval ) {
*dst8 = min_audioval;
} else {
*dst8 = dst_sample;
}
++dst8;
++src8;
}
}
break;
 
case AUDIO_S16LSB: {
Sint16 src1, src2;
int dst_sample;
const int max_audioval = ((1<<(16-1))-1);
const int min_audioval = -(1<<(16-1));
 
len /= 2;
while ( len-- ) {
src1 = ((src[1])<<8|src[0]);
ADJUST_VOLUME(src1, volume);
src2 = ((dst[1])<<8|dst[0]);
src += 2;
dst_sample = src1+src2;
if ( dst_sample > max_audioval ) {
dst_sample = max_audioval;
} else
if ( dst_sample < min_audioval ) {
dst_sample = min_audioval;
}
dst[0] = dst_sample&0xFF;
dst_sample >>= 8;
dst[1] = dst_sample&0xFF;
dst += 2;
}
}
break;
 
case AUDIO_S16MSB: {
Sint16 src1, src2;
int dst_sample;
const int max_audioval = ((1<<(16-1))-1);
const int min_audioval = -(1<<(16-1));
 
len /= 2;
while ( len-- ) {
src1 = ((src[0])<<8|src[1]);
ADJUST_VOLUME(src1, volume);
src2 = ((dst[0])<<8|dst[1]);
src += 2;
dst_sample = src1+src2;
if ( dst_sample > max_audioval ) {
dst_sample = max_audioval;
} else
if ( dst_sample < min_audioval ) {
dst_sample = min_audioval;
}
dst[1] = dst_sample&0xFF;
dst_sample >>= 8;
dst[0] = dst_sample&0xFF;
dst += 2;
}
}
break;
 
default: /* If this happens... FIXME! */
SDL_SetError("SDL_MixAudio(): unknown audio format");
return;
}
}
/contrib/games/wolf3d/SDL/SDL_sysaudio.h
0,0 → 1,150
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
 
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
Sam Lantinga
slouken@devolution.com
*/
 
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_sysaudio.h,v 1.8 2001/07/23 02:58:42 slouken Exp $";
#endif
 
#ifndef _SDL_sysaudio_h
#define _SDL_sysaudio_h
 
#include "SDL_mutex.h"
#include "SDL_thread.h"
 
/* The SDL audio driver */
typedef struct SDL_AudioDevice SDL_AudioDevice;
 
/* Define the SDL audio driver structure */
#define _THIS SDL_AudioDevice *_this
#ifndef _STATUS
#define _STATUS SDL_status *status
#endif
struct SDL_AudioDevice {
/* * * */
/* The name of this audio driver */
const char *name;
 
/* * * */
/* The description of this audio driver */
const char *desc;
 
/* * * */
/* Public driver functions */
int (*OpenAudio)(_THIS, SDL_AudioSpec *spec);
void (*ThreadInit)(_THIS); /* Called by audio thread at start */
void (*WaitAudio)(_THIS);
void (*PlayAudio)(_THIS);
Uint8 *(*GetAudioBuf)(_THIS);
void (*WaitDone)(_THIS);
void (*CloseAudio)(_THIS);
 
/* * * */
/* Data common to all devices */
 
/* The current audio specification (shared with audio thread) */
SDL_AudioSpec spec;
 
/* An audio conversion block for audio format emulation */
SDL_AudioCVT convert;
 
/* Current state flags */
int enabled;
int paused;
int opened;
 
/* Fake audio buffer for when the audio hardware is busy */
Uint8 *fake_stream;
 
/* A semaphore for locking the mixing buffers */
SDL_mutex *mixer_lock;
 
/* A thread to feed the audio device */
SDL_Thread *thread;
Uint32 threadid;
 
/* * * */
/* Data private to this driver */
struct SDL_PrivateAudioData *hidden;
 
/* * * */
/* The function used to dispose of this structure */
void (*free)(_THIS);
};
#undef _THIS
 
typedef struct AudioBootStrap {
const char *name;
const char *desc;
int (*available)(void);
SDL_AudioDevice *(*create)(int devindex);
} AudioBootStrap;
 
#ifdef OPENBSD_AUDIO_SUPPORT
extern AudioBootStrap OPENBSD_AUDIO_bootstrap;
#endif
#ifdef OSS_SUPPORT
extern AudioBootStrap DSP_bootstrap;
extern AudioBootStrap DMA_bootstrap;
#endif
#ifdef ALSA_SUPPORT
extern AudioBootStrap ALSA_bootstrap;
#endif
#if (defined(unix) && !defined(__CYGWIN32__)) && \
!defined(OSS_SUPPORT) && !defined(ALSA_SUPPORT)
extern AudioBootStrap AUDIO_bootstrap;
#endif
#ifdef ARTSC_SUPPORT
extern AudioBootStrap ARTSC_bootstrap;
#endif
#ifdef ESD_SUPPORT
extern AudioBootStrap ESD_bootstrap;
#endif
#ifdef NAS_SUPPORT
extern AudioBootStrap NAS_bootstrap;
#endif
#ifdef ENABLE_DIRECTX
extern AudioBootStrap DSOUND_bootstrap;
#endif
#ifdef ENABLE_WINDIB
extern AudioBootStrap WAVEOUT_bootstrap;
#endif
#ifdef _AIX
extern AudioBootStrap Paud_bootstrap;
#endif
#ifdef __BEOS__
extern AudioBootStrap BAUDIO_bootstrap;
#endif
#if defined(macintosh) || TARGET_API_MAC_CARBON
extern AudioBootStrap SNDMGR_bootstrap;
#endif
#ifdef ENABLE_AHI
extern AudioBootStrap AHI_bootstrap;
#endif
#ifdef DISKAUD_SUPPORT
extern AudioBootStrap DISKAUD_bootstrap;
#endif
 
/* This is the current audio device */
extern SDL_AudioDevice *current_audio;
 
#endif /* _SDL_sysaudio_h */
/contrib/games/wolf3d/SDL/SDL_wave.c
0,0 → 1,591
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
 
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
Sam Lantinga
slouken@devolution.com
*/
 
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_wave.c,v 1.2 2001/04/26 16:50:17 hercules Exp $";
#endif
 
#ifndef DISABLE_FILE
 
/* Microsoft WAVE file loading routines */
 
#include <stdlib.h>
#include <string.h>
 
#include "SDL_error.h"
#include "SDL_audio.h"
#include "SDL_wave.h"
#include "SDL_endian.h"
 
#ifndef NELEMS
#define NELEMS(array) ((sizeof array)/(sizeof array[0]))
#endif
 
static int ReadChunk(SDL_RWops *src, Chunk *chunk);
 
struct MS_ADPCM_decodestate {
Uint8 hPredictor;
Uint16 iDelta;
Sint16 iSamp1;
Sint16 iSamp2;
};
static struct MS_ADPCM_decoder {
WaveFMT wavefmt;
Uint16 wSamplesPerBlock;
Uint16 wNumCoef;
Sint16 aCoeff[7][2];
/* * * */
struct MS_ADPCM_decodestate state[2];
} MS_ADPCM_state;
 
static int InitMS_ADPCM(WaveFMT *format)
{
Uint8 *rogue_feel;
Uint16 extra_info;
int i;
 
/* Set the rogue pointer to the MS_ADPCM specific data */
MS_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);
MS_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);
MS_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);
MS_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate);
MS_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign);
MS_ADPCM_state.wavefmt.bitspersample =
SDL_SwapLE16(format->bitspersample);
rogue_feel = (Uint8 *)format+sizeof(*format);
if ( sizeof(*format) == 16 ) {
extra_info = ((rogue_feel[1]<<8)|rogue_feel[0]);
rogue_feel += sizeof(Uint16);
}
MS_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);
rogue_feel += sizeof(Uint16);
MS_ADPCM_state.wNumCoef = ((rogue_feel[1]<<8)|rogue_feel[0]);
rogue_feel += sizeof(Uint16);
if ( MS_ADPCM_state.wNumCoef != 7 ) {
SDL_SetError("Unknown set of MS_ADPCM coefficients");
return(-1);
}
for ( i=0; i<MS_ADPCM_state.wNumCoef; ++i ) {
MS_ADPCM_state.aCoeff[i][0] = ((rogue_feel[1]<<8)|rogue_feel[0]);
rogue_feel += sizeof(Uint16);
MS_ADPCM_state.aCoeff[i][1] = ((rogue_feel[1]<<8)|rogue_feel[0]);
rogue_feel += sizeof(Uint16);
}
return(0);
}
 
static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state,
Uint8 nybble, Sint16 *coeff)
{
const Sint32 max_audioval = ((1<<(16-1))-1);
const Sint32 min_audioval = -(1<<(16-1));
const Sint32 adaptive[] = {
230, 230, 230, 230, 307, 409, 512, 614,
768, 614, 512, 409, 307, 230, 230, 230
};
Sint32 new_sample, delta;
 
new_sample = ((state->iSamp1 * coeff[0]) +
(state->iSamp2 * coeff[1]))/256;
if ( nybble & 0x08 ) {
new_sample += state->iDelta * (nybble-0x10);
} else {
new_sample += state->iDelta * nybble;
}
if ( new_sample < min_audioval ) {
new_sample = min_audioval;
} else
if ( new_sample > max_audioval ) {
new_sample = max_audioval;
}
delta = ((Sint32)state->iDelta * adaptive[nybble])/256;
if ( delta < 16 ) {
delta = 16;
}
state->iDelta = delta;
state->iSamp2 = state->iSamp1;
state->iSamp1 = new_sample;
return(new_sample);
}
 
static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
{
struct MS_ADPCM_decodestate *state[2];
Uint8 *freeable, *encoded, *decoded;
Sint32 encoded_len, samplesleft;
Sint8 nybble, stereo;
Sint16 *coeff[2];
Sint32 new_sample;
 
/* Allocate the proper sized output buffer */
encoded_len = *audio_len;
encoded = *audio_buf;
freeable = *audio_buf;
*audio_len = (encoded_len/MS_ADPCM_state.wavefmt.blockalign) *
MS_ADPCM_state.wSamplesPerBlock*
MS_ADPCM_state.wavefmt.channels*sizeof(Sint16);
*audio_buf = (Uint8 *)malloc(*audio_len);
if ( *audio_buf == NULL ) {
SDL_Error(SDL_ENOMEM);
return(-1);
}
decoded = *audio_buf;
 
/* Get ready... Go! */
stereo = (MS_ADPCM_state.wavefmt.channels == 2);
state[0] = &MS_ADPCM_state.state[0];
state[1] = &MS_ADPCM_state.state[stereo];
while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) {
/* Grab the initial information for this block */
state[0]->hPredictor = *encoded++;
if ( stereo ) {
state[1]->hPredictor = *encoded++;
}
state[0]->iDelta = ((encoded[1]<<8)|encoded[0]);
encoded += sizeof(Sint16);
if ( stereo ) {
state[1]->iDelta = ((encoded[1]<<8)|encoded[0]);
encoded += sizeof(Sint16);
}
state[0]->iSamp1 = ((encoded[1]<<8)|encoded[0]);
encoded += sizeof(Sint16);
if ( stereo ) {
state[1]->iSamp1 = ((encoded[1]<<8)|encoded[0]);
encoded += sizeof(Sint16);
}
state[0]->iSamp2 = ((encoded[1]<<8)|encoded[0]);
encoded += sizeof(Sint16);
if ( stereo ) {
state[1]->iSamp2 = ((encoded[1]<<8)|encoded[0]);
encoded += sizeof(Sint16);
}
coeff[0] = MS_ADPCM_state.aCoeff[state[0]->hPredictor];
coeff[1] = MS_ADPCM_state.aCoeff[state[1]->hPredictor];
 
/* Store the two initial samples we start with */
decoded[0] = state[0]->iSamp2&0xFF;
decoded[1] = state[0]->iSamp2>>8;
decoded += 2;
if ( stereo ) {
decoded[0] = state[1]->iSamp2&0xFF;
decoded[1] = state[1]->iSamp2>>8;
decoded += 2;
}
decoded[0] = state[0]->iSamp1&0xFF;
decoded[1] = state[0]->iSamp1>>8;
decoded += 2;
if ( stereo ) {
decoded[0] = state[1]->iSamp1&0xFF;
decoded[1] = state[1]->iSamp1>>8;
decoded += 2;
}
 
/* Decode and store the other samples in this block */
samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)*
MS_ADPCM_state.wavefmt.channels;
while ( samplesleft > 0 ) {
nybble = (*encoded)>>4;
new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]);
decoded[0] = new_sample&0xFF;
new_sample >>= 8;
decoded[1] = new_sample&0xFF;
decoded += 2;
 
nybble = (*encoded)&0x0F;
new_sample = MS_ADPCM_nibble(state[1],nybble,coeff[1]);
decoded[0] = new_sample&0xFF;
new_sample >>= 8;
decoded[1] = new_sample&0xFF;
decoded += 2;
 
++encoded;
samplesleft -= 2;
}
encoded_len -= MS_ADPCM_state.wavefmt.blockalign;
}
free(freeable);
return(0);
}
 
struct IMA_ADPCM_decodestate {
Sint32 sample;
Sint8 index;
};
static struct IMA_ADPCM_decoder {
WaveFMT wavefmt;
Uint16 wSamplesPerBlock;
/* * * */
struct IMA_ADPCM_decodestate state[2];
} IMA_ADPCM_state;
 
static int InitIMA_ADPCM(WaveFMT *format)
{
Uint8 *rogue_feel;
Uint16 extra_info;
 
/* Set the rogue pointer to the IMA_ADPCM specific data */
IMA_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);
IMA_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);
IMA_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);
IMA_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate);
IMA_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign);
IMA_ADPCM_state.wavefmt.bitspersample =
SDL_SwapLE16(format->bitspersample);
rogue_feel = (Uint8 *)format+sizeof(*format);
if ( sizeof(*format) == 16 ) {
extra_info = ((rogue_feel[1]<<8)|rogue_feel[0]);
rogue_feel += sizeof(Uint16);
}
IMA_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);
return(0);
}
 
static Sint32 IMA_ADPCM_nibble(struct IMA_ADPCM_decodestate *state,Uint8 nybble)
{
const Sint32 max_audioval = ((1<<(16-1))-1);
const Sint32 min_audioval = -(1<<(16-1));
const int index_table[16] = {
-1, -1, -1, -1,
2, 4, 6, 8,
-1, -1, -1, -1,
2, 4, 6, 8
};
const Sint32 step_table[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130,
143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408,
449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282,
1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630,
9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350,
22385, 24623, 27086, 29794, 32767
};
Sint32 delta, step;
 
/* Compute difference and new sample value */
step = step_table[state->index];
delta = step >> 3;
if ( nybble & 0x04 ) delta += step;
if ( nybble & 0x02 ) delta += (step >> 1);
if ( nybble & 0x01 ) delta += (step >> 2);
if ( nybble & 0x08 ) delta = -delta;
state->sample += delta;
 
/* Update index value */
state->index += index_table[nybble];
if ( state->index > 88 ) {
state->index = 88;
} else
if ( state->index < 0 ) {
state->index = 0;
}
 
/* Clamp output sample */
if ( state->sample > max_audioval ) {
state->sample = max_audioval;
} else
if ( state->sample < min_audioval ) {
state->sample = min_audioval;
}
return(state->sample);
}
 
/* Fill the decode buffer with a channel block of data (8 samples) */
static void Fill_IMA_ADPCM_block(Uint8 *decoded, Uint8 *encoded,
int channel, int numchannels, struct IMA_ADPCM_decodestate *state)
{
int i;
Sint8 nybble;
Sint32 new_sample;
 
decoded += (channel * 2);
for ( i=0; i<4; ++i ) {
nybble = (*encoded)&0x0F;
new_sample = IMA_ADPCM_nibble(state, nybble);
decoded[0] = new_sample&0xFF;
new_sample >>= 8;
decoded[1] = new_sample&0xFF;
decoded += 2 * numchannels;
 
nybble = (*encoded)>>4;
new_sample = IMA_ADPCM_nibble(state, nybble);
decoded[0] = new_sample&0xFF;
new_sample >>= 8;
decoded[1] = new_sample&0xFF;
decoded += 2 * numchannels;
 
++encoded;
}
}
 
static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
{
struct IMA_ADPCM_decodestate *state;
Uint8 *freeable, *encoded, *decoded;
Sint32 encoded_len, samplesleft;
int c, channels;
 
/* Check to make sure we have enough variables in the state array */
channels = IMA_ADPCM_state.wavefmt.channels;
if ( channels > NELEMS(IMA_ADPCM_state.state) ) {
SDL_SetError("IMA ADPCM decoder can only handle %d channels",
NELEMS(IMA_ADPCM_state.state));
return(-1);
}
state = IMA_ADPCM_state.state;
 
/* Allocate the proper sized output buffer */
encoded_len = *audio_len;
encoded = *audio_buf;
freeable = *audio_buf;
*audio_len = (encoded_len/IMA_ADPCM_state.wavefmt.blockalign) *
IMA_ADPCM_state.wSamplesPerBlock*
IMA_ADPCM_state.wavefmt.channels*sizeof(Sint16);
*audio_buf = (Uint8 *)malloc(*audio_len);
if ( *audio_buf == NULL ) {
SDL_Error(SDL_ENOMEM);
return(-1);
}
decoded = *audio_buf;
 
/* Get ready... Go! */
while ( encoded_len >= IMA_ADPCM_state.wavefmt.blockalign ) {
/* Grab the initial information for this block */
for ( c=0; c<channels; ++c ) {
/* Fill the state information for this block */
state[c].sample = ((encoded[1]<<8)|encoded[0]);
encoded += 2;
if ( state[c].sample & 0x8000 ) {
state[c].sample -= 0x10000;
}
state[c].index = *encoded++;
/* Reserved byte in buffer header, should be 0 */
if ( *encoded++ != 0 ) {
/* Uh oh, corrupt data? Buggy code? */;
}
 
/* Store the initial sample we start with */
decoded[0] = state[c].sample&0xFF;
decoded[1] = state[c].sample>>8;
decoded += 2;
}
 
/* Decode and store the other samples in this block */
samplesleft = (IMA_ADPCM_state.wSamplesPerBlock-1)*channels;
while ( samplesleft > 0 ) {
for ( c=0; c<channels; ++c ) {
Fill_IMA_ADPCM_block(decoded, encoded,
c, channels, &state[c]);
encoded += 4;
samplesleft -= 8;
}
decoded += (channels * 8 * 2);
}
encoded_len -= IMA_ADPCM_state.wavefmt.blockalign;
}
free(freeable);
return(0);
}
 
SDL_AudioSpec * SDL_LoadWAV_RW (SDL_RWops *src, int freesrc,
SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
{
int was_error;
Chunk chunk;
int lenread;
int MS_ADPCM_encoded, IMA_ADPCM_encoded;
int samplesize;
 
/* WAV magic header */
Uint32 RIFFchunk;
Uint32 wavelen;
Uint32 WAVEmagic;
 
/* FMT chunk */
WaveFMT *format = NULL;
 
/* Make sure we are passed a valid data source */
was_error = 0;
if ( src == NULL ) {
was_error = 1;
goto done;
}
/* Check the magic header */
RIFFchunk = SDL_ReadLE32(src);
wavelen = SDL_ReadLE32(src);
WAVEmagic = SDL_ReadLE32(src);
if ( (RIFFchunk != RIFF) || (WAVEmagic != WAVE) ) {
SDL_SetError("Unrecognized file type (not WAVE)");
was_error = 1;
goto done;
}
 
/* Read the audio data format chunk */
chunk.data = NULL;
do {
if ( chunk.data != NULL ) {
free(chunk.data);
}
lenread = ReadChunk(src, &chunk);
if ( lenread < 0 ) {
was_error = 1;
goto done;
}
} while ( (chunk.magic == FACT) || (chunk.magic == LIST) );
 
/* Decode the audio data format */
format = (WaveFMT *)chunk.data;
if ( chunk.magic != FMT ) {
SDL_SetError("Complex WAVE files not supported");
was_error = 1;
goto done;
}
MS_ADPCM_encoded = IMA_ADPCM_encoded = 0;
switch (SDL_SwapLE16(format->encoding)) {
case PCM_CODE:
/* We can understand this */
break;
case MS_ADPCM_CODE:
/* Try to understand this */
if ( InitMS_ADPCM(format) < 0 ) {
was_error = 1;
goto done;
}
MS_ADPCM_encoded = 1;
break;
case IMA_ADPCM_CODE:
/* Try to understand this */
if ( InitIMA_ADPCM(format) < 0 ) {
was_error = 1;
goto done;
}
IMA_ADPCM_encoded = 1;
break;
default:
SDL_SetError("Unknown WAVE data format: 0x%.4x",
SDL_SwapLE16(format->encoding));
was_error = 1;
goto done;
}
memset(spec, 0, (sizeof *spec));
spec->freq = SDL_SwapLE32(format->frequency);
switch (SDL_SwapLE16(format->bitspersample)) {
case 4:
if ( MS_ADPCM_encoded || IMA_ADPCM_encoded ) {
spec->format = AUDIO_S16;
} else {
was_error = 1;
}
break;
case 8:
spec->format = AUDIO_U8;
break;
case 16:
spec->format = AUDIO_S16;
break;
default:
was_error = 1;
break;
}
if ( was_error ) {
SDL_SetError("Unknown %d-bit PCM data format",
SDL_SwapLE16(format->bitspersample));
goto done;
}
spec->channels = (Uint8)SDL_SwapLE16(format->channels);
spec->samples = 4096; /* Good default buffer size */
 
/* Read the audio data chunk */
*audio_buf = NULL;
do {
if ( *audio_buf != NULL ) {
free(*audio_buf);
}
lenread = ReadChunk(src, &chunk);
if ( lenread < 0 ) {
was_error = 1;
goto done;
}
*audio_len = lenread;
*audio_buf = chunk.data;
} while ( chunk.magic != DATA );
 
if ( MS_ADPCM_encoded ) {
if ( MS_ADPCM_decode(audio_buf, audio_len) < 0 ) {
was_error = 1;
goto done;
}
}
if ( IMA_ADPCM_encoded ) {
if ( IMA_ADPCM_decode(audio_buf, audio_len) < 0 ) {
was_error = 1;
goto done;
}
}
 
/* Don't return a buffer that isn't a multiple of samplesize */
samplesize = ((spec->format & 0xFF)/8)*spec->channels;
*audio_len &= ~(samplesize-1);
 
done:
if ( format != NULL ) {
free(format);
}
if ( freesrc && src ) {
SDL_RWclose(src);
}
if ( was_error ) {
spec = NULL;
}
return(spec);
}
 
/* Since the WAV memory is allocated in the shared library, it must also
be freed here. (Necessary under Win32, VC++)
*/
void SDL_FreeWAV(Uint8 *audio_buf)
{
if ( audio_buf != NULL ) {
free(audio_buf);
}
}
 
static int ReadChunk(SDL_RWops *src, Chunk *chunk)
{
chunk->magic = SDL_ReadLE32(src);
chunk->length = SDL_ReadLE32(src);
chunk->data = (Uint8 *)malloc(chunk->length);
if ( chunk->data == NULL ) {
SDL_Error(SDL_ENOMEM);
return(-1);
}
if ( SDL_RWread(src, chunk->data, chunk->length, 1) != 1 ) {
SDL_Error(SDL_EFREAD);
free(chunk->data);
return(-1);
}
return(chunk->length);
}
 
#endif /* ENABLE_FILE */
/contrib/games/wolf3d/SDL/SDL_wave.h
0,0 → 1,65
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
 
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
Sam Lantinga
slouken@devolution.com
*/
 
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_wave.h,v 1.2 2001/04/26 16:50:17 hercules Exp $";
#endif
 
/* WAVE files are little-endian */
 
/*******************************************/
/* Define values for Microsoft WAVE format */
/*******************************************/
#define RIFF 0x46464952 /* "RIFF" */
#define WAVE 0x45564157 /* "WAVE" */
#define FACT 0x74636166 /* "fact" */
#define LIST 0x5453494c /* "LIST" */
#define FMT 0x20746D66 /* "fmt " */
#define DATA 0x61746164 /* "data" */
#define PCM_CODE 0x0001
#define MS_ADPCM_CODE 0x0002
#define IMA_ADPCM_CODE 0x0011
#define WAVE_MONO 1
#define WAVE_STEREO 2
 
/* Normally, these three chunks come consecutively in a WAVE file */
typedef struct WaveFMT {
/* Not saved in the chunk we read:
Uint32 FMTchunk;
Uint32 fmtlen;
*/
Uint16 encoding;
Uint16 channels; /* 1 = mono, 2 = stereo */
Uint32 frequency; /* One of 11025, 22050, or 44100 Hz */
Uint32 byterate; /* Average bytes per second */
Uint16 blockalign; /* Bytes per sample block */
Uint16 bitspersample; /* One of 8, 12, 16, or 4 for ADPCM */
} WaveFMT;
 
/* The general chunk found in the WAVE file */
typedef struct Chunk {
Uint32 magic;
Uint32 length;
Uint8 *data; /* Data includes magic and length */
} Chunk;
 
/contrib/games/wolf3d/SDL_mixer/SDL_mixer.h
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 */
/contrib/games/wolf3d/SDL_mixer/dynamic_flac.h
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();
/contrib/games/wolf3d/SDL_mixer/dynamic_fluidsynth.h
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();
/contrib/games/wolf3d/SDL_mixer/dynamic_mod.h
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();
/contrib/games/wolf3d/SDL_mixer/dynamic_mp3.h
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();
/contrib/games/wolf3d/SDL_mixer/dynamic_ogg.h
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();
/contrib/games/wolf3d/SDL_mixer/effect_position.c
0,0 → 1,1619
/*
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 internally supported special effects that use SDL_mixer's
effect callback API. They are meant for speed over quality. :)
*/
 
/* $Id$ */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include "SDL.h"
#include "SDL_mixer.h"
#include "SDL_endian.h"
 
#define __MIX_INTERNAL_EFFECT__
#include "effects_internal.h"
 
/* profile code:
#include <sys/time.h>
#include <unistd.h>
struct timeval tv1;
struct timeval tv2;
gettimeofday(&tv1, NULL);
 
... do your thing here ...
 
gettimeofday(&tv2, NULL);
printf("%ld\n", tv2.tv_usec - tv1.tv_usec);
*/
 
 
/*
* Positional effects...panning, distance attenuation, etc.
*/
 
typedef struct _Eff_positionargs
{
volatile float left_f;
volatile float right_f;
volatile Uint8 left_u8;
volatile Uint8 right_u8;
volatile float left_rear_f;
volatile float right_rear_f;
volatile float center_f;
volatile float lfe_f;
volatile Uint8 left_rear_u8;
volatile Uint8 right_rear_u8;
volatile Uint8 center_u8;
volatile Uint8 lfe_u8;
volatile float distance_f;
volatile Uint8 distance_u8;
volatile Sint16 room_angle;
volatile int in_use;
volatile int channels;
} position_args;
 
static position_args **pos_args_array = NULL;
static position_args *pos_args_global = NULL;
static int position_channels = 0;
 
void _Eff_PositionDeinit(void)
{
int i;
for (i = 0; i < position_channels; i++) {
SDL_free(pos_args_array[i]);
}
 
position_channels = 0;
 
SDL_free(pos_args_global);
pos_args_global = NULL;
SDL_free(pos_args_array);
pos_args_array = NULL;
}
 
 
/* This just frees up the callback-specific data. */
static void _Eff_PositionDone(int channel, void *udata)
{
if (channel < 0) {
if (pos_args_global != NULL) {
SDL_free(pos_args_global);
pos_args_global = NULL;
}
}
 
else if (pos_args_array[channel] != NULL) {
SDL_free(pos_args_array[channel]);
pos_args_array[channel] = NULL;
}
}
 
 
static void _Eff_position_u8(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Uint8 *ptr = (Uint8 *) stream;
int i;
 
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
if (len % sizeof (Uint16) != 0) {
*ptr = (Uint8) (((float) *ptr) * args->distance_f);
ptr++;
len--;
}
 
if (args->room_angle == 180)
for (i = 0; i < len; i += sizeof (Uint8) * 2) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
ptr++;
}
else for (i = 0; i < len; i += sizeof (Uint8) * 2) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
ptr++;
}
}
static void _Eff_position_u8_c4(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Uint8 *ptr = (Uint8 *) stream;
int i;
 
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
if (len % sizeof (Uint16) != 0) {
*ptr = (Uint8) (((float) *ptr) * args->distance_f);
ptr++;
len--;
}
 
if (args->room_angle == 0)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 90)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 180)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 270)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
ptr++;
}
}
 
 
static void _Eff_position_u8_c6(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Uint8 *ptr = (Uint8 *) stream;
int i;
 
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
if (len % sizeof (Uint16) != 0) {
*ptr = (Uint8) (((float) *ptr) * args->distance_f);
ptr++;
len--;
}
 
if (args->room_angle == 0)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->center_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->lfe_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 90)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f/2) + 128)
+ (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f/2) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->lfe_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 180)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f/2) + 128)
+ (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f/2) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->lfe_f) * args->distance_f) + 128);
ptr++;
}
else if (args->room_angle == 270)
for (i = 0; i < len; i += sizeof (Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f/2) + 128)
+ (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f/2) + 128);
ptr++;
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->lfe_f) * args->distance_f) + 128);
ptr++;
}
}
 
 
/*
* This one runs about 10.1 times faster than the non-table version, with
* no loss in quality. It does, however, require 64k of memory for the
* lookup table. Also, this will only update position information once per
* call; the non-table version always checks the arguments for each sample,
* in case the user has called Mix_SetPanning() or whatnot again while this
* callback is running.
*/
static void _Eff_position_table_u8(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Uint8 *ptr = (Uint8 *) stream;
Uint32 *p;
int i;
Uint8 *l = ((Uint8 *) _Eff_volume_table) + (256 * args->left_u8);
Uint8 *r = ((Uint8 *) _Eff_volume_table) + (256 * args->right_u8);
Uint8 *d = ((Uint8 *) _Eff_volume_table) + (256 * args->distance_u8);
 
if (args->room_angle == 180) {
Uint8 *temp = l;
l = r;
r = temp;
}
/*
* if there's only a mono channnel, then l[] and r[] are always
* volume 255, and are therefore throwaways. Still, we have to
* be sure not to overrun the audio buffer...
*/
while (len % sizeof (Uint32) != 0) {
*ptr = d[l[*ptr]];
ptr++;
if (args->channels > 1) {
*ptr = d[r[*ptr]];
ptr++;
}
len -= args->channels;
}
 
p = (Uint32 *) ptr;
 
for (i = 0; i < len; i += sizeof (Uint32)) {
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
*p = (d[l[(*p & 0xFF000000) >> 24]] << 24) |
(d[r[(*p & 0x00FF0000) >> 16]] << 16) |
(d[l[(*p & 0x0000FF00) >> 8]] << 8) |
(d[r[(*p & 0x000000FF) ]] ) ;
#else
*p = (d[r[(*p & 0xFF000000) >> 24]] << 24) |
(d[l[(*p & 0x00FF0000) >> 16]] << 16) |
(d[r[(*p & 0x0000FF00) >> 8]] << 8) |
(d[l[(*p & 0x000000FF) ]] ) ;
#endif
++p;
}
}
 
 
static void _Eff_position_s8(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Sint8 *ptr = (Sint8 *) stream;
int i;
 
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
if (len % sizeof (Sint16) != 0) {
*ptr = (Sint8) (((float) *ptr) * args->distance_f);
ptr++;
len--;
}
 
if (args->room_angle == 180)
for (i = 0; i < len; i += sizeof (Sint8) * 2) {
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
ptr++;
}
else
for (i = 0; i < len; i += sizeof (Sint8) * 2) {
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f);
ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f);
ptr++;
}
}
static void _Eff_position_s8_c4(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Sint8 *ptr = (Sint8 *) stream;
int i;
 
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
if (len % sizeof (Sint16) != 0) {
*ptr = (Sint8) (((float) *ptr) * args->distance_f);
ptr++;
len--;
}
 
for (i = 0; i < len; i += sizeof (Sint8) * 4) {
switch (args->room_angle) {
case 0:
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
break;
case 90:
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
break;
case 180:
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
break;
case 270:
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
break;
}
}
}
static void _Eff_position_s8_c6(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Sint8 *ptr = (Sint8 *) stream;
int i;
 
/*
* if there's only a mono channnel (the only way we wouldn't have
* a len divisible by 2 here), then left_f and right_f are always
* 1.0, and are therefore throwaways.
*/
if (len % sizeof (Sint16) != 0) {
*ptr = (Sint8) (((float) *ptr) * args->distance_f);
ptr++;
len--;
}
 
for (i = 0; i < len; i += sizeof (Sint8) * 6) {
switch (args->room_angle) {
case 0:
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->center_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
break;
case 90:
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
+ (Sint8)((((float) *ptr) * args->right_f) * args->distance_f / 2); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
break;
case 180:
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f / 2)
+ (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
break;
case 270:
*ptr = (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_rear_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->right_f) * args->distance_f); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f / 2)
+ (Sint8)((((float) *ptr) * args->left_rear_f) * args->distance_f / 2); ptr++;
*ptr = (Sint8)((((float) *ptr) * args->lfe_f) * args->distance_f); ptr++;
break;
}
}
}
 
 
/*
* This one runs about 10.1 times faster than the non-table version, with
* no loss in quality. It does, however, require 64k of memory for the
* lookup table. Also, this will only update position information once per
* call; the non-table version always checks the arguments for each sample,
* in case the user has called Mix_SetPanning() or whatnot again while this
* callback is running.
*/
static void _Eff_position_table_s8(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Sint8 *ptr = (Sint8 *) stream;
Uint32 *p;
int i;
Sint8 *l = ((Sint8 *) _Eff_volume_table) + (256 * args->left_u8);
Sint8 *r = ((Sint8 *) _Eff_volume_table) + (256 * args->right_u8);
Sint8 *d = ((Sint8 *) _Eff_volume_table) + (256 * args->distance_u8);
 
if (args->room_angle == 180) {
Sint8 *temp = l;
l = r;
r = temp;
}
 
 
while (len % sizeof (Uint32) != 0) {
*ptr = d[l[*ptr]];
ptr++;
if (args->channels > 1) {
*ptr = d[r[*ptr]];
ptr++;
}
len -= args->channels;
}
 
p = (Uint32 *) ptr;
 
for (i = 0; i < len; i += sizeof (Uint32)) {
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
*p = (d[l[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
(d[r[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
(d[l[((Sint16)(Sint8)((*p & 0x0000FF00) >> 8))+128]] << 8) |
(d[r[((Sint16)(Sint8)((*p & 0x000000FF) ))+128]] ) ;
#else
*p = (d[r[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
(d[l[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
(d[r[((Sint16)(Sint8)((*p & 0x0000FF00) >> 8))+128]] << 8) |
(d[l[((Sint16)(Sint8)((*p & 0x000000FF) ))+128]] ) ;
#endif
++p;
}
 
 
}
 
 
/* !!! FIXME : Optimize the code for 16-bit samples? */
 
static void _Eff_position_u16lsb(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Uint16) * 2) {
Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
 
if (args->room_angle == 180) {
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
}
else {
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
}
}
}
static void _Eff_position_u16lsb_c4(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Uint16) * 4) {
Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
* args->distance_f) + 32768);
Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
* args->distance_f) + 32768);
 
switch (args->room_angle) {
case 0:
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
break;
case 90:
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
break;
case 180:
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
break;
case 270:
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
break;
}
}
}
static void _Eff_position_u16lsb_c6(int chan, void *stream, int len, void *udata)
{
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Uint16) * 6) {
Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
Sint16 samprr = (Sint16) (SDL_SwapLE16(*(ptr+3)) - 32768);
Sint16 sampce = (Sint16) (SDL_SwapLE16(*(ptr+4)) - 32768);
Sint16 sampwf = (Sint16) (SDL_SwapLE16(*(ptr+5)) - 32768);
 
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
* args->distance_f) + 32768);
Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
* args->distance_f) + 32768);
Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
* args->distance_f) + 32768);
Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
* args->distance_f) + 32768);
 
switch (args->room_angle) {
case 0:
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapce);
*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
break;
case 90:
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr)/2 + (Uint16) SDL_SwapLE16(swaprr)/2;
*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
break;
case 180:
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
break;
case 270:
*(ptr++) = (Uint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl);
*(ptr++) = (Uint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapr);
*(ptr++) = (Uint16) SDL_SwapLE16(swapl)/2 + (Uint16) SDL_SwapLE16(swaplr)/2;
*(ptr++) = (Uint16) SDL_SwapLE16(swapwf);
break;
}
}
}
 
static void _Eff_position_s16lsb(int chan, void *stream, int len, void *udata)
{
/* 16 signed bits (lsb) * 2 channels. */
volatile position_args *args = (volatile position_args *) udata;
Sint16 *ptr = (Sint16 *) stream;
int i;
 
#if 0
if (len % (sizeof(Sint16) * 2)) {
fprintf(stderr,"Not an even number of frames! len=%d\n", len);
return;
}
#endif
 
for (i = 0; i < len; i += sizeof (Sint16) * 2) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
args->right_f) * args->distance_f);
if (args->room_angle == 180) {
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
}
else {
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
}
}
}
static void _Eff_position_s16lsb_c4(int chan, void *stream, int len, void *udata)
{
/* 16 signed bits (lsb) * 4 channels. */
volatile position_args *args = (volatile position_args *) udata;
Sint16 *ptr = (Sint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Sint16) * 4) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
args->right_f) * args->distance_f);
Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
args->left_rear_f) * args->distance_f);
Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
args->right_rear_f) * args->distance_f);
switch (args->room_angle) {
case 0:
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
break;
case 90:
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
break;
case 180:
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
break;
case 270:
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
break;
}
}
}
 
static void _Eff_position_s16lsb_c6(int chan, void *stream, int len, void *udata)
{
/* 16 signed bits (lsb) * 6 channels. */
volatile position_args *args = (volatile position_args *) udata;
Sint16 *ptr = (Sint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Sint16) * 6) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
args->right_f) * args->distance_f);
Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+2))) *
args->left_rear_f) * args->distance_f);
Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+3))) *
args->right_rear_f) * args->distance_f);
Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+4))) *
args->center_f) * args->distance_f);
Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+5))) *
args->lfe_f) * args->distance_f);
switch (args->room_angle) {
case 0:
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapce);
*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
break;
case 90:
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr)/2 + (Sint16) SDL_SwapLE16(swaprr)/2;
*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
break;
case 180:
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
break;
case 270:
*(ptr++) = (Sint16) SDL_SwapLE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl);
*(ptr++) = (Sint16) SDL_SwapLE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapr);
*(ptr++) = (Sint16) SDL_SwapLE16(swapl)/2 + (Sint16) SDL_SwapLE16(swaplr)/2;
*(ptr++) = (Sint16) SDL_SwapLE16(swapwf);
break;
}
}
}
 
static void _Eff_position_u16msb(int chan, void *stream, int len, void *udata)
{
/* 16 signed bits (lsb) * 2 channels. */
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Sint16) * 2) {
Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
 
if (args->room_angle == 180) {
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
}
else {
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
}
}
}
static void _Eff_position_u16msb_c4(int chan, void *stream, int len, void *udata)
{
/* 16 signed bits (lsb) * 4 channels. */
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Sint16) * 4) {
Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
* args->distance_f) + 32768);
Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
* args->distance_f) + 32768);
 
switch (args->room_angle) {
case 0:
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
break;
case 90:
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
break;
case 180:
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
break;
case 270:
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
break;
}
}
}
static void _Eff_position_u16msb_c6(int chan, void *stream, int len, void *udata)
{
/* 16 signed bits (lsb) * 6 channels. */
volatile position_args *args = (volatile position_args *) udata;
Uint16 *ptr = (Uint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Sint16) * 6) {
Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
Sint16 samprr = (Sint16) (SDL_SwapBE16(*(ptr+3)) - 32768);
Sint16 sampce = (Sint16) (SDL_SwapBE16(*(ptr+4)) - 32768);
Sint16 sampwf = (Sint16) (SDL_SwapBE16(*(ptr+5)) - 32768);
Uint16 swapl = (Uint16) ((Sint16) (((float) sampl * args->left_f)
* args->distance_f) + 32768);
Uint16 swapr = (Uint16) ((Sint16) (((float) sampr * args->right_f)
* args->distance_f) + 32768);
Uint16 swaplr = (Uint16) ((Sint16) (((float) samplr * args->left_rear_f)
* args->distance_f) + 32768);
Uint16 swaprr = (Uint16) ((Sint16) (((float) samprr * args->right_rear_f)
* args->distance_f) + 32768);
Uint16 swapce = (Uint16) ((Sint16) (((float) sampce * args->center_f)
* args->distance_f) + 32768);
Uint16 swapwf = (Uint16) ((Sint16) (((float) sampwf * args->lfe_f)
* args->distance_f) + 32768);
 
switch (args->room_angle) {
case 0:
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapce);
*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
break;
case 90:
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr)/2 + (Uint16) SDL_SwapBE16(swaprr)/2;
*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
break;
case 180:
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
break;
case 270:
*(ptr++) = (Uint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl);
*(ptr++) = (Uint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapr);
*(ptr++) = (Uint16) SDL_SwapBE16(swapl)/2 + (Uint16) SDL_SwapBE16(swaplr)/2;
*(ptr++) = (Uint16) SDL_SwapBE16(swapwf);
break;
}
}
}
 
static void _Eff_position_s16msb(int chan, void *stream, int len, void *udata)
{
/* 16 signed bits (lsb) * 2 channels. */
volatile position_args *args = (volatile position_args *) udata;
Sint16 *ptr = (Sint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Sint16) * 2) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
args->right_f) * args->distance_f);
*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
}
}
static void _Eff_position_s16msb_c4(int chan, void *stream, int len, void *udata)
{
/* 16 signed bits (lsb) * 4 channels. */
volatile position_args *args = (volatile position_args *) udata;
Sint16 *ptr = (Sint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Sint16) * 4) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
args->right_f) * args->distance_f);
Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
args->left_rear_f) * args->distance_f);
Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
args->right_rear_f) * args->distance_f);
switch (args->room_angle) {
case 0:
*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
break;
case 90:
*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
break;
case 180:
*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
break;
case 270:
*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
break;
}
}
}
static void _Eff_position_s16msb_c6(int chan, void *stream, int len, void *udata)
{
/* 16 signed bits (lsb) * 6 channels. */
volatile position_args *args = (volatile position_args *) udata;
Sint16 *ptr = (Sint16 *) stream;
int i;
 
for (i = 0; i < len; i += sizeof (Sint16) * 6) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
args->right_f) * args->distance_f);
Sint16 swaplr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+2))) *
args->left_rear_f) * args->distance_f);
Sint16 swaprr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+3))) *
args->right_rear_f) * args->distance_f);
Sint16 swapce = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+4))) *
args->center_f) * args->distance_f);
Sint16 swapwf = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+5))) *
args->lfe_f) * args->distance_f);
 
switch (args->room_angle) {
case 0:
*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapce);
*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
break;
case 90:
*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapr)/2 + (Sint16) SDL_SwapBE16(swaprr)/2;
*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
break;
case 180:
*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
*(ptr++) = (Sint16) SDL_SwapBE16(swaprr)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
break;
case 270:
*(ptr++) = (Sint16) SDL_SwapBE16(swaplr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapl);
*(ptr++) = (Sint16) SDL_SwapBE16(swaprr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapr);
*(ptr++) = (Sint16) SDL_SwapBE16(swapl)/2 + (Sint16) SDL_SwapBE16(swaplr)/2;
*(ptr++) = (Sint16) SDL_SwapBE16(swapwf);
break;
}
}
}
 
static void init_position_args(position_args *args)
{
memset(args, '\0', sizeof (position_args));
args->in_use = 0;
args->room_angle = 0;
args->left_u8 = args->right_u8 = args->distance_u8 = 255;
args->left_f = args->right_f = args->distance_f = 1.0f;
args->left_rear_u8 = args->right_rear_u8 = args->center_u8 = args->lfe_u8 = 255;
args->left_rear_f = args->right_rear_f = args->center_f = args->lfe_f = 1.0f;
Mix_QuerySpec(NULL, NULL, (int *) &args->channels);
}
 
 
static position_args *get_position_arg(int channel)
{
void *rc;
int i;
 
if (channel < 0) {
if (pos_args_global == NULL) {
pos_args_global = SDL_malloc(sizeof (position_args));
if (pos_args_global == NULL) {
Mix_SetError("Out of memory");
return(NULL);
}
init_position_args(pos_args_global);
}
 
return(pos_args_global);
}
 
if (channel >= position_channels) {
rc = SDL_realloc(pos_args_array, (channel + 1) * sizeof (position_args *));
if (rc == NULL) {
Mix_SetError("Out of memory");
return(NULL);
}
pos_args_array = (position_args **) rc;
for (i = position_channels; i <= channel; i++) {
pos_args_array[i] = NULL;
}
position_channels = channel + 1;
}
 
if (pos_args_array[channel] == NULL) {
pos_args_array[channel] = (position_args *)SDL_malloc(sizeof(position_args));
if (pos_args_array[channel] == NULL) {
Mix_SetError("Out of memory");
return(NULL);
}
init_position_args(pos_args_array[channel]);
}
 
return(pos_args_array[channel]);
}
 
 
static Mix_EffectFunc_t get_position_effect_func(Uint16 format, int channels)
{
Mix_EffectFunc_t f = NULL;
 
switch (format) {
case AUDIO_U8:
switch (channels) {
case 1:
case 2:
f = (_Eff_build_volume_table_u8()) ? _Eff_position_table_u8 :
_Eff_position_u8;
break;
case 4:
f = _Eff_position_u8_c4;
break;
case 6:
f = _Eff_position_u8_c6;
break;
}
break;
 
case AUDIO_S8:
switch (channels) {
case 1:
case 2:
f = (_Eff_build_volume_table_s8()) ? _Eff_position_table_s8 :
_Eff_position_s8;
break;
case 4:
f = _Eff_position_s8_c4;
break;
case 6:
f = _Eff_position_s8_c6;
break;
}
break;
 
case AUDIO_U16LSB:
switch (channels) {
case 1:
case 2:
f = _Eff_position_u16lsb;
break;
case 4:
f = _Eff_position_u16lsb_c4;
break;
case 6:
f = _Eff_position_u16lsb_c6;
break;
}
break;
 
case AUDIO_S16LSB:
switch (channels) {
case 1:
case 2:
f = _Eff_position_s16lsb;
break;
case 4:
f = _Eff_position_s16lsb_c4;
break;
case 6:
f = _Eff_position_s16lsb_c6;
break;
}
break;
 
case AUDIO_U16MSB:
switch (channels) {
case 1:
case 2:
f = _Eff_position_u16msb;
break;
case 4:
f = _Eff_position_u16msb_c4;
break;
case 6:
f = _Eff_position_u16msb_c6;
break;
}
break;
 
case AUDIO_S16MSB:
switch (channels) {
case 1:
case 2:
f = _Eff_position_s16msb;
break;
case 4:
f = _Eff_position_s16msb_c4;
break;
case 6:
f = _Eff_position_s16msb_c6;
break;
}
break;
 
default:
Mix_SetError("Unsupported audio format");
}
 
return(f);
}
 
static Uint8 speaker_amplitude[6];
 
static void set_amplitudes(int channels, int angle, int room_angle)
{
int left = 255, right = 255;
int left_rear = 255, right_rear = 255, center = 255;
 
angle = SDL_abs(angle) % 360; /* make angle between 0 and 359. */
 
if (channels == 2)
{
/*
* We only attenuate by position if the angle falls on the far side
* of center; That is, an angle that's due north would not attenuate
* either channel. Due west attenuates the right channel to 0.0, and
* due east attenuates the left channel to 0.0. Slightly east of
* center attenuates the left channel a little, and the right channel
* not at all. I think of this as occlusion by one's own head. :)
*
* ...so, we split our angle circle into four quadrants...
*/
if (angle < 90) {
left = 255 - ((int) (255.0f * (((float) angle) / 89.0f)));
} else if (angle < 180) {
left = (int) (255.0f * (((float) (angle - 90)) / 89.0f));
} else if (angle < 270) {
right = 255 - ((int) (255.0f * (((float) (angle - 180)) / 89.0f)));
} else {
right = (int) (255.0f * (((float) (angle - 270)) / 89.0f));
}
}
 
if (channels == 4 || channels == 6)
{
/*
* An angle that's due north does not attenuate the center channel.
* An angle in the first quadrant, 0-90, does not attenuate the RF.
*
* ...so, we split our angle circle into 8 ...
*
* CE
* 0
* LF | RF
* |
* 270<-------|----------->90
* |
* LR | RR
* 180
*
*/
if (angle < 45) {
left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
left_rear = 255 - ((int) (255.0f * (((float) (angle + 45)) / 89.0f)));
right_rear = 255 - ((int) (255.0f * (((float) (90 - angle)) / 179.0f)));
} else if (angle < 90) {
center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
left = ((int) (255.0f * (((float) (180 - angle)) / 179.0f)));
left_rear = 255 - ((int) (255.0f * (((float) (135 - angle)) / 89.0f)));
right_rear = ((int) (255.0f * (((float) (90 + angle)) / 179.0f)));
} else if (angle < 135) {
center = ((int) (255.0f * (((float) (225 - angle)) / 179.0f)));
left = 255 - ((int) (255.0f * (((float) (angle - 45)) / 89.0f)));
right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
} else if (angle < 180) {
center = 255 - ((int) (255.0f * (((float) (angle - 90)) / 89.0f)));
left = 255 - ((int) (255.0f * (((float) (225 - angle)) / 89.0f)));
right = ((int) (255.0f * (((float) (270 - angle)) / 179.0f)));
left_rear = ((int) (255.0f * (((float) (angle)) / 179.0f)));
} else if (angle < 225) {
center = 255 - ((int) (255.0f * (((float) (270 - angle)) / 89.0f)));
left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
right = 255 - ((int) (255.0f * (((float) (angle - 135)) / 89.0f)));
right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
} else if (angle < 270) {
center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
left = ((int) (255.0f * (((float) (angle - 90)) / 179.0f)));
right = 255 - ((int) (255.0f * (((float) (315 - angle)) / 89.0f)));
right_rear = ((int) (255.0f * (((float) (360 - angle)) / 179.0f)));
} else if (angle < 315) {
center = ((int) (255.0f * (((float) (angle - 135)) / 179.0f)));
right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
right_rear = 255 - ((int) (255.0f * (((float) (angle - 225)) / 89.0f)));
} else {
right = ((int) (255.0f * (((float) (angle - 180)) / 179.0f)));
left_rear = ((int) (255.0f * (((float) (450 - angle)) / 179.0f)));
right_rear = 255 - ((int) (255.0f * (((float) (405 - angle)) / 89.0f)));
}
}
 
if (left < 0) left = 0; if (left > 255) left = 255;
if (right < 0) right = 0; if (right > 255) right = 255;
if (left_rear < 0) left_rear = 0; if (left_rear > 255) left_rear = 255;
if (right_rear < 0) right_rear = 0; if (right_rear > 255) right_rear = 255;
if (center < 0) center = 0; if (center > 255) center = 255;
 
if (room_angle == 90) {
speaker_amplitude[0] = (Uint8)left_rear;
speaker_amplitude[1] = (Uint8)left;
speaker_amplitude[2] = (Uint8)right_rear;
speaker_amplitude[3] = (Uint8)right;
}
else if (room_angle == 180) {
if (channels == 2) {
speaker_amplitude[0] = (Uint8)right;
speaker_amplitude[1] = (Uint8)left;
}
else {
speaker_amplitude[0] = (Uint8)right_rear;
speaker_amplitude[1] = (Uint8)left_rear;
speaker_amplitude[2] = (Uint8)right;
speaker_amplitude[3] = (Uint8)left;
}
}
else if (room_angle == 270) {
speaker_amplitude[0] = (Uint8)right;
speaker_amplitude[1] = (Uint8)right_rear;
speaker_amplitude[2] = (Uint8)left;
speaker_amplitude[3] = (Uint8)left_rear;
}
else {
speaker_amplitude[0] = (Uint8)left;
speaker_amplitude[1] = (Uint8)right;
speaker_amplitude[2] = (Uint8)left_rear;
speaker_amplitude[3] = (Uint8)right_rear;
}
speaker_amplitude[4] = (Uint8)center;
speaker_amplitude[5] = 255;
}
 
int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);
 
int Mix_SetPanning(int channel, Uint8 left, Uint8 right)
{
Mix_EffectFunc_t f = NULL;
int channels;
Uint16 format;
position_args *args = NULL;
int retval = 1;
 
Mix_QuerySpec(NULL, &format, &channels);
 
if (channels != 2 && channels != 4 && channels != 6) /* it's a no-op; we call that successful. */
return(1);
 
if (channels > 2) {
/* left = right = 255 => angle = 0, to unregister effect as when channels = 2 */
/* left = 255 => angle = -90; left = 0 => angle = +89 */
int angle = 0;
if ((left != 255) || (right != 255)) {
angle = (int)left;
angle = 127 - angle;
angle = -angle;
angle = angle * 90 / 128; /* Make it larger for more effect? */
}
return( Mix_SetPosition(channel, angle, 0) );
}
 
f = get_position_effect_func(format, channels);
if (f == NULL)
return(0);
 
SDL_LockAudio();
args = get_position_arg(channel);
if (!args) {
SDL_UnlockAudio();
return(0);
}
 
/* it's a no-op; unregister the effect, if it's registered. */
if ((args->distance_u8 == 255) && (left == 255) && (right == 255)) {
if (args->in_use) {
retval = _Mix_UnregisterEffect_locked(channel, f);
SDL_UnlockAudio();
return(retval);
} else {
SDL_UnlockAudio();
return(1);
}
}
 
args->left_u8 = left;
args->left_f = ((float) left) / 255.0f;
args->right_u8 = right;
args->right_f = ((float) right) / 255.0f;
args->room_angle = 0;
 
if (!args->in_use) {
args->in_use = 1;
retval=_Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void*)args);
}
 
SDL_UnlockAudio();
return(retval);
}
 
 
int Mix_SetDistance(int channel, Uint8 distance)
{
Mix_EffectFunc_t f = NULL;
Uint16 format;
position_args *args = NULL;
int channels;
int retval = 1;
 
Mix_QuerySpec(NULL, &format, &channels);
f = get_position_effect_func(format, channels);
if (f == NULL)
return(0);
 
SDL_LockAudio();
args = get_position_arg(channel);
if (!args) {
SDL_UnlockAudio();
return(0);
}
 
distance = 255 - distance; /* flip it to our scale. */
 
/* it's a no-op; unregister the effect, if it's registered. */
if ((distance == 255) && (args->left_u8 == 255) && (args->right_u8 == 255)) {
if (args->in_use) {
retval = _Mix_UnregisterEffect_locked(channel, f);
SDL_UnlockAudio();
return(retval);
} else {
SDL_UnlockAudio();
return(1);
}
}
 
args->distance_u8 = distance;
args->distance_f = ((float) distance) / 255.0f;
if (!args->in_use) {
args->in_use = 1;
retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args);
}
 
SDL_UnlockAudio();
return(retval);
}
 
 
int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance)
{
Mix_EffectFunc_t f = NULL;
Uint16 format;
int channels;
position_args *args = NULL;
Sint16 room_angle = 0;
int retval = 1;
 
Mix_QuerySpec(NULL, &format, &channels);
f = get_position_effect_func(format, channels);
if (f == NULL)
return(0);
 
angle = SDL_abs(angle) % 360; /* make angle between 0 and 359. */
 
SDL_LockAudio();
args = get_position_arg(channel);
if (!args) {
SDL_UnlockAudio();
return(0);
}
 
/* it's a no-op; unregister the effect, if it's registered. */
if ((!distance) && (!angle)) {
if (args->in_use) {
retval = _Mix_UnregisterEffect_locked(channel, f);
SDL_UnlockAudio();
return(retval);
} else {
SDL_UnlockAudio();
return(1);
}
}
 
if (channels == 2)
{
if (angle > 180)
room_angle = 180; /* exchange left and right channels */
else room_angle = 0;
}
 
if (channels == 4 || channels == 6)
{
if (angle > 315) room_angle = 0;
else if (angle > 225) room_angle = 270;
else if (angle > 135) room_angle = 180;
else if (angle > 45) room_angle = 90;
else room_angle = 0;
}
 
 
distance = 255 - distance; /* flip it to scale Mix_SetDistance() uses. */
 
set_amplitudes(channels, angle, room_angle);
 
args->left_u8 = speaker_amplitude[0];
args->left_f = ((float) speaker_amplitude[0]) / 255.0f;
args->right_u8 = speaker_amplitude[1];
args->right_f = ((float) speaker_amplitude[1]) / 255.0f;
args->left_rear_u8 = speaker_amplitude[2];
args->left_rear_f = ((float) speaker_amplitude[2]) / 255.0f;
args->right_rear_u8 = speaker_amplitude[3];
args->right_rear_f = ((float) speaker_amplitude[3]) / 255.0f;
args->center_u8 = speaker_amplitude[4];
args->center_f = ((float) speaker_amplitude[4]) / 255.0f;
args->lfe_u8 = speaker_amplitude[5];
args->lfe_f = ((float) speaker_amplitude[5]) / 255.0f;
args->distance_u8 = distance;
args->distance_f = ((float) distance) / 255.0f;
args->room_angle = room_angle;
if (!args->in_use) {
args->in_use = 1;
retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args);
}
 
SDL_UnlockAudio();
return(retval);
}
 
 
/* end of effects_position.c ... */
 
/contrib/games/wolf3d/SDL_mixer/effects_internal.c
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 ... */
 
/contrib/games/wolf3d/SDL_mixer/effects_internal.h
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
 
/contrib/games/wolf3d/SDL_mixer/fluidsynth.h
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_ */
/contrib/games/wolf3d/SDL_mixer/load_aiff.c
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);
}
 
/contrib/games/wolf3d/SDL_mixer/load_aiff.h
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);
/contrib/games/wolf3d/SDL_mixer/load_flac.h
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
/contrib/games/wolf3d/SDL_mixer/load_ogg.h
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
/contrib/games/wolf3d/SDL_mixer/load_voc.c
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 ... */
/contrib/games/wolf3d/SDL_mixer/load_voc.h
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);
/contrib/games/wolf3d/SDL_mixer/mixer.c
0,0 → 1,1488
/*
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$ */
 
#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_aiff.h"
#include "load_voc.h"
#include "load_ogg.h"
#include "load_flac.h"
#include "dynamic_flac.h"
#include "dynamic_mod.h"
#include "dynamic_mp3.h"
#include "dynamic_ogg.h"
 
#define __MIX_INTERNAL_EFFECT__
#include "effects_internal.h"
 
/* Magic numbers for various audio file formats */
#define RIFF 0x46464952 /* "RIFF" */
#define WAVE 0x45564157 /* "WAVE" */
#define FORM 0x4d524f46 /* "FORM" */
#define OGGS 0x5367674f /* "OggS" */
#define CREA 0x61657243 /* "Crea" */
#define FLAC 0x43614C66 /* "fLaC" */
 
static int audio_opened = 0;
static SDL_AudioSpec mixer;
 
typedef struct _Mix_effectinfo
{
Mix_EffectFunc_t callback;
Mix_EffectDone_t done_callback;
void *udata;
struct _Mix_effectinfo *next;
} effect_info;
 
static struct _Mix_Channel {
Mix_Chunk *chunk;
int playing;
int paused;
Uint8 *samples;
int volume;
int looping;
int tag;
Uint32 expire;
Uint32 start_time;
Mix_Fading fading;
int fade_volume;
int fade_volume_reset;
Uint32 fade_length;
Uint32 ticks_fade;
effect_info *effects;
} *mix_channel = NULL;
 
static effect_info *posteffects = NULL;
 
static int num_channels;
static int reserved_channels = 0;
 
 
/* Support for hooking into the mixer callback system */
static void (*mix_postmix)(void *udata, Uint8 *stream, int len) = NULL;
static void *mix_postmix_data = NULL;
 
/* rcg07062001 callback to alert when channels are done playing. */
static void (*channel_done_callback)(int channel) = NULL;
 
/* Music function declarations */
extern int open_music(SDL_AudioSpec *mixer);
extern void close_music(void);
 
/* Support for user defined music functions, plus the default one */
extern int volatile music_active;
extern void music_mixer(void *udata, Uint8 *stream, int len);
static void (*mix_music)(void *udata, Uint8 *stream, int len) = music_mixer;
static void *music_data = NULL;
 
/* rcg06042009 report available decoders at runtime. */
static const char **chunk_decoders = NULL;
static int num_decoders = 0;
 
/* Semicolon-separated SoundFont paths */
#ifdef MID_MUSIC
extern char* soundfont_paths;
#endif
 
int Mix_GetNumChunkDecoders(void)
{
return(num_decoders);
}
 
const char *Mix_GetChunkDecoder(int index)
{
if ((index < 0) || (index >= num_decoders)) {
return NULL;
}
return(chunk_decoders[index]);
}
 
static void add_chunk_decoder(const char *decoder)
{
void *ptr = SDL_realloc(chunk_decoders, (num_decoders + 1) * sizeof (const char **));
if (ptr == NULL) {
return; /* oh well, go on without it. */
}
chunk_decoders = (const char **) ptr;
chunk_decoders[num_decoders++] = decoder;
}
 
/* rcg06192001 get linked library's version. */
const SDL_version *Mix_Linked_Version(void)
{
static SDL_version linked_version;
SDL_MIXER_VERSION(&linked_version);
return(&linked_version);
}
 
static int initialized = 0;
 
int Mix_Init(int flags)
{
int result = 0;
 
if (flags & MIX_INIT_FLUIDSYNTH) {
#ifdef USE_FLUIDSYNTH_MIDI
if ((initialized & MIX_INIT_FLUIDSYNTH) || Mix_InitFluidSynth() == 0) {
result |= MIX_INIT_FLUIDSYNTH;
}
#else
Mix_SetError("Mixer not built with FluidSynth support");
#endif
}
if (flags & MIX_INIT_FLAC) {
#ifdef FLAC_MUSIC
if ((initialized & MIX_INIT_FLAC) || Mix_InitFLAC() == 0) {
result |= MIX_INIT_FLAC;
}
#else
Mix_SetError("Mixer not built with FLAC support");
#endif
}
if (flags & MIX_INIT_MOD) {
#ifdef MOD_MUSIC
if ((initialized & MIX_INIT_MOD) || Mix_InitMOD() == 0) {
result |= MIX_INIT_MOD;
}
#else
Mix_SetError("Mixer not built with MOD support");
#endif
}
if (flags & MIX_INIT_MP3) {
#ifdef MP3_MUSIC
if ((initialized & MIX_INIT_MP3) || Mix_InitMP3() == 0) {
result |= MIX_INIT_MP3;
}
#else
Mix_SetError("Mixer not built with MP3 support");
#endif
}
if (flags & MIX_INIT_OGG) {
#ifdef OGG_MUSIC
if ((initialized & MIX_INIT_OGG) || Mix_InitOgg() == 0) {
result |= MIX_INIT_OGG;
}
#else
Mix_SetError("Mixer not built with Ogg Vorbis support");
#endif
}
initialized |= result;
 
return (result);
}
 
void Mix_Quit()
{
#ifdef USE_FLUIDSYNTH_MIDI
if (initialized & MIX_INIT_FLUIDSYNTH) {
Mix_QuitFluidSynth();
}
#endif
#ifdef FLAC_MUSIC
if (initialized & MIX_INIT_FLAC) {
Mix_QuitFLAC();
}
#endif
#ifdef MOD_MUSIC
if (initialized & MIX_INIT_MOD) {
Mix_QuitMOD();
}
#endif
#ifdef MP3_MUSIC
if (initialized & MIX_INIT_MP3) {
Mix_QuitMP3();
}
#endif
#ifdef OGG_MUSIC
if (initialized & MIX_INIT_OGG) {
Mix_QuitOgg();
}
#endif
#ifdef MID_MUSIC
if (soundfont_paths) {
SDL_free(soundfont_paths);
}
#endif
initialized = 0;
}
 
static int _Mix_remove_all_effects(int channel, effect_info **e);
 
/*
* rcg06122001 Cleanup effect callbacks.
* MAKE SURE SDL_LockAudio() is called before this (or you're in the
* audio callback).
*/
static void _Mix_channel_done_playing(int channel)
{
if (channel_done_callback) {
channel_done_callback(channel);
}
 
/*
* Call internal function directly, to avoid locking audio from
* inside audio callback.
*/
_Mix_remove_all_effects(channel, &mix_channel[channel].effects);
}
 
 
static void *Mix_DoEffects(int chan, void *snd, int len)
{
int posteffect = (chan == MIX_CHANNEL_POST);
effect_info *e = ((posteffect) ? posteffects : mix_channel[chan].effects);
void *buf = snd;
 
if (e != NULL) { /* are there any registered effects? */
/* if this is the postmix, we can just overwrite the original. */
if (!posteffect) {
buf = SDL_malloc(len);
if (buf == NULL) {
return(snd);
}
memcpy(buf, snd, len);
}
 
for (; e != NULL; e = e->next) {
if (e->callback != NULL) {
e->callback(chan, buf, len, e->udata);
}
}
}
 
/* be sure to SDL_free() the return value if != snd ... */
return(buf);
}
 
 
/* Mixing function */
static void mix_channels(void *udata, Uint8 *stream, int len)
{
Uint8 *mix_input;
int i, mixable, volume = SDL_MIX_MAXVOLUME;
Uint32 sdl_ticks;
 
#if SDL_VERSION_ATLEAST(1, 3, 0)
/* Need to initialize the stream in SDL 1.3+ */
memset(stream, mixer.silence, len);
#endif
 
/* Mix the music (must be done before the channels are added) */
if ( music_active || (mix_music != music_mixer) ) {
mix_music(music_data, stream, len);
}
 
/* Mix any playing channels... */
sdl_ticks = SDL_GetTicks();
for ( i=0; i<num_channels; ++i ) {
if( ! mix_channel[i].paused ) {
if ( mix_channel[i].expire > 0 && mix_channel[i].expire < sdl_ticks ) {
/* Expiration delay for that channel is reached */
mix_channel[i].playing = 0;
mix_channel[i].looping = 0;
mix_channel[i].fading = MIX_NO_FADING;
mix_channel[i].expire = 0;
_Mix_channel_done_playing(i);
} else if ( mix_channel[i].fading != MIX_NO_FADING ) {
Uint32 ticks = sdl_ticks - mix_channel[i].ticks_fade;
if( ticks > mix_channel[i].fade_length ) {
Mix_Volume(i, mix_channel[i].fade_volume_reset); /* Restore the volume */
if( mix_channel[i].fading == MIX_FADING_OUT ) {
mix_channel[i].playing = 0;
mix_channel[i].looping = 0;
mix_channel[i].expire = 0;
_Mix_channel_done_playing(i);
}
mix_channel[i].fading = MIX_NO_FADING;
} else {
if( mix_channel[i].fading == MIX_FADING_OUT ) {
Mix_Volume(i, (mix_channel[i].fade_volume * (mix_channel[i].fade_length-ticks))
/ mix_channel[i].fade_length );
} else {
Mix_Volume(i, (mix_channel[i].fade_volume * ticks) / mix_channel[i].fade_length );
}
}
}
if ( mix_channel[i].playing > 0 ) {
int index = 0;
int remaining = len;
while (mix_channel[i].playing > 0 && index < len) {
remaining = len - index;
volume = (mix_channel[i].volume*mix_channel[i].chunk->volume) / MIX_MAX_VOLUME;
mixable = mix_channel[i].playing;
if ( mixable > remaining ) {
mixable = remaining;
}
 
mix_input = Mix_DoEffects(i, mix_channel[i].samples, mixable);
SDL_MixAudio(stream+index,mix_input,mixable,volume);
if (mix_input != mix_channel[i].samples)
SDL_free(mix_input);
 
mix_channel[i].samples += mixable;
mix_channel[i].playing -= mixable;
index += mixable;
 
/* rcg06072001 Alert app if channel is done playing. */
if (!mix_channel[i].playing && !mix_channel[i].looping) {
_Mix_channel_done_playing(i);
}
}
 
/* If looping the sample and we are at its end, make sure
we will still return a full buffer */
while ( mix_channel[i].looping && index < len ) {
int alen = mix_channel[i].chunk->alen;
remaining = len - index;
if (remaining > alen) {
remaining = alen;
}
 
mix_input = Mix_DoEffects(i, mix_channel[i].chunk->abuf, remaining);
SDL_MixAudio(stream+index, mix_input, remaining, volume);
if (mix_input != mix_channel[i].chunk->abuf)
SDL_free(mix_input);
 
--mix_channel[i].looping;
mix_channel[i].samples = mix_channel[i].chunk->abuf + remaining;
mix_channel[i].playing = mix_channel[i].chunk->alen - remaining;
index += remaining;
}
if ( ! mix_channel[i].playing && mix_channel[i].looping ) {
--mix_channel[i].looping;
mix_channel[i].samples = mix_channel[i].chunk->abuf;
mix_channel[i].playing = mix_channel[i].chunk->alen;
}
}
}
}
 
/* rcg06122001 run posteffects... */
Mix_DoEffects(MIX_CHANNEL_POST, stream, len);
 
if ( mix_postmix ) {
mix_postmix(mix_postmix_data, stream, len);
}
}
 
#if 0
static void PrintFormat(char *title, SDL_AudioSpec *fmt)
{
printf("%s: %d bit %s audio (%s) at %u Hz\n", title, (fmt->format&0xFF),
(fmt->format&0x8000) ? "signed" : "unsigned",
(fmt->channels > 2) ? "surround" :
(fmt->channels > 1) ? "stereo" : "mono", fmt->freq);
}
#endif
 
 
/* Open the mixer with a certain desired audio format */
int Mix_OpenAudio(int frequency, Uint16 format, int nchannels, int chunksize)
{
int i;
SDL_AudioSpec desired;
 
/* If the mixer is already opened, increment open count */
if ( audio_opened ) {
if ( format == mixer.format && nchannels == mixer.channels ) {
++audio_opened;
return(0);
}
while ( audio_opened ) {
Mix_CloseAudio();
}
}
 
/* Set the desired format and frequency */
desired.freq = frequency;
desired.format = format;
desired.channels = nchannels;
desired.samples = chunksize;
desired.callback = mix_channels;
desired.userdata = NULL;
 
/* Accept nearly any audio format */
if ( SDL_OpenAudio(&desired, &mixer) < 0 ) {
return(-1);
}
#if 0
PrintFormat("Audio device", &mixer);
#endif
 
/* Initialize the music players */
if ( open_music(&mixer) < 0 ) {
SDL_CloseAudio();
return(-1);
}
 
num_channels = MIX_CHANNELS;
mix_channel = (struct _Mix_Channel *) SDL_malloc(num_channels * sizeof(struct _Mix_Channel));
 
/* Clear out the audio channels */
for ( i=0; i<num_channels; ++i ) {
mix_channel[i].chunk = NULL;
mix_channel[i].playing = 0;
mix_channel[i].looping = 0;
mix_channel[i].volume = SDL_MIX_MAXVOLUME;
mix_channel[i].fade_volume = SDL_MIX_MAXVOLUME;
mix_channel[i].fade_volume_reset = SDL_MIX_MAXVOLUME;
mix_channel[i].fading = MIX_NO_FADING;
mix_channel[i].tag = -1;
mix_channel[i].expire = 0;
mix_channel[i].effects = NULL;
mix_channel[i].paused = 0;
}
Mix_VolumeMusic(SDL_MIX_MAXVOLUME);
 
_Mix_InitEffects();
 
/* This list is (currently) decided at build time. */
add_chunk_decoder("WAVE");
add_chunk_decoder("AIFF");
add_chunk_decoder("VOC");
#ifdef OGG_MUSIC
add_chunk_decoder("OGG");
#endif
#ifdef FLAC_MUSIC
add_chunk_decoder("FLAC");
#endif
 
audio_opened = 1;
SDL_PauseAudio(0);
return(0);
}
 
/* Dynamically change the number of channels managed by the mixer.
If decreasing the number of channels, the upper channels are
stopped.
*/
int Mix_AllocateChannels(int numchans)
{
if ( numchans<0 || numchans==num_channels )
return(num_channels);
 
if ( numchans < num_channels ) {
/* Stop the affected channels */
int i;
for(i=numchans; i < num_channels; i++) {
Mix_UnregisterAllEffects(i);
Mix_HaltChannel(i);
}
}
SDL_LockAudio();
mix_channel = (struct _Mix_Channel *) SDL_realloc(mix_channel, numchans * sizeof(struct _Mix_Channel));
if ( numchans > num_channels ) {
/* Initialize the new channels */
int i;
for(i=num_channels; i < numchans; i++) {
mix_channel[i].chunk = NULL;
mix_channel[i].playing = 0;
mix_channel[i].looping = 0;
mix_channel[i].volume = SDL_MIX_MAXVOLUME;
mix_channel[i].fade_volume = SDL_MIX_MAXVOLUME;
mix_channel[i].fade_volume_reset = SDL_MIX_MAXVOLUME;
mix_channel[i].fading = MIX_NO_FADING;
mix_channel[i].tag = -1;
mix_channel[i].expire = 0;
mix_channel[i].effects = NULL;
mix_channel[i].paused = 0;
}
}
num_channels = numchans;
SDL_UnlockAudio();
return(num_channels);
}
 
/* Return the actual mixer parameters */
int Mix_QuerySpec(int *frequency, Uint16 *format, int *channels)
{
if ( audio_opened ) {
if ( frequency ) {
*frequency = mixer.freq;
}
if ( format ) {
*format = mixer.format;
}
if ( channels ) {
*channels = mixer.channels;
}
}
return(audio_opened);
}
 
 
/*
* !!! FIXME: Ideally, we want a Mix_LoadSample_RW(), which will handle the
* generic setup, then call the correct file format loader.
*/
 
/* Load a wave file */
Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
{
Uint32 magic;
Mix_Chunk *chunk;
SDL_AudioSpec wavespec, *loaded;
SDL_AudioCVT wavecvt;
int samplesize;
 
/* rcg06012001 Make sure src is valid */
if ( ! src ) {
SDL_SetError("Mix_LoadWAV_RW with NULL src");
return(NULL);
}
 
/* Make sure audio has been opened */
if ( ! audio_opened ) {
SDL_SetError("Audio device hasn't been opened");
if ( freesrc && src ) {
SDL_RWclose(src);
}
return(NULL);
}
 
/* Allocate the chunk memory */
chunk = (Mix_Chunk *)SDL_malloc(sizeof(Mix_Chunk));
if ( chunk == NULL ) {
SDL_SetError("Out of memory");
if ( freesrc ) {
SDL_RWclose(src);
}
return(NULL);
}
 
/* Find out what kind of audio file this is */
magic = SDL_ReadLE32(src);
/* Seek backwards for compatibility with older loaders */
SDL_RWseek(src, -(int)sizeof(Uint32), SEEK_CUR);
 
switch (magic) {
case WAVE:
case RIFF:
loaded = SDL_LoadWAV_RW(src, freesrc, &wavespec,
(Uint8 **)&chunk->abuf, &chunk->alen);
break;
case FORM:
loaded = Mix_LoadAIFF_RW(src, freesrc, &wavespec,
(Uint8 **)&chunk->abuf, &chunk->alen);
break;
#ifdef OGG_MUSIC
case OGGS:
loaded = Mix_LoadOGG_RW(src, freesrc, &wavespec,
(Uint8 **)&chunk->abuf, &chunk->alen);
break;
#endif
#ifdef FLAC_MUSIC
case FLAC:
loaded = Mix_LoadFLAC_RW(src, freesrc, &wavespec,
(Uint8 **)&chunk->abuf, &chunk->alen);
break;
#endif
case CREA:
loaded = Mix_LoadVOC_RW(src, freesrc, &wavespec,
(Uint8 **)&chunk->abuf, &chunk->alen);
break;
default:
SDL_SetError("Unrecognized sound file type");
return(0);
}
if ( !loaded ) {
SDL_free(chunk);
if ( freesrc ) {
SDL_RWclose(src);
}
return(NULL);
}
 
#if 0
PrintFormat("Audio device", &mixer);
PrintFormat("-- Wave file", &wavespec);
#endif
 
/* Build the audio converter and create conversion buffers */
if ( wavespec.format != mixer.format ||
wavespec.channels != mixer.channels ||
wavespec.freq != mixer.freq ) {
if ( SDL_BuildAudioCVT(&wavecvt,
wavespec.format, wavespec.channels, wavespec.freq,
mixer.format, mixer.channels, mixer.freq) < 0 ) {
SDL_free(chunk->abuf);
SDL_free(chunk);
return(NULL);
}
samplesize = ((wavespec.format & 0xFF)/8)*wavespec.channels;
wavecvt.len = chunk->alen & ~(samplesize-1);
wavecvt.buf = (Uint8 *)SDL_calloc(1, wavecvt.len*wavecvt.len_mult);
if ( wavecvt.buf == NULL ) {
SDL_SetError("Out of memory");
SDL_free(chunk->abuf);
SDL_free(chunk);
return(NULL);
}
memcpy(wavecvt.buf, chunk->abuf, chunk->alen);
SDL_free(chunk->abuf);
 
/* Run the audio converter */
if ( SDL_ConvertAudio(&wavecvt) < 0 ) {
SDL_free(wavecvt.buf);
SDL_free(chunk);
return(NULL);
}
 
chunk->abuf = wavecvt.buf;
chunk->alen = wavecvt.len_cvt;
}
 
chunk->allocated = 1;
chunk->volume = MIX_MAX_VOLUME;
 
return(chunk);
}
 
/* Load a wave file of the mixer format from a memory buffer */
Mix_Chunk *Mix_QuickLoad_WAV(Uint8 *mem)
{
Mix_Chunk *chunk;
Uint8 magic[4];
 
/* Make sure audio has been opened */
if ( ! audio_opened ) {
SDL_SetError("Audio device hasn't been opened");
return(NULL);
}
 
/* Allocate the chunk memory */
chunk = (Mix_Chunk *)SDL_calloc(1,sizeof(Mix_Chunk));
if ( chunk == NULL ) {
SDL_SetError("Out of memory");
return(NULL);
}
 
/* Essentially just skip to the audio data (no error checking - fast) */
chunk->allocated = 0;
mem += 12; /* WAV header */
do {
memcpy(magic, mem, 4);
mem += 4;
chunk->alen = ((mem[3]<<24)|(mem[2]<<16)|(mem[1]<<8)|(mem[0]));
mem += 4;
chunk->abuf = mem;
mem += chunk->alen;
} while ( memcmp(magic, "data", 4) != 0 );
chunk->volume = MIX_MAX_VOLUME;
 
return(chunk);
}
 
/* Load raw audio data of the mixer format from a memory buffer */
Mix_Chunk *Mix_QuickLoad_RAW(Uint8 *mem, Uint32 len)
{
Mix_Chunk *chunk;
 
/* Make sure audio has been opened */
if ( ! audio_opened ) {
SDL_SetError("Audio device hasn't been opened");
return(NULL);
}
 
/* Allocate the chunk memory */
chunk = (Mix_Chunk *)SDL_malloc(sizeof(Mix_Chunk));
if ( chunk == NULL ) {
SDL_SetError("Out of memory");
return(NULL);
}
 
/* Essentially just point at the audio data (no error checking - fast) */
chunk->allocated = 0;
chunk->alen = len;
chunk->abuf = mem;
chunk->volume = MIX_MAX_VOLUME;
 
return(chunk);
}
 
/* Free an audio chunk previously loaded */
void Mix_FreeChunk(Mix_Chunk *chunk)
{
int i;
 
/* Caution -- if the chunk is playing, the mixer will crash */
if ( chunk ) {
/* Guarantee that this chunk isn't playing */
SDL_LockAudio();
if ( mix_channel ) {
for ( i=0; i<num_channels; ++i ) {
if ( chunk == mix_channel[i].chunk ) {
mix_channel[i].playing = 0;
mix_channel[i].looping = 0;
}
}
}
SDL_UnlockAudio();
/* Actually free the chunk */
if ( chunk->allocated ) {
SDL_free(chunk->abuf);
}
SDL_free(chunk);
}
}
 
/* 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.
*/
void Mix_SetPostMix(void (*mix_func)
(void *udata, Uint8 *stream, int len), void *arg)
{
SDL_LockAudio();
mix_postmix_data = arg;
mix_postmix = mix_func;
SDL_UnlockAudio();
}
 
/* Add your own music player or mixer function.
If 'mix_func' is NULL, the default music player is re-enabled.
*/
void Mix_HookMusic(void (*mix_func)(void *udata, Uint8 *stream, int len),
void *arg)
{
SDL_LockAudio();
if ( mix_func != NULL ) {
music_data = arg;
mix_music = mix_func;
} else {
music_data = NULL;
mix_music = music_mixer;
}
SDL_UnlockAudio();
}
 
void *Mix_GetMusicHookData(void)
{
return(music_data);
}
 
void Mix_ChannelFinished(void (*channel_finished)(int channel))
{
SDL_LockAudio();
channel_done_callback = channel_finished;
SDL_UnlockAudio();
}
 
 
/* 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.
*/
int Mix_ReserveChannels(int num)
{
if (num > num_channels)
num = num_channels;
reserved_channels = num;
return num;
}
 
static int checkchunkintegral(Mix_Chunk *chunk)
{
int frame_width = 1;
 
if ((mixer.format & 0xFF) == 16) frame_width = 2;
frame_width *= mixer.channels;
while (chunk->alen % frame_width) chunk->alen--;
return chunk->alen;
}
 
/* Play an audio chunk on a specific channel.
If the specified channel is -1, play on the first free channel.
'ticks' is the number of milliseconds at most to play the sample, or -1
if there is no limit.
Returns which channel was used to play the sound.
*/
int Mix_PlayChannelTimed(int which, Mix_Chunk *chunk, int loops, int ticks)
{
int i;
 
/* Don't play null pointers :-) */
if ( chunk == NULL ) {
Mix_SetError("Tried to play a NULL chunk");
return(-1);
}
if ( !checkchunkintegral(chunk)) {
Mix_SetError("Tried to play a chunk with a bad frame");
return(-1);
}
 
/* Lock the mixer while modifying the playing channels */
SDL_LockAudio();
{
/* If which is -1, play on the first free channel */
if ( which == -1 ) {
for ( i=reserved_channels; i<num_channels; ++i ) {
if ( mix_channel[i].playing <= 0 )
break;
}
if ( i == num_channels ) {
Mix_SetError("No free channels available");
which = -1;
} else {
which = i;
}
}
 
/* Queue up the audio data for this channel */
if ( which >= 0 && which < num_channels ) {
Uint32 sdl_ticks = SDL_GetTicks();
if (Mix_Playing(which))
_Mix_channel_done_playing(which);
mix_channel[which].samples = chunk->abuf;
mix_channel[which].playing = chunk->alen;
mix_channel[which].looping = loops;
mix_channel[which].chunk = chunk;
mix_channel[which].paused = 0;
mix_channel[which].fading = MIX_NO_FADING;
mix_channel[which].start_time = sdl_ticks;
mix_channel[which].expire = (ticks>0) ? (sdl_ticks + ticks) : 0;
}
}
SDL_UnlockAudio();
 
/* Return the channel on which the sound is being played */
return(which);
}
 
/* Change the expiration delay for a channel */
int Mix_ExpireChannel(int which, int ticks)
{
int status = 0;
 
if ( which == -1 ) {
int i;
for ( i=0; i < num_channels; ++ i ) {
status += Mix_ExpireChannel(i, ticks);
}
} else if ( which < num_channels ) {
SDL_LockAudio();
mix_channel[which].expire = (ticks>0) ? (SDL_GetTicks() + ticks) : 0;
SDL_UnlockAudio();
++ status;
}
return(status);
}
 
/* Fade in a sound on a channel, over ms milliseconds */
int Mix_FadeInChannelTimed(int which, Mix_Chunk *chunk, int loops, int ms, int ticks)
{
int i;
 
/* Don't play null pointers :-) */
if ( chunk == NULL ) {
return(-1);
}
if ( !checkchunkintegral(chunk)) {
Mix_SetError("Tried to play a chunk with a bad frame");
return(-1);
}
 
/* Lock the mixer while modifying the playing channels */
SDL_LockAudio();
{
/* If which is -1, play on the first free channel */
if ( which == -1 ) {
for ( i=reserved_channels; i<num_channels; ++i ) {
if ( mix_channel[i].playing <= 0 )
break;
}
if ( i == num_channels ) {
which = -1;
} else {
which = i;
}
}
 
/* Queue up the audio data for this channel */
if ( which >= 0 && which < num_channels ) {
Uint32 sdl_ticks = SDL_GetTicks();
if (Mix_Playing(which))
_Mix_channel_done_playing(which);
mix_channel[which].samples = chunk->abuf;
mix_channel[which].playing = chunk->alen;
mix_channel[which].looping = loops;
mix_channel[which].chunk = chunk;
mix_channel[which].paused = 0;
mix_channel[which].fading = MIX_FADING_IN;
mix_channel[which].fade_volume = mix_channel[which].volume;
mix_channel[which].fade_volume_reset = mix_channel[which].volume;
mix_channel[which].volume = 0;
mix_channel[which].fade_length = (Uint32)ms;
mix_channel[which].start_time = mix_channel[which].ticks_fade = sdl_ticks;
mix_channel[which].expire = (ticks > 0) ? (sdl_ticks+ticks) : 0;
}
}
SDL_UnlockAudio();
 
/* Return the channel on which the sound is being played */
return(which);
}
 
/* Set volume of a particular channel */
int Mix_Volume(int which, int volume)
{
int i;
int prev_volume = 0;
 
if ( which == -1 ) {
for ( i=0; i<num_channels; ++i ) {
prev_volume += Mix_Volume(i, volume);
}
prev_volume /= num_channels;
} else if ( which < num_channels ) {
prev_volume = mix_channel[which].volume;
if ( volume >= 0 ) {
if ( volume > SDL_MIX_MAXVOLUME ) {
volume = SDL_MIX_MAXVOLUME;
}
mix_channel[which].volume = volume;
}
}
return(prev_volume);
}
/* Set volume of a particular chunk */
int Mix_VolumeChunk(Mix_Chunk *chunk, int volume)
{
int prev_volume;
 
prev_volume = chunk->volume;
if ( volume >= 0 ) {
if ( volume > MIX_MAX_VOLUME ) {
volume = MIX_MAX_VOLUME;
}
chunk->volume = volume;
}
return(prev_volume);
}
 
/* Halt playing of a particular channel */
int Mix_HaltChannel(int which)
{
int i;
 
if ( which == -1 ) {
for ( i=0; i<num_channels; ++i ) {
Mix_HaltChannel(i);
}
} else if ( which < num_channels ) {
SDL_LockAudio();
if (mix_channel[which].playing) {
_Mix_channel_done_playing(which);
mix_channel[which].playing = 0;
mix_channel[which].looping = 0;
}
mix_channel[which].expire = 0;
if(mix_channel[which].fading != MIX_NO_FADING) /* Restore volume */
mix_channel[which].volume = mix_channel[which].fade_volume_reset;
mix_channel[which].fading = MIX_NO_FADING;
SDL_UnlockAudio();
}
return(0);
}
 
/* Halt playing of a particular group of channels */
int Mix_HaltGroup(int tag)
{
int i;
 
for ( i=0; i<num_channels; ++i ) {
if( mix_channel[i].tag == tag ) {
Mix_HaltChannel(i);
}
}
return(0);
}
 
/* Fade out a channel and then stop it automatically */
int Mix_FadeOutChannel(int which, int ms)
{
int status;
 
status = 0;
if ( audio_opened ) {
if ( which == -1 ) {
int i;
 
for ( i=0; i<num_channels; ++i ) {
status += Mix_FadeOutChannel(i, ms);
}
} else if ( which < num_channels ) {
SDL_LockAudio();
if ( mix_channel[which].playing &&
(mix_channel[which].volume > 0) &&
(mix_channel[which].fading != MIX_FADING_OUT) ) {
mix_channel[which].fade_volume = mix_channel[which].volume;
mix_channel[which].fading = MIX_FADING_OUT;
mix_channel[which].fade_length = ms;
mix_channel[which].ticks_fade = SDL_GetTicks();
 
/* only change fade_volume_reset if we're not fading. */
if (mix_channel[which].fading == MIX_NO_FADING) {
mix_channel[which].fade_volume_reset = mix_channel[which].volume;
}
++status;
}
SDL_UnlockAudio();
}
}
return(status);
}
 
/* Halt playing of a particular group of channels */
int Mix_FadeOutGroup(int tag, int ms)
{
int i;
int status = 0;
for ( i=0; i<num_channels; ++i ) {
if( mix_channel[i].tag == tag ) {
status += Mix_FadeOutChannel(i,ms);
}
}
return(status);
}
 
Mix_Fading Mix_FadingChannel(int which)
{
if ( which < 0 || which >= num_channels ) {
return MIX_NO_FADING;
}
return mix_channel[which].fading;
}
 
/* Check the status of a specific channel.
If the specified mix_channel is -1, check all mix channels.
*/
int Mix_Playing(int which)
{
int status;
 
status = 0;
if ( which == -1 ) {
int i;
 
for ( i=0; i<num_channels; ++i ) {
if ((mix_channel[i].playing > 0) ||
(mix_channel[i].looping > 0))
{
++status;
}
}
} else if ( which < num_channels ) {
if ( (mix_channel[which].playing > 0) ||
(mix_channel[which].looping > 0) )
{
++status;
}
}
return(status);
}
 
/* rcg06072001 Get the chunk associated with a channel. */
Mix_Chunk *Mix_GetChunk(int channel)
{
Mix_Chunk *retval = NULL;
 
if ((channel >= 0) && (channel < num_channels)) {
retval = mix_channel[channel].chunk;
}
 
return(retval);
}
 
/* Close the mixer, halting all playing audio */
void Mix_CloseAudio(void)
{
int i;
 
if ( audio_opened ) {
if ( audio_opened == 1 ) {
for (i = 0; i < num_channels; i++) {
Mix_UnregisterAllEffects(i);
}
Mix_UnregisterAllEffects(MIX_CHANNEL_POST);
close_music();
Mix_HaltChannel(-1);
_Mix_DeinitEffects();
SDL_CloseAudio();
SDL_free(mix_channel);
mix_channel = NULL;
 
/* rcg06042009 report available decoders at runtime. */
SDL_free(chunk_decoders);
chunk_decoders = NULL;
num_decoders = 0;
}
--audio_opened;
}
}
 
/* Pause a particular channel (or all) */
void Mix_Pause(int which)
{
Uint32 sdl_ticks = SDL_GetTicks();
if ( which == -1 ) {
int i;
 
for ( i=0; i<num_channels; ++i ) {
if ( mix_channel[i].playing > 0 ) {
mix_channel[i].paused = sdl_ticks;
}
}
} else if ( which < num_channels ) {
if ( mix_channel[which].playing > 0 ) {
mix_channel[which].paused = sdl_ticks;
}
}
}
 
/* Resume a paused channel */
void Mix_Resume(int which)
{
Uint32 sdl_ticks = SDL_GetTicks();
 
SDL_LockAudio();
if ( which == -1 ) {
int i;
 
for ( i=0; i<num_channels; ++i ) {
if ( mix_channel[i].playing > 0 ) {
if(mix_channel[i].expire > 0)
mix_channel[i].expire += sdl_ticks - mix_channel[i].paused;
mix_channel[i].paused = 0;
}
}
} else if ( which < num_channels ) {
if ( mix_channel[which].playing > 0 ) {
if(mix_channel[which].expire > 0)
mix_channel[which].expire += sdl_ticks - mix_channel[which].paused;
mix_channel[which].paused = 0;
}
}
SDL_UnlockAudio();
}
 
int Mix_Paused(int which)
{
if ( which < 0 ) {
int status = 0;
int i;
for( i=0; i < num_channels; ++i ) {
if ( mix_channel[i].paused ) {
++ status;
}
}
return(status);
} else if ( which < num_channels ) {
return(mix_channel[which].paused != 0);
} else {
return(0);
}
}
 
/* Change the group of a channel */
int Mix_GroupChannel(int which, int tag)
{
if ( which < 0 || which > num_channels )
return(0);
 
SDL_LockAudio();
mix_channel[which].tag = tag;
SDL_UnlockAudio();
return(1);
}
 
/* Assign several consecutive channels to a group */
int Mix_GroupChannels(int from, int to, int tag)
{
int status = 0;
for( ; from <= to; ++ from ) {
status += Mix_GroupChannel(from, tag);
}
return(status);
}
 
/* Finds the first available channel in a group of channels */
int Mix_GroupAvailable(int tag)
{
int i;
for( i=0; i < num_channels; i ++ ) {
if ( ((tag == -1) || (tag == mix_channel[i].tag)) &&
(mix_channel[i].playing <= 0) )
return i;
}
return(-1);
}
 
int Mix_GroupCount(int tag)
{
int count = 0;
int i;
for( i=0; i < num_channels; i ++ ) {
if ( mix_channel[i].tag==tag || tag==-1 )
++ count;
}
return(count);
}
 
/* Finds the "oldest" sample playing in a group of channels */
int Mix_GroupOldest(int tag)
{
int chan = -1;
Uint32 mintime = SDL_GetTicks();
int i;
for( i=0; i < num_channels; i ++ ) {
if ( (mix_channel[i].tag==tag || tag==-1) && mix_channel[i].playing > 0
&& mix_channel[i].start_time <= mintime ) {
mintime = mix_channel[i].start_time;
chan = i;
}
}
return(chan);
}
 
/* Finds the "most recent" (i.e. last) sample playing in a group of channels */
int Mix_GroupNewer(int tag)
{
int chan = -1;
Uint32 maxtime = 0;
int i;
for( i=0; i < num_channels; i ++ ) {
if ( (mix_channel[i].tag==tag || tag==-1) && mix_channel[i].playing > 0
&& mix_channel[i].start_time >= maxtime ) {
maxtime = mix_channel[i].start_time;
chan = i;
}
}
return(chan);
}
 
 
 
/*
* rcg06122001 The special effects exportable API.
* Please see effect_*.c for internally-implemented effects, such
* as Mix_SetPanning().
*/
 
/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */
static int _Mix_register_effect(effect_info **e, Mix_EffectFunc_t f,
Mix_EffectDone_t d, void *arg)
{
effect_info *new_e;
 
if (!e) {
Mix_SetError("Internal error");
return(0);
}
 
if (f == NULL) {
Mix_SetError("NULL effect callback");
return(0);
}
 
new_e = SDL_malloc(sizeof (effect_info));
if (new_e == NULL) {
Mix_SetError("Out of memory");
return(0);
}
 
new_e->callback = f;
new_e->done_callback = d;
new_e->udata = arg;
new_e->next = NULL;
 
/* add new effect to end of linked list... */
if (*e == NULL) {
*e = new_e;
} else {
effect_info *cur = *e;
while (1) {
if (cur->next == NULL) {
cur->next = new_e;
break;
}
cur = cur->next;
}
}
 
return(1);
}
 
 
/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */
static int _Mix_remove_effect(int channel, effect_info **e, Mix_EffectFunc_t f)
{
effect_info *cur;
effect_info *prev = NULL;
effect_info *next = NULL;
 
if (!e) {
Mix_SetError("Internal error");
return(0);
}
 
for (cur = *e; cur != NULL; cur = cur->next) {
if (cur->callback == f) {
next = cur->next;
if (cur->done_callback != NULL) {
cur->done_callback(channel, cur->udata);
}
SDL_free(cur);
 
if (prev == NULL) { /* removing first item of list? */
*e = next;
} else {
prev->next = next;
}
return(1);
}
prev = cur;
}
 
Mix_SetError("No such effect registered");
return(0);
}
 
 
/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */
static int _Mix_remove_all_effects(int channel, effect_info **e)
{
effect_info *cur;
effect_info *next;
 
if (!e) {
Mix_SetError("Internal error");
return(0);
}
 
for (cur = *e; cur != NULL; cur = next) {
next = cur->next;
if (cur->done_callback != NULL) {
cur->done_callback(channel, cur->udata);
}
SDL_free(cur);
}
*e = NULL;
 
return(1);
}
 
 
/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */
int _Mix_RegisterEffect_locked(int channel, Mix_EffectFunc_t f,
Mix_EffectDone_t d, void *arg)
{
effect_info **e = NULL;
 
if (channel == MIX_CHANNEL_POST) {
e = &posteffects;
} else {
if ((channel < 0) || (channel >= num_channels)) {
Mix_SetError("Invalid channel number");
return(0);
}
e = &mix_channel[channel].effects;
}
 
return _Mix_register_effect(e, f, d, arg);
}
 
int Mix_RegisterEffect(int channel, Mix_EffectFunc_t f,
Mix_EffectDone_t d, void *arg)
{
int retval;
SDL_LockAudio();
retval = _Mix_RegisterEffect_locked(channel, f, d, arg);
SDL_UnlockAudio();
return retval;
}
 
 
/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */
int _Mix_UnregisterEffect_locked(int channel, Mix_EffectFunc_t f)
{
effect_info **e = NULL;
 
if (channel == MIX_CHANNEL_POST) {
e = &posteffects;
} else {
if ((channel < 0) || (channel >= num_channels)) {
Mix_SetError("Invalid channel number");
return(0);
}
e = &mix_channel[channel].effects;
}
 
return _Mix_remove_effect(channel, e, f);
}
 
int Mix_UnregisterEffect(int channel, Mix_EffectFunc_t f)
{
int retval;
SDL_LockAudio();
retval = _Mix_UnregisterEffect_locked(channel, f);
SDL_UnlockAudio();
return(retval);
}
 
/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */
int _Mix_UnregisterAllEffects_locked(int channel)
{
effect_info **e = NULL;
 
if (channel == MIX_CHANNEL_POST) {
e = &posteffects;
} else {
if ((channel < 0) || (channel >= num_channels)) {
Mix_SetError("Invalid channel number");
return(0);
}
e = &mix_channel[channel].effects;
}
 
return _Mix_remove_all_effects(channel, e);
}
 
int Mix_UnregisterAllEffects(int channel)
{
int retval;
SDL_LockAudio();
retval = _Mix_UnregisterAllEffects_locked(channel);
SDL_UnlockAudio();
return(retval);
}
 
/* end of mixer.c ... */
 
/contrib/games/wolf3d/SDL_mixer/music.c
0,0 → 1,1597
/*
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$ */
 
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "SDL_endian.h"
#include "SDL_audio.h"
#include "SDL_timer.h"
 
#include "SDL_mixer.h"
 
#ifdef CMD_MUSIC
#include "music_cmd.h"
#endif
#ifdef WAV_MUSIC
#include "wavestream.h"
#endif
#ifdef MODPLUG_MUSIC
#include "music_modplug.h"
#endif
#ifdef MOD_MUSIC
#include "music_mod.h"
#endif
#ifdef MID_MUSIC
# ifdef USE_TIMIDITY_MIDI
# include "timidity.h"
# endif
# ifdef USE_FLUIDSYNTH_MIDI
# include "fluidsynth.h"
# endif
# ifdef USE_NATIVE_MIDI
# include "native_midi.h"
# endif
#endif
#ifdef OGG_MUSIC
#include "music_ogg.h"
#endif
#ifdef MP3_MUSIC
#include "dynamic_mp3.h"
#endif
#ifdef MP3_MAD_MUSIC
#include "music_mad.h"
#endif
#ifdef FLAC_MUSIC
#include "music_flac.h"
#endif
 
#if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
static SDL_AudioSpec used_mixer;
#endif
 
 
int volatile music_active = 1;
static int volatile music_stopped = 0;
static int music_loops = 0;
static char *music_cmd = NULL;
static Mix_Music * volatile music_playing = NULL;
static int music_volume = MIX_MAX_VOLUME;
 
struct _Mix_Music {
Mix_MusicType type;
union {
#ifdef CMD_MUSIC
MusicCMD *cmd;
#endif
#ifdef WAV_MUSIC
WAVStream *wave;
#endif
#ifdef MODPLUG_MUSIC
modplug_data *modplug;
#endif
#ifdef MOD_MUSIC
struct MODULE *module;
#endif
#ifdef MID_MUSIC
#ifdef USE_TIMIDITY_MIDI
MidiSong *midi;
#endif
#ifdef USE_FLUIDSYNTH_MIDI
FluidSynthMidiSong *fluidsynthmidi;
#endif
#ifdef USE_NATIVE_MIDI
NativeMidiSong *nativemidi;
#endif
#endif
#ifdef OGG_MUSIC
OGG_music *ogg;
#endif
#ifdef MP3_MUSIC
SMPEG *mp3;
#endif
#ifdef MP3_MAD_MUSIC
mad_data *mp3_mad;
#endif
#ifdef FLAC_MUSIC
FLAC_music *flac;
#endif
} data;
Mix_Fading fading;
int fade_step;
int fade_steps;
int error;
};
#ifdef MID_MUSIC
#ifdef USE_TIMIDITY_MIDI
static int timidity_ok;
static int samplesize;
#endif
#ifdef USE_FLUIDSYNTH_MIDI
static int fluidsynth_ok;
#endif
#ifdef USE_NATIVE_MIDI
static int native_midi_ok;
#endif
#endif
 
/* Used to calculate fading steps */
static int ms_per_step;
 
/* rcg06042009 report available decoders at runtime. */
static const char **music_decoders = NULL;
static int num_decoders = 0;
 
/* Semicolon-separated SoundFont paths */
#ifdef MID_MUSIC
char* soundfont_paths = NULL;
#endif
 
int Mix_GetNumMusicDecoders(void)
{
return(num_decoders);
}
 
const char *Mix_GetMusicDecoder(int index)
{
if ((index < 0) || (index >= num_decoders)) {
return NULL;
}
return(music_decoders[index]);
}
 
static void add_music_decoder(const char *decoder)
{
void *ptr = SDL_realloc(music_decoders, (num_decoders + 1) * sizeof (const char **));
if (ptr == NULL) {
return; /* oh well, go on without it. */
}
music_decoders = (const char **) ptr;
music_decoders[num_decoders++] = decoder;
}
 
/* Local low-level functions prototypes */
static void music_internal_initialize_volume(void);
static void music_internal_volume(int volume);
static int music_internal_play(Mix_Music *music, double position);
static int music_internal_position(double position);
static int music_internal_playing();
static void music_internal_halt(void);
 
 
/* Support for hooking when the music has finished */
static void (*music_finished_hook)(void) = NULL;
 
void Mix_HookMusicFinished(void (*music_finished)(void))
{
SDL_LockAudio();
music_finished_hook = music_finished;
SDL_UnlockAudio();
}
 
 
/* If music isn't playing, halt it if no looping is required, restart it */
/* otherwhise. NOP if the music is playing */
static int music_halt_or_loop (void)
{
/* Restart music if it has to loop */
if (!music_internal_playing())
{
#ifdef USE_NATIVE_MIDI
/* Native MIDI handles looping internally */
if (music_playing->type == MUS_MID && native_midi_ok) {
music_loops = 0;
}
#endif
 
/* Restart music if it has to loop at a high level */
if (music_loops)
{
Mix_Fading current_fade;
--music_loops;
current_fade = music_playing->fading;
music_internal_play(music_playing, 0.0);
music_playing->fading = current_fade;
}
else
{
music_internal_halt();
if (music_finished_hook)
music_finished_hook();
return 0;
}
}
return 1;
}
 
 
 
/* Mixing function */
void music_mixer(void *udata, Uint8 *stream, int len)
{
int left = 0;
 
if ( music_playing && music_active ) {
/* Handle fading */
if ( music_playing->fading != MIX_NO_FADING ) {
if ( music_playing->fade_step++ < music_playing->fade_steps ) {
int volume;
int fade_step = music_playing->fade_step;
int fade_steps = music_playing->fade_steps;
 
if ( music_playing->fading == MIX_FADING_OUT ) {
volume = (music_volume * (fade_steps-fade_step)) / fade_steps;
} else { /* Fading in */
volume = (music_volume * fade_step) / fade_steps;
}
music_internal_volume(volume);
} else {
if ( music_playing->fading == MIX_FADING_OUT ) {
music_internal_halt();
if ( music_finished_hook ) {
music_finished_hook();
}
return;
}
music_playing->fading = MIX_NO_FADING;
}
}
music_halt_or_loop();
if (!music_internal_playing())
return;
 
switch (music_playing->type) {
#ifdef CMD_MUSIC
case MUS_CMD:
/* The playing is done externally */
break;
#endif
#ifdef WAV_MUSIC
case MUS_WAV:
left = WAVStream_PlaySome(stream, len);
break;
#endif
#ifdef MODPLUG_MUSIC
case MUS_MODPLUG:
left = modplug_playAudio(music_playing->data.modplug, stream, len);
break;
#endif
#ifdef MOD_MUSIC
case MUS_MOD:
left = MOD_playAudio(music_playing->data.module, stream, len);
break;
#endif
#ifdef MID_MUSIC
case MUS_MID:
#ifdef USE_NATIVE_MIDI
if ( native_midi_ok ) {
/* Native midi is handled asynchronously */
goto skip;
}
#endif
#ifdef USE_FLUIDSYNTH_MIDI
if ( fluidsynth_ok ) {
fluidsynth_playsome(music_playing->data.fluidsynthmidi, stream, len);
goto skip;
}
#endif
#ifdef USE_TIMIDITY_MIDI
if ( timidity_ok ) {
int samples = len / samplesize;
Timidity_PlaySome(stream, samples);
goto skip;
}
#endif
break;
#endif
#ifdef OGG_MUSIC
case MUS_OGG:
left = OGG_playAudio(music_playing->data.ogg, stream, len);
break;
#endif
#ifdef FLAC_MUSIC
case MUS_FLAC:
left = FLAC_playAudio(music_playing->data.flac, stream, len);
break;
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
left = (len - smpeg.SMPEG_playAudio(music_playing->data.mp3, stream, len));
break;
#endif
#ifdef MP3_MAD_MUSIC
case MUS_MP3_MAD:
left = mad_getSamples(music_playing->data.mp3_mad, stream, len);
break;
#endif
default:
/* Unknown music type?? */
break;
}
}
 
skip:
/* Handle seamless music looping */
if (left > 0 && left < len) {
music_halt_or_loop();
if (music_internal_playing())
music_mixer(udata, stream+(len-left), left);
}
}
 
/* Initialize the music players with a certain desired audio format */
int open_music(SDL_AudioSpec *mixer)
{
#ifdef WAV_MUSIC
if ( WAVStream_Init(mixer) == 0 ) {
add_music_decoder("WAVE");
}
#endif
#ifdef MODPLUG_MUSIC
if ( modplug_init(mixer) == 0 ) {
add_music_decoder("MODPLUG");
}
#endif
#ifdef MOD_MUSIC
if ( MOD_init(mixer) == 0 ) {
add_music_decoder("MIKMOD");
}
#endif
#ifdef MID_MUSIC
#ifdef USE_TIMIDITY_MIDI
samplesize = mixer->size / mixer->samples;
if ( Timidity_Init(mixer->freq, mixer->format,
mixer->channels, mixer->samples) == 0 ) {
timidity_ok = 1;
add_music_decoder("TIMIDITY");
} else {
timidity_ok = 0;
}
#endif
#ifdef USE_FLUIDSYNTH_MIDI
if ( fluidsynth_init(mixer) == 0 ) {
fluidsynth_ok = 1;
add_music_decoder("FLUIDSYNTH");
} else {
fluidsynth_ok = 0;
}
#endif
#ifdef USE_NATIVE_MIDI
#ifdef USE_FLUIDSYNTH_MIDI
native_midi_ok = !fluidsynth_ok;
if ( native_midi_ok )
#endif
#ifdef USE_TIMIDITY_MIDI
native_midi_ok = !timidity_ok;
if ( !native_midi_ok ) {
native_midi_ok = (getenv("SDL_NATIVE_MUSIC") != NULL);
}
if ( native_midi_ok )
#endif
native_midi_ok = native_midi_detect();
if ( native_midi_ok )
add_music_decoder("NATIVEMIDI");
#endif
#endif
#ifdef OGG_MUSIC
if ( OGG_init(mixer) == 0 ) {
add_music_decoder("OGG");
}
#endif
#ifdef FLAC_MUSIC
if ( FLAC_init(mixer) == 0 ) {
add_music_decoder("FLAC");
}
#endif
#if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
/* Keep a copy of the mixer */
used_mixer = *mixer;
add_music_decoder("MP3");
#endif
 
music_playing = NULL;
music_stopped = 0;
Mix_VolumeMusic(SDL_MIX_MAXVOLUME);
 
/* Calculate the number of ms for each callback */
ms_per_step = (int) (((float)mixer->samples * 1000.0) / mixer->freq);
 
return(0);
}
 
/* Portable case-insensitive string compare function */
int MIX_string_equals(const char *str1, const char *str2)
{
while ( *str1 && *str2 ) {
if ( toupper((unsigned char)*str1) !=
toupper((unsigned char)*str2) )
break;
++str1;
++str2;
}
return (!*str1 && !*str2);
}
 
static int detect_mp3(Uint8 *magic)
{
if ( strncmp((char *)magic, "ID3", 3) == 0 ) {
return 1;
}
 
/* Detection code lifted from SMPEG */
if(((magic[0] & 0xff) != 0xff) || // No sync bits
((magic[1] & 0xf0) != 0xf0) || //
((magic[2] & 0xf0) == 0x00) || // Bitrate is 0
((magic[2] & 0xf0) == 0xf0) || // Bitrate is 15
((magic[2] & 0x0c) == 0x0c) || // Frequency is 3
((magic[1] & 0x06) == 0x00)) { // Layer is 4
return(0);
}
return 1;
}
 
/* MUS_MOD can't be auto-detected. If no other format was detected, MOD is
* assumed and MUS_MOD will be returned, meaning that the format might not
* actually be MOD-based.
*
* Returns MUS_NONE in case of errors. */
static Mix_MusicType detect_music_type(SDL_RWops *rw)
{
Uint8 magic[5];
Uint8 moremagic[9];
 
int start = SDL_RWtell(rw);
if (SDL_RWread(rw, magic, 1, 4) != 4 || SDL_RWread(rw, moremagic, 1, 8) != 8 ) {
Mix_SetError("Couldn't read from RWops");
return MUS_NONE;
}
SDL_RWseek(rw, start, RW_SEEK_SET);
magic[4]='\0';
moremagic[8] = '\0';
 
/* WAVE files have the magic four bytes "RIFF"
AIFF files have the magic 12 bytes "FORM" XXXX "AIFF" */
if (((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
(strcmp((char *)magic, "FORM") == 0)) {
return MUS_WAV;
}
 
/* Ogg Vorbis files have the magic four bytes "OggS" */
if (strcmp((char *)magic, "OggS") == 0) {
return MUS_OGG;
}
 
/* FLAC files have the magic four bytes "fLaC" */
if (strcmp((char *)magic, "fLaC") == 0) {
return MUS_FLAC;
}
 
/* MIDI files have the magic four bytes "MThd" */
if (strcmp((char *)magic, "MThd") == 0) {
return MUS_MID;
}
 
if (detect_mp3(magic)) {
return MUS_MP3;
}
 
/* Assume MOD format.
*
* Apparently there is no way to check if the file is really a MOD,
* or there are too many formats supported by MikMod/ModPlug, or
* MikMod/ModPlug does this check by itself. */
return MUS_MOD;
}
 
/* Load a music file */
Mix_Music *Mix_LoadMUS(const char *file)
{
SDL_RWops *rw;
Mix_Music *music;
Mix_MusicType type;
char *ext = strrchr(file, '.');
 
#ifdef CMD_MUSIC
if ( music_cmd ) {
/* Allocate memory for the music structure */
music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music));
if ( music == NULL ) {
Mix_SetError("Out of memory");
return(NULL);
}
music->error = 0;
music->type = MUS_CMD;
music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
if ( music->data.cmd == NULL ) {
SDL_free(music);
music == NULL;
}
return music;
}
#endif
 
rw = SDL_RWFromFile(file, "rb");
if ( rw == NULL ) {
Mix_SetError("Couldn't open '%s'", file);
return NULL;
}
 
/* Use the extension as a first guess on the file type */
type = MUS_NONE;
ext = strrchr(file, '.');
/* No need to guard these with #ifdef *_MUSIC stuff,
* since we simply call Mix_LoadMUSType_RW() later */
if ( ext ) {
++ext; /* skip the dot in the extension */
if ( MIX_string_equals(ext, "WAV") ) {
type = MUS_WAV;
} else if ( MIX_string_equals(ext, "MID") ||
MIX_string_equals(ext, "MIDI") ||
MIX_string_equals(ext, "KAR") ) {
type = MUS_MID;
} else if ( MIX_string_equals(ext, "OGG") ) {
type = MUS_OGG;
} else if ( MIX_string_equals(ext, "FLAC") ) {
type = MUS_FLAC;
} else if ( MIX_string_equals(ext, "MPG") ||
MIX_string_equals(ext, "MPEG") ||
MIX_string_equals(ext, "MP3") ||
MIX_string_equals(ext, "MAD") ) {
type = MUS_MP3;
}
}
if ( type == MUS_NONE ) {
type = detect_music_type(rw);
}
 
/* We need to know if a specific error occurs; if not, we'll set a
* generic one, so we clear the current one. */
Mix_SetError("");
music = Mix_LoadMUSType_RW(rw, type, SDL_TRUE);
if ( music == NULL && Mix_GetError()[0] == '\0' ) {
SDL_FreeRW(rw);
Mix_SetError("Couldn't open '%s'", file);
}
return music;
}
 
Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw)
{
return Mix_LoadMUSType_RW(rw, MUS_NONE, SDL_FALSE);
}
 
Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *rw, Mix_MusicType type, int freesrc)
{
Mix_Music *music;
 
if (!rw) {
Mix_SetError("RWops pointer is NULL");
return NULL;
}
 
/* If the caller wants auto-detection, figure out what kind of file
* this is. */
if (type == MUS_NONE) {
if ((type = detect_music_type(rw)) == MUS_NONE) {
/* Don't call Mix_SetError() here since detect_music_type()
* does that. */
return NULL;
}
}
 
/* Allocate memory for the music structure */
music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music));
if (music == NULL ) {
Mix_SetError("Out of memory");
return NULL;
}
music->error = 0;
 
switch (type) {
#ifdef WAV_MUSIC
case MUS_WAV:
/* The WAVE loader needs the first 4 bytes of the header */
{
Uint8 magic[5];
int start = SDL_RWtell(rw);
if (SDL_RWread(rw, magic, 1, 4) != 4) {
Mix_SetError("Couldn't read from RWops");
return MUS_NONE;
}
SDL_RWseek(rw, start, RW_SEEK_SET);
magic[4] = '\0';
music->type = MUS_WAV;
music->data.wave = WAVStream_LoadSong_RW(rw, (char *)magic, freesrc);
}
if (music->data.wave == NULL) {
music->error = 1;
}
break;
#endif
#ifdef OGG_MUSIC
case MUS_OGG:
music->type = MUS_OGG;
music->data.ogg = OGG_new_RW(rw, freesrc);
if ( music->data.ogg == NULL ) {
music->error = 1;
}
break;
#endif
#ifdef FLAC_MUSIC
case MUS_FLAC:
music->type = MUS_FLAC;
music->data.flac = FLAC_new_RW(rw, freesrc);
if ( music->data.flac == NULL ) {
music->error = 1;
}
break;
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
if ( Mix_Init(MIX_INIT_MP3) ) {
SMPEG_Info info;
music->type = MUS_MP3;
music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0);
if ( !info.has_audio ) {
Mix_SetError("MPEG file does not have any audio stream.");
music->error = 1;
} else {
smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
}
} else {
music->error = 1;
}
break;
#elif defined(MP3_MAD_MUSIC)
case MUS_MP3:
music->type = MUS_MP3_MAD;
music->data.mp3_mad = mad_openFileRW(rw, &used_mixer, freesrc);
if (music->data.mp3_mad == 0) {
Mix_SetError("Could not initialize MPEG stream.");
music->error = 1;
}
break;
#endif
#ifdef MID_MUSIC
case MUS_MID:
music->type = MUS_MID;
#ifdef USE_NATIVE_MIDI
if ( native_midi_ok ) {
music->data.nativemidi = native_midi_loadsong_RW(rw, freesrc);
if ( music->data.nativemidi == NULL ) {
Mix_SetError("%s", native_midi_error());
music->error = 1;
}
break;
}
#endif
#ifdef USE_FLUIDSYNTH_MIDI
if ( fluidsynth_ok ) {
music->data.fluidsynthmidi = fluidsynth_loadsong_RW(rw, freesrc);
if ( music->data.fluidsynthmidi == NULL ) {
music->error = 1;
}
break;
}
#endif
#ifdef USE_TIMIDITY_MIDI
if ( timidity_ok ) {
music->data.midi = Timidity_LoadSong_RW(rw, freesrc);
if ( music->data.midi == NULL ) {
Mix_SetError("%s", Timidity_Error());
music->error = 1;
}
} else {
Mix_SetError("%s", Timidity_Error());
music->error = 1;
}
#endif
break;
#endif
#if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC)
case MUS_MOD:
music->error = 1;
#ifdef MODPLUG_MUSIC
if ( music->error ) {
music->type = MUS_MODPLUG;
music->data.modplug = modplug_new_RW(rw, freesrc);
if ( music->data.modplug ) {
music->error = 0;
}
}
#endif
#ifdef MOD_MUSIC
if ( music->error ) {
music->type = MUS_MOD;
music->data.module = MOD_new_RW(rw, freesrc);
if ( music->data.module ) {
music->error = 0;
}
}
#endif
break;
#endif
 
default:
Mix_SetError("Unrecognized music format");
music->error=1;
} /* switch (want) */
 
 
if (music->error) {
SDL_free(music);
music=NULL;
}
return(music);
}
 
/* Free a music chunk previously loaded */
void Mix_FreeMusic(Mix_Music *music)
{
if ( music ) {
/* Stop the music if it's currently playing */
SDL_LockAudio();
if ( music == music_playing ) {
/* Wait for any fade out to finish */
while ( music->fading == MIX_FADING_OUT ) {
SDL_UnlockAudio();
SDL_Delay(100);
SDL_LockAudio();
}
if ( music == music_playing ) {
music_internal_halt();
}
}
SDL_UnlockAudio();
switch (music->type) {
#ifdef CMD_MUSIC
case MUS_CMD:
MusicCMD_FreeSong(music->data.cmd);
break;
#endif
#ifdef WAV_MUSIC
case MUS_WAV:
WAVStream_FreeSong(music->data.wave);
break;
#endif
#ifdef MODPLUG_MUSIC
case MUS_MODPLUG:
modplug_delete(music->data.modplug);
break;
#endif
#ifdef MOD_MUSIC
case MUS_MOD:
MOD_delete(music->data.module);
break;
#endif
#ifdef MID_MUSIC
case MUS_MID:
#ifdef USE_NATIVE_MIDI
if ( native_midi_ok ) {
native_midi_freesong(music->data.nativemidi);
goto skip;
}
#endif
#ifdef USE_FLUIDSYNTH_MIDI
if ( fluidsynth_ok ) {
fluidsynth_freesong(music->data.fluidsynthmidi);
goto skip;
}
#endif
#ifdef USE_TIMIDITY_MIDI
if ( timidity_ok ) {
Timidity_FreeSong(music->data.midi);
goto skip;
}
#endif
break;
#endif
#ifdef OGG_MUSIC
case MUS_OGG:
OGG_delete(music->data.ogg);
break;
#endif
#ifdef FLAC_MUSIC
case MUS_FLAC:
FLAC_delete(music->data.flac);
break;
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
smpeg.SMPEG_delete(music->data.mp3);
break;
#endif
#ifdef MP3_MAD_MUSIC
case MUS_MP3_MAD:
mad_closeFile(music->data.mp3_mad);
break;
#endif
default:
/* Unknown music type?? */
break;
}
 
skip:
SDL_free(music);
}
}
 
/* Find out the music format of a mixer music, or the currently playing
music, if 'music' is NULL.
*/
Mix_MusicType Mix_GetMusicType(const Mix_Music *music)
{
Mix_MusicType type = MUS_NONE;
 
if ( music ) {
type = music->type;
} else {
SDL_LockAudio();
if ( music_playing ) {
type = music_playing->type;
}
SDL_UnlockAudio();
}
return(type);
}
 
/* Play a music chunk. Returns 0, or -1 if there was an error.
*/
static int music_internal_play(Mix_Music *music, double position)
{
int retval = 0;
 
#if defined(__MACOSX__) && defined(USE_NATIVE_MIDI)
/* This fixes a bug with native MIDI on Mac OS X, where you
can't really stop and restart MIDI from the audio callback.
*/
if ( music == music_playing && music->type == MUS_MID && native_midi_ok ) {
/* Just a seek suffices to restart playing */
music_internal_position(position);
return 0;
}
#endif
 
/* Note the music we're playing */
if ( music_playing ) {
music_internal_halt();
}
music_playing = music;
 
/* Set the initial volume */
if ( music->type != MUS_MOD ) {
music_internal_initialize_volume();
}
 
/* Set up for playback */
switch (music->type) {
#ifdef CMD_MUSIC
case MUS_CMD:
MusicCMD_Start(music->data.cmd);
break;
#endif
#ifdef WAV_MUSIC
case MUS_WAV:
WAVStream_Start(music->data.wave);
break;
#endif
#ifdef MODPLUG_MUSIC
case MUS_MODPLUG:
/* can't set volume until file is loaded, so finally set it now */
music_internal_initialize_volume();
modplug_play(music->data.modplug);
break;
#endif
#ifdef MOD_MUSIC
case MUS_MOD:
MOD_play(music->data.module);
/* Player_SetVolume() does nothing before Player_Start() */
music_internal_initialize_volume();
break;
#endif
#ifdef MID_MUSIC
case MUS_MID:
#ifdef USE_NATIVE_MIDI
if ( native_midi_ok ) {
native_midi_start(music->data.nativemidi, music_loops);
goto skip;
}
#endif
#ifdef USE_FLUIDSYNTH_MIDI
if (fluidsynth_ok ) {
fluidsynth_start(music->data.fluidsynthmidi);
goto skip;
}
#endif
#ifdef USE_TIMIDITY_MIDI
if ( timidity_ok ) {
Timidity_Start(music->data.midi);
goto skip;
}
#endif
break;
#endif
#ifdef OGG_MUSIC
case MUS_OGG:
OGG_play(music->data.ogg);
break;
#endif
#ifdef FLAC_MUSIC
case MUS_FLAC:
FLAC_play(music->data.flac);
break;
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
smpeg.SMPEG_enableaudio(music->data.mp3,1);
smpeg.SMPEG_enablevideo(music->data.mp3,0);
smpeg.SMPEG_play(music_playing->data.mp3);
break;
#endif
#ifdef MP3_MAD_MUSIC
case MUS_MP3_MAD:
mad_start(music->data.mp3_mad);
break;
#endif
default:
Mix_SetError("Can't play unknown music type");
retval = -1;
break;
}
 
skip:
/* Set the playback position, note any errors if an offset is used */
if ( retval == 0 ) {
if ( position > 0.0 ) {
if ( music_internal_position(position) < 0 ) {
Mix_SetError("Position not implemented for music type");
retval = -1;
}
} else {
music_internal_position(0.0);
}
}
 
/* If the setup failed, we're not playing any music anymore */
if ( retval < 0 ) {
music_playing = NULL;
}
return(retval);
}
int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
{
int retval;
 
if ( ms_per_step == 0 ) {
SDL_SetError("Audio device hasn't been opened");
return(-1);
}
 
/* Don't play null pointers :-) */
if ( music == NULL ) {
Mix_SetError("music parameter was NULL");
return(-1);
}
 
/* Setup the data */
if ( ms ) {
music->fading = MIX_FADING_IN;
} else {
music->fading = MIX_NO_FADING;
}
music->fade_step = 0;
music->fade_steps = ms/ms_per_step;
 
/* Play the puppy */
SDL_LockAudio();
/* If the current music is fading out, wait for the fade to complete */
while ( music_playing && (music_playing->fading == MIX_FADING_OUT) ) {
SDL_UnlockAudio();
SDL_Delay(100);
SDL_LockAudio();
}
music_active = 1;
if (loops == 1) {
/* Loop is the number of times to play the audio */
loops = 0;
}
music_loops = loops;
retval = music_internal_play(music, position);
SDL_UnlockAudio();
 
return(retval);
}
int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
{
return Mix_FadeInMusicPos(music, loops, ms, 0.0);
}
int Mix_PlayMusic(Mix_Music *music, int loops)
{
return Mix_FadeInMusicPos(music, loops, 0, 0.0);
}
 
/* Set the playing music position */
int music_internal_position(double position)
{
int retval = 0;
 
switch (music_playing->type) {
#ifdef MODPLUG_MUSIC
case MUS_MODPLUG:
modplug_jump_to_time(music_playing->data.modplug, position);
break;
#endif
#ifdef MOD_MUSIC
case MUS_MOD:
MOD_jump_to_time(music_playing->data.module, position);
break;
#endif
#ifdef OGG_MUSIC
case MUS_OGG:
OGG_jump_to_time(music_playing->data.ogg, position);
break;
#endif
#ifdef FLAC_MUSIC
case MUS_FLAC:
FLAC_jump_to_time(music_playing->data.flac, position);
break;
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
smpeg.SMPEG_rewind(music_playing->data.mp3);
smpeg.SMPEG_play(music_playing->data.mp3);
if ( position > 0.0 ) {
smpeg.SMPEG_skip(music_playing->data.mp3, (float)position);
}
break;
#endif
#ifdef MP3_MAD_MUSIC
case MUS_MP3_MAD:
mad_seek(music_playing->data.mp3_mad, position);
break;
#endif
default:
/* TODO: Implement this for other music backends */
retval = -1;
break;
}
return(retval);
}
int Mix_SetMusicPosition(double position)
{
int retval;
 
SDL_LockAudio();
if ( music_playing ) {
retval = music_internal_position(position);
if ( retval < 0 ) {
Mix_SetError("Position not implemented for music type");
}
} else {
Mix_SetError("Music isn't playing");
retval = -1;
}
SDL_UnlockAudio();
 
return(retval);
}
 
/* Set the music's initial volume */
static void music_internal_initialize_volume(void)
{
if ( music_playing->fading == MIX_FADING_IN ) {
music_internal_volume(0);
} else {
music_internal_volume(music_volume);
}
}
 
/* Set the music volume */
static void music_internal_volume(int volume)
{
switch (music_playing->type) {
#ifdef CMD_MUSIC
case MUS_CMD:
MusicCMD_SetVolume(volume);
break;
#endif
#ifdef WAV_MUSIC
case MUS_WAV:
WAVStream_SetVolume(volume);
break;
#endif
#ifdef MODPLUG_MUSIC
case MUS_MODPLUG:
modplug_setvolume(music_playing->data.modplug, volume);
break;
#endif
#ifdef MOD_MUSIC
case MUS_MOD:
MOD_setvolume(music_playing->data.module, volume);
break;
#endif
#ifdef MID_MUSIC
case MUS_MID:
#ifdef USE_NATIVE_MIDI
if ( native_midi_ok ) {
native_midi_setvolume(volume);
return;
}
#endif
#ifdef USE_FLUIDSYNTH_MIDI
if ( fluidsynth_ok ) {
fluidsynth_setvolume(music_playing->data.fluidsynthmidi, volume);
return;
}
#endif
#ifdef USE_TIMIDITY_MIDI
if ( timidity_ok ) {
Timidity_SetVolume(volume);
return;
}
#endif
break;
#endif
#ifdef OGG_MUSIC
case MUS_OGG:
OGG_setvolume(music_playing->data.ogg, volume);
break;
#endif
#ifdef FLAC_MUSIC
case MUS_FLAC:
FLAC_setvolume(music_playing->data.flac, volume);
break;
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
smpeg.SMPEG_setvolume(music_playing->data.mp3,(int)(((float)volume/(float)MIX_MAX_VOLUME)*100.0));
break;
#endif
#ifdef MP3_MAD_MUSIC
case MUS_MP3_MAD:
mad_setVolume(music_playing->data.mp3_mad, volume);
break;
#endif
default:
/* Unknown music type?? */
break;
}
}
int Mix_VolumeMusic(int volume)
{
int prev_volume;
 
prev_volume = music_volume;
if ( volume < 0 ) {
return prev_volume;
}
if ( volume > SDL_MIX_MAXVOLUME ) {
volume = SDL_MIX_MAXVOLUME;
}
music_volume = volume;
SDL_LockAudio();
if ( music_playing ) {
music_internal_volume(music_volume);
}
SDL_UnlockAudio();
return(prev_volume);
}
 
/* Halt playing of music */
static void music_internal_halt(void)
{
switch (music_playing->type) {
#ifdef CMD_MUSIC
case MUS_CMD:
MusicCMD_Stop(music_playing->data.cmd);
break;
#endif
#ifdef WAV_MUSIC
case MUS_WAV:
WAVStream_Stop();
break;
#endif
#ifdef MODPLUG_MUSIC
case MUS_MODPLUG:
modplug_stop(music_playing->data.modplug);
break;
#endif
#ifdef MOD_MUSIC
case MUS_MOD:
MOD_stop(music_playing->data.module);
break;
#endif
#ifdef MID_MUSIC
case MUS_MID:
#ifdef USE_NATIVE_MIDI
if ( native_midi_ok ) {
native_midi_stop();
goto skip;
}
#endif
#ifdef USE_FLUIDSYNTH_MIDI
if ( fluidsynth_ok ) {
fluidsynth_stop(music_playing->data.fluidsynthmidi);
goto skip;
}
#endif
#ifdef USE_TIMIDITY_MIDI
if ( timidity_ok ) {
Timidity_Stop();
goto skip;
}
#endif
break;
#endif
#ifdef OGG_MUSIC
case MUS_OGG:
OGG_stop(music_playing->data.ogg);
break;
#endif
#ifdef FLAC_MUSIC
case MUS_FLAC:
FLAC_stop(music_playing->data.flac);
break;
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
smpeg.SMPEG_stop(music_playing->data.mp3);
break;
#endif
#ifdef MP3_MAD_MUSIC
case MUS_MP3_MAD:
mad_stop(music_playing->data.mp3_mad);
break;
#endif
default:
/* Unknown music type?? */
return;
}
 
skip:
music_playing->fading = MIX_NO_FADING;
music_playing = NULL;
}
int Mix_HaltMusic(void)
{
SDL_LockAudio();
if ( music_playing ) {
music_internal_halt();
}
SDL_UnlockAudio();
 
return(0);
}
 
/* Progressively stop the music */
int Mix_FadeOutMusic(int ms)
{
int retval = 0;
 
if ( ms_per_step == 0 ) {
SDL_SetError("Audio device hasn't been opened");
return 0;
}
 
if (ms <= 0) { /* just halt immediately. */
Mix_HaltMusic();
return 1;
}
 
SDL_LockAudio();
if ( music_playing) {
int fade_steps = (ms + ms_per_step - 1)/ms_per_step;
if ( music_playing->fading == MIX_NO_FADING ) {
music_playing->fade_step = 0;
} else {
int step;
int old_fade_steps = music_playing->fade_steps;
if ( music_playing->fading == MIX_FADING_OUT ) {
step = music_playing->fade_step;
} else {
step = old_fade_steps
- music_playing->fade_step + 1;
}
music_playing->fade_step = (step * fade_steps)
/ old_fade_steps;
}
music_playing->fading = MIX_FADING_OUT;
music_playing->fade_steps = fade_steps;
retval = 1;
}
SDL_UnlockAudio();
 
return(retval);
}
 
Mix_Fading Mix_FadingMusic(void)
{
Mix_Fading fading = MIX_NO_FADING;
 
SDL_LockAudio();
if ( music_playing ) {
fading = music_playing->fading;
}
SDL_UnlockAudio();
 
return(fading);
}
 
/* Pause/Resume the music stream */
void Mix_PauseMusic(void)
{
music_active = 0;
}
 
void Mix_ResumeMusic(void)
{
music_active = 1;
}
 
void Mix_RewindMusic(void)
{
Mix_SetMusicPosition(0.0);
}
 
int Mix_PausedMusic(void)
{
return (music_active == 0);
}
 
/* Check the status of the music */
static int music_internal_playing()
{
int playing = 1;
 
if (music_playing == NULL) {
return 0;
}
 
switch (music_playing->type) {
#ifdef CMD_MUSIC
case MUS_CMD:
if (!MusicCMD_Active(music_playing->data.cmd)) {
playing = 0;
}
break;
#endif
#ifdef WAV_MUSIC
case MUS_WAV:
if ( ! WAVStream_Active() ) {
playing = 0;
}
break;
#endif
#ifdef MODPLUG_MUSIC
case MUS_MODPLUG:
if ( ! modplug_playing(music_playing->data.modplug) ) {
playing = 0;
}
break;
#endif
#ifdef MOD_MUSIC
case MUS_MOD:
if ( ! MOD_playing(music_playing->data.module) ) {
playing = 0;
}
break;
#endif
#ifdef MID_MUSIC
case MUS_MID:
#ifdef USE_NATIVE_MIDI
if ( native_midi_ok ) {
if ( ! native_midi_active() )
playing = 0;
goto skip;
}
#endif
#ifdef USE_FLUIDSYNTH_MIDI
if ( fluidsynth_ok ) {
if ( ! fluidsynth_active(music_playing->data.fluidsynthmidi) )
playing = 0;
goto skip;
}
#endif
#ifdef USE_TIMIDITY_MIDI
if ( timidity_ok ) {
if ( ! Timidity_Active() )
playing = 0;
goto skip;
}
#endif
break;
#endif
#ifdef OGG_MUSIC
case MUS_OGG:
if ( ! OGG_playing(music_playing->data.ogg) ) {
playing = 0;
}
break;
#endif
#ifdef FLAC_MUSIC
case MUS_FLAC:
if ( ! FLAC_playing(music_playing->data.flac) ) {
playing = 0;
}
break;
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
if ( smpeg.SMPEG_status(music_playing->data.mp3) != SMPEG_PLAYING )
playing = 0;
break;
#endif
#ifdef MP3_MAD_MUSIC
case MUS_MP3_MAD:
if (!mad_isPlaying(music_playing->data.mp3_mad)) {
playing = 0;
}
break;
#endif
default:
playing = 0;
break;
}
 
skip:
return(playing);
}
int Mix_PlayingMusic(void)
{
int playing = 0;
 
SDL_LockAudio();
if ( music_playing ) {
playing = music_loops || music_internal_playing();
}
SDL_UnlockAudio();
 
return(playing);
}
 
/* Set the external music playback command */
int Mix_SetMusicCMD(const char *command)
{
Mix_HaltMusic();
if ( music_cmd ) {
SDL_free(music_cmd);
music_cmd = NULL;
}
if ( command ) {
music_cmd = (char *)SDL_malloc(strlen(command)+1);
if ( music_cmd == NULL ) {
return(-1);
}
strcpy(music_cmd, command);
}
return(0);
}
 
int Mix_SetSynchroValue(int i)
{
/* Not supported by any players at this time */
return(-1);
}
 
int Mix_GetSynchroValue(void)
{
/* Not supported by any players at this time */
return(-1);
}
 
 
/* Uninitialize the music players */
void close_music(void)
{
Mix_HaltMusic();
#ifdef CMD_MUSIC
Mix_SetMusicCMD(NULL);
#endif
#ifdef MODPLUG_MUSIC
modplug_exit();
#endif
#ifdef MOD_MUSIC
MOD_exit();
#endif
#ifdef MID_MUSIC
# ifdef USE_TIMIDITY_MIDI
Timidity_Close();
# endif
#endif
 
/* rcg06042009 report available decoders at runtime. */
SDL_free(music_decoders);
music_decoders = NULL;
num_decoders = 0;
 
ms_per_step = 0;
}
 
int Mix_SetSoundFonts(const char *paths)
{
#ifdef MID_MUSIC
if (soundfont_paths) {
SDL_free(soundfont_paths);
soundfont_paths = NULL;
}
 
if (paths) {
if (!(soundfont_paths = SDL_strdup(paths))) {
Mix_SetError("Insufficient memory to set SoundFonts");
return 0;
}
}
#endif
return 1;
}
 
#ifdef MID_MUSIC
const char* Mix_GetSoundFonts(void)
{
const char* force = getenv("SDL_FORCE_SOUNDFONTS");
 
if (!soundfont_paths || (force && force[0] == '1')) {
return getenv("SDL_SOUNDFONTS");
} else {
return soundfont_paths;
}
}
 
int Mix_EachSoundFont(int (*function)(const char*, void*), void *data)
{
char *context, *path, *paths;
const char* cpaths = Mix_GetSoundFonts();
 
if (!cpaths) {
Mix_SetError("No SoundFonts have been requested");
return 0;
}
 
if (!(paths = SDL_strdup(cpaths))) {
Mix_SetError("Insufficient memory to iterate over SoundFonts");
return 0;
}
 
#if defined(__MINGW32__) || defined(__MINGW64__)
for (path = strtok(paths, ";"); path; path = strtok(NULL, ";")) {
#elif defined(_WIN32)
for (path = strtok_s(paths, ";", &context); path; path = strtok_s(NULL, ";", &context)) {
#else
for (path = strtok_r(paths, ":;", &context); path; path = strtok_r(NULL, ":;", &context)) {
#endif
if (!function(path, data)) {
SDL_free(paths);
return 0;
}
}
 
SDL_free(paths);
return 1;
}
#endif
/contrib/games/wolf3d/SDL_mixer/music_cmd.h
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 */
/contrib/games/wolf3d/SDL_mixer/music_flac.h
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 */
/contrib/games/wolf3d/SDL_mixer/music_mad.h
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
/contrib/games/wolf3d/SDL_mixer/music_mod.h
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 */
/contrib/games/wolf3d/SDL_mixer/music_modplug.h
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
/contrib/games/wolf3d/SDL_mixer/music_ogg.h
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 */
/contrib/games/wolf3d/SDL_mixer/wavestream.h
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);
/contrib/games/wolf3d/compile_flags.txt
0,0 → 1,4
-I
../../sdk/sources/SDL-1.2.2_newlib/include
../../sdk/sources/newlib/libc/include
.
/contrib/games/wolf3d/id_sd.cpp
27,21 → 27,16
// NeedsMusic - load music?
//
 
/// ///////////// ///
/// In Kolibrios - stub
 
#include "wl_def.h"
//#include <SDL_mixer.h>
#include "SDL_mixer/SDL_mixer.h"
#if defined(GP2X_940)
#include "gp2x/fmopl.h"
#else
#ifdef USE_GPL
#include "dosbox/dbopl.h"
#else
#include "mame/fmopl.h"
#endif
#endif
 
#pragma hdrstop
 
#define ORIGSAMPLERATE 7042
 
typedef struct
71,6 → 66,11
uint32_t length;
} digiinfo;
 
static Mix_Chunk *SoundChunks[ STARTMUSIC - STARTDIGISOUNDS];
static byte *SoundBuffers[STARTMUSIC - STARTDIGISOUNDS];
 
globalsoundpos channelSoundPos[MIX_CHANNELS];
 
// Global variables
boolean AdLibPresent,
SoundBlasterPresent,SBProPresent,
116,29 → 116,1309
static int sqHackSeqLen;
static longword sqHackTime;
 
// STUB
void SD_Startup(void){};
void SD_Shutdown(void){};
 
int SD_GetChannelForDigi(int which){};
void SD_PositionSound(int leftvol,int rightvol){};
boolean SD_PlaySound(soundnames sound){};
void SD_SetPosition(int channel, int leftvol,int rightvol){};
void SD_StopSound(void){};
void SD_WaitSoundDone(void){};
static void SDL_SoundFinished(void)
{
SoundNumber = (soundnames)0;
SoundPriority = 0;
}
 
void SD_StartMusic(int chunk){};
void SD_ContinueMusic(int chunk, int startoffs){};
void SD_MusicOn(void){};
void SD_FadeOutMusic(void){};
int SD_MusicOff(void){};
 
boolean SD_MusicPlaying(void){};
boolean SD_SetSoundMode(SDMode mode){};
boolean SD_SetMusicMode(SMMode mode){};
word SD_SoundPlaying(void){};
#ifdef NOTYET
 
void SD_SetDigiDevice(SDSMode){};
void SD_PrepareSound(int which){};
int SD_PlayDigitized(word which,int leftpos,int rightpos){};
void SD_StopDigitized(void){};
void SDL_turnOnPCSpeaker(word timerval);
#pragma aux SDL_turnOnPCSpeaker = \
"mov al,0b6h" \
"out 43h,al" \
"mov al,bl" \
"out 42h,al" \
"mov al,bh" \
"out 42h,al" \
"in al,61h" \
"or al,3" \
"out 61h,al" \
parm [bx] \
modify exact [al]
 
void SDL_turnOffPCSpeaker();
#pragma aux SDL_turnOffPCSpeaker = \
"in al,61h" \
"and al,0fch" \
"out 61h,al" \
modify exact [al]
 
void SDL_setPCSpeaker(byte val);
#pragma aux SDL_setPCSpeaker = \
"in al,61h" \
"and al,0fch" \
"or al,ah" \
"out 61h,al" \
parm [ah] \
modify exact [al]
 
void inline SDL_DoFX()
{
if(pcSound)
{
if(*pcSound!=pcLastSample)
{
pcLastSample=*pcSound;
 
if(pcLastSample)
SDL_turnOnPCSpeaker(pcLastSample*60);
else
SDL_turnOffPCSpeaker();
}
pcSound++;
pcLengthLeft--;
if(!pcLengthLeft)
{
pcSound=0;
SoundNumber=(soundnames)0;
SoundPriority=0;
SDL_turnOffPCSpeaker();
}
}
 
// [adlib sound stuff removed...]
}
 
static void SDL_DigitizedDoneInIRQ(void);
 
void inline SDL_DoFast()
{
count_fx++;
if(count_fx>=5)
{
count_fx=0;
 
SDL_DoFX();
 
count_time++;
if(count_time>=2)
{
TimeCount++;
count_time=0;
}
}
 
// [adlib music and soundsource stuff removed...]
 
TimerCount+=TimerDivisor;
if(*((word *)&TimerCount+1))
{
*((word *)&TimerCount+1)=0;
t0OldService();
}
else
{
outp(0x20,0x20);
}
}
 
// Timer 0 ISR for 7000Hz interrupts
void __interrupt SDL_t0ExtremeAsmService(void)
{
if(pcindicate)
{
if(pcSound)
{
SDL_setPCSpeaker(((*pcSound++)&0x80)>>6);
pcLengthLeft--;
if(!pcLengthLeft)
{
pcSound=0;
SDL_turnOffPCSpeaker();
SDL_DigitizedDoneInIRQ();
}
}
}
extreme++;
if(extreme>=10)
{
extreme=0;
SDL_DoFast();
}
else
outp(0x20,0x20);
}
 
// Timer 0 ISR for 700Hz interrupts
void __interrupt SDL_t0FastAsmService(void)
{
SDL_DoFast();
}
 
// Timer 0 ISR for 140Hz interrupts
void __interrupt SDL_t0SlowAsmService(void)
{
count_time++;
if(count_time>=2)
{
TimeCount++;
count_time=0;
}
 
SDL_DoFX();
 
TimerCount+=TimerDivisor;
if(*((word *)&TimerCount+1))
{
*((word *)&TimerCount+1)=0;
t0OldService();
}
else
outp(0x20,0x20);
}
 
void SDL_IndicatePC(boolean ind)
{
pcindicate=ind;
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_SetTimer0() - Sets system timer 0 to the specified speed
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_SetTimer0(word speed)
{
#ifndef TPROF // If using Borland's profiling, don't screw with the timer
// _asm pushfd
_asm cli
 
outp(0x43,0x36); // Change timer 0
outp(0x40,(byte)speed);
outp(0x40,speed >> 8);
// Kludge to handle special case for digitized PC sounds
if (TimerDivisor == (1192030 / (TickBase * 100)))
TimerDivisor = (1192030 / (TickBase * 10));
else
TimerDivisor = speed;
 
// _asm popfd
_asm sti
#else
TimerDivisor = 0x10000;
#endif
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_SetIntsPerSec() - Uses SDL_SetTimer0() to set the number of
// interrupts generated by system timer 0 per second
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_SetIntsPerSec(word ints)
{
TimerRate = ints;
SDL_SetTimer0(1192030 / ints);
}
 
static void
SDL_SetTimerSpeed(void)
{
word rate;
void (_interrupt *isr)(void);
 
if ((DigiMode == sds_PC) && DigiPlaying)
{
rate = TickBase * 100;
isr = SDL_t0ExtremeAsmService;
}
else if ((MusicMode == smm_AdLib) || ((DigiMode == sds_SoundSource) && DigiPlaying) )
{
rate = TickBase * 10;
isr = SDL_t0FastAsmService;
}
else
{
rate = TickBase * 2;
isr = SDL_t0SlowAsmService;
}
 
if (rate != TimerRate)
{
_dos_setvect(8,isr);
SDL_SetIntsPerSec(rate);
TimerRate = rate;
}
}
 
//
// PC Sound code
//
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_PCPlaySample() - Plays the specified sample on the PC speaker
//
///////////////////////////////////////////////////////////////////////////
#ifdef _MUSE_
void
#else
static void
#endif
SDL_PCPlaySample(byte *data,longword len,boolean inIRQ)
{
if(!inIRQ)
{
// _asm pushfd
_asm cli
}
 
SDL_IndicatePC(true);
 
pcLengthLeft = len;
pcSound = (volatile byte *)data;
 
if(!inIRQ)
{
// _asm popfd
_asm sti
}
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_PCStopSample() - Stops a sample playing on the PC speaker
//
///////////////////////////////////////////////////////////////////////////
#ifdef _MUSE_
void
#else
static void
#endif
SDL_PCStopSampleInIRQ(void)
{
pcSound = 0;
 
SDL_IndicatePC(false);
 
_asm in al,0x61 // Turn the speaker off
_asm and al,0xfd // ~2
_asm out 0x61,al
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_PCPlaySound() - Plays the specified sound on the PC speaker
//
///////////////////////////////////////////////////////////////////////////
#ifdef _MUSE_
void
#else
static void
#endif
SDL_PCPlaySound(PCSound *sound)
{
// _asm pushfd
_asm cli
 
pcLastSample = -1;
pcLengthLeft = sound->common.length;
pcSound = sound->data;
 
// _asm popfd
_asm sti
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_PCStopSound() - Stops the current sound playing on the PC Speaker
//
///////////////////////////////////////////////////////////////////////////
#ifdef _MUSE_
void
#else
static void
#endif
SDL_PCStopSound(void)
{
// _asm pushfd
_asm cli
 
pcSound = 0;
 
_asm in al,0x61 // Turn the speaker off
_asm and al,0xfd // ~2
_asm out 0x61,al
 
// _asm popfd
_asm sti
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_ShutPC() - Turns off the pc speaker
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_ShutPC(void)
{
// _asm pushfd
_asm cli
 
pcSound = 0;
 
_asm in al,0x61 // Turn the speaker & gate off
_asm and al,0xfc // ~3
_asm out 0x61,al
 
// _asm popfd
_asm sti
}
 
#endif
 
void
SD_StopDigitized(void)
{
DigiPlaying = false;
DigiNumber = (soundnames) 0;
DigiPriority = 0;
SoundPositioned = false;
if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))
SDL_SoundFinished();
 
switch (DigiMode)
{
case sds_PC:
// SDL_PCStopSampleInIRQ();
break;
case sds_SoundBlaster:
// SDL_SBStopSampleInIRQ();
Mix_HaltChannel(-1);
break;
}
}
 
int SD_GetChannelForDigi(int which)
{
if(DigiChannel[which] != -1) return DigiChannel[which];
 
int channel = Mix_GroupAvailable(1);
if(channel == -1) channel = Mix_GroupOldest(1);
if(channel == -1) // All sounds stopped in the meantime?
return Mix_GroupAvailable(1);
return channel;
}
 
void SD_SetPosition(int channel, int leftpos, int rightpos)
{
if((leftpos < 0) || (leftpos > 15) || (rightpos < 0) || (rightpos > 15)
|| ((leftpos == 15) && (rightpos == 15)))
Quit("SD_SetPosition: Illegal position");
 
switch (DigiMode)
{
case sds_SoundBlaster:
// SDL_PositionSBP(leftpos,rightpos);
Mix_SetPanning(channel, ((15 - leftpos) << 4) + 15,
((15 - rightpos) << 4) + 15);
break;
}
}
 
Sint16 GetSample(float csample, byte *samples, int size)
{
float s0=0, s1=0, s2=0;
int cursample = (int) csample;
float sf = csample - (float) cursample;
 
if(cursample-1 >= 0) s0 = (float) (samples[cursample-1] - 128);
s1 = (float) (samples[cursample] - 128);
if(cursample+1 < size) s2 = (float) (samples[cursample+1] - 128);
 
float val = s0*sf*(sf-1)/2 - s1*(sf*sf-1) + s2*(sf+1)*sf/2;
int32_t intval = (int32_t) (val * 256);
if(intval < -32768) intval = -32768;
else if(intval > 32767) intval = 32767;
return (Sint16) intval;
}
 
void SD_PrepareSound(int which)
{
if(DigiList == NULL)
Quit("SD_PrepareSound(%i): DigiList not initialized!\n", which);
 
int page = DigiList[which].startpage;
int size = DigiList[which].length;
 
byte *origsamples = PM_GetSound(page);
if(origsamples + size >= PM_GetEnd())
Quit("SD_PrepareSound(%i): Sound reaches out of page file!\n", which);
 
int destsamples = (int) ((float) size * (float) param_samplerate
/ (float) ORIGSAMPLERATE);
 
byte *wavebuffer = (byte *) malloc(sizeof(headchunk) + sizeof(wavechunk)
+ destsamples * 2); // dest are 16-bit samples
if(wavebuffer == NULL)
Quit("Unable to allocate wave buffer for sound %i!\n", which);
 
headchunk head = {{'R','I','F','F'}, 0, {'W','A','V','E'},
{'f','m','t',' '}, 0x10, 0x0001, 1, param_samplerate, param_samplerate*2, 2, 16};
wavechunk dhead = {{'d', 'a', 't', 'a'}, destsamples*2};
head.filelenminus8 = sizeof(head) + destsamples*2; // (sizeof(dhead)-8 = 0)
memcpy(wavebuffer, &head, sizeof(head));
memcpy(wavebuffer+sizeof(head), &dhead, sizeof(dhead));
 
// alignment is correct, as wavebuffer comes from malloc
// and sizeof(headchunk) % 4 == 0 and sizeof(wavechunk) % 4 == 0
Sint16 *newsamples = (Sint16 *)(void *) (wavebuffer + sizeof(headchunk)
+ sizeof(wavechunk));
float cursample = 0.F;
float samplestep = (float) ORIGSAMPLERATE / (float) param_samplerate;
for(int i=0; i<destsamples; i++, cursample+=samplestep)
{
newsamples[i] = GetSample((float)size * (float)i / (float)destsamples,
origsamples, size);
}
SoundBuffers[which] = wavebuffer;
 
SoundChunks[which] = Mix_LoadWAV_RW(SDL_RWFromMem(wavebuffer,
sizeof(headchunk) + sizeof(wavechunk) + destsamples * 2), 1);
}
 
int SD_PlayDigitized(word which,int leftpos,int rightpos)
{
if (!DigiMode)
return 0;
 
if (which >= NumDigi)
Quit("SD_PlayDigitized: bad sound number %i", which);
 
int channel = SD_GetChannelForDigi(which);
SD_SetPosition(channel, leftpos,rightpos);
 
DigiPlaying = true;
 
Mix_Chunk *sample = SoundChunks[which];
if(sample == NULL)
{
printf("SoundChunks[%i] is NULL!\n", which);
return 0;
}
 
if(Mix_PlayChannel(channel, sample, 0) == -1)
{
printf("Unable to play sound: %s\n", Mix_GetError());
return 0;
}
 
return channel;
}
 
void SD_ChannelFinished(int channel)
{
channelSoundPos[channel].valid = 0;
}
 
void
SD_SetDigiDevice(SDSMode mode)
{
boolean devicenotpresent;
 
if (mode == DigiMode)
return;
 
SD_StopDigitized();
 
devicenotpresent = false;
switch (mode)
{
case sds_SoundBlaster:
if (!SoundBlasterPresent)
devicenotpresent = true;
break;
}
 
if (!devicenotpresent)
{
DigiMode = mode;
 
#ifdef NOTYET
SDL_SetTimerSpeed();
#endif
}
}
 
void
SDL_SetupDigi(void)
{
// Correct padding enforced by PM_Startup()
word *soundInfoPage = (word *) (void *) PM_GetPage(ChunksInFile-1);
NumDigi = (word) PM_GetPageSize(ChunksInFile - 1) / 4;
 
DigiList = (digiinfo *) malloc(NumDigi * sizeof(digiinfo));
int i;
for(i = 0; i < NumDigi; i++)
{
// Calculate the size of the digi from the sizes of the pages between
// the start page and the start page of the next sound
 
DigiList[i].startpage = soundInfoPage[i * 2];
if((int) DigiList[i].startpage >= ChunksInFile - 1)
{
NumDigi = i;
break;
}
 
int lastPage;
if(i < NumDigi - 1)
{
lastPage = soundInfoPage[i * 2 + 2];
if(lastPage == 0 || lastPage + PMSoundStart > ChunksInFile - 1) lastPage = ChunksInFile - 1;
else lastPage += PMSoundStart;
}
else lastPage = ChunksInFile - 1;
 
int size = 0;
for(int page = PMSoundStart + DigiList[i].startpage; page < lastPage; page++)
size += PM_GetPageSize(page);
 
// Don't include padding of sound info page, if padding was added
if(lastPage == ChunksInFile - 1 && PMSoundInfoPagePadded) size--;
 
// Patch lower 16-bit of size with size from sound info page.
// The original VSWAP contains padding which is included in the page size,
// but not included in the 16-bit size. So we use the more precise value.
if((size & 0xffff0000) != 0 && (size & 0xffff) < soundInfoPage[i * 2 + 1])
size -= 0x10000;
size = (size & 0xffff0000) | soundInfoPage[i * 2 + 1];
 
DigiList[i].length = size;
}
 
for(i = 0; i < LASTSOUND; i++)
{
DigiMap[i] = -1;
DigiChannel[i] = -1;
}
}
 
// AdLib Code
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_ALStopSound() - Turns off any sound effects playing through the
// AdLib card
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_ALStopSound(void)
{
alSound = 0;
alOut(alFreqH + 0, 0);
}
 
static void
SDL_AlSetFXInst(Instrument *inst)
{
byte c,m;
 
m = 0; // modulator cell for channel 0
c = 3; // carrier cell for channel 0
alOut(m + alChar,inst->mChar);
alOut(m + alScale,inst->mScale);
alOut(m + alAttack,inst->mAttack);
alOut(m + alSus,inst->mSus);
alOut(m + alWave,inst->mWave);
alOut(c + alChar,inst->cChar);
alOut(c + alScale,inst->cScale);
alOut(c + alAttack,inst->cAttack);
alOut(c + alSus,inst->cSus);
alOut(c + alWave,inst->cWave);
 
// Note: Switch commenting on these lines for old MUSE compatibility
// alOutInIRQ(alFeedCon,inst->nConn);
alOut(alFeedCon,0);
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_ALPlaySound() - Plays the specified sound on the AdLib card
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_ALPlaySound(AdLibSound *sound)
{
Instrument *inst;
byte *data;
 
SDL_ALStopSound();
 
alLengthLeft = sound->common.length;
data = sound->data;
alBlock = ((sound->block & 7) << 2) | 0x20;
inst = &sound->inst;
 
if (!(inst->mSus | inst->cSus))
{
Quit("SDL_ALPlaySound() - Bad instrument");
}
 
SDL_AlSetFXInst(inst);
alSound = (byte *)data;
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_ShutAL() - Shuts down the AdLib card for sound effects
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_ShutAL(void)
{
alSound = 0;
alOut(alEffects,0);
alOut(alFreqH + 0,0);
SDL_AlSetFXInst(&alZeroInst);
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_CleanAL() - Totally shuts down the AdLib card
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_CleanAL(void)
{
int i;
 
alOut(alEffects,0);
for (i = 1; i < 0xf5; i++)
alOut(i, 0);
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_StartAL() - Starts up the AdLib card for sound effects
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_StartAL(void)
{
alOut(alEffects, 0);
SDL_AlSetFXInst(&alZeroInst);
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_DetectAdLib() - Determines if there's an AdLib (or SoundBlaster
// emulating an AdLib) present
//
///////////////////////////////////////////////////////////////////////////
static boolean
SDL_DetectAdLib(void)
{
for (int i = 1; i <= 0xf5; i++) // Zero all the registers
alOut(i, 0);
 
alOut(1, 0x20); // Set WSE=1
// alOut(8, 0); // Set CSM=0 & SEL=0
 
return true;
}
 
////////////////////////////////////////////////////////////////////////////
//
// SDL_ShutDevice() - turns off whatever device was being used for sound fx
//
////////////////////////////////////////////////////////////////////////////
static void
SDL_ShutDevice(void)
{
switch (SoundMode)
{
case sdm_PC:
// SDL_ShutPC();
break;
case sdm_AdLib:
SDL_ShutAL();
break;
}
SoundMode = sdm_Off;
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_CleanDevice() - totally shuts down all sound devices
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_CleanDevice(void)
{
if ((SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib))
SDL_CleanAL();
}
 
///////////////////////////////////////////////////////////////////////////
//
// SDL_StartDevice() - turns on whatever device is to be used for sound fx
//
///////////////////////////////////////////////////////////////////////////
static void
SDL_StartDevice(void)
{
switch (SoundMode)
{
case sdm_AdLib:
SDL_StartAL();
break;
}
SoundNumber = (soundnames) 0;
SoundPriority = 0;
}
 
// Public routines
 
///////////////////////////////////////////////////////////////////////////
//
// SD_SetSoundMode() - Sets which sound hardware to use for sound effects
//
///////////////////////////////////////////////////////////////////////////
boolean
SD_SetSoundMode(SDMode mode)
{
boolean result = false;
word tableoffset;
 
SD_StopSound();
 
if ((mode == sdm_AdLib) && !AdLibPresent)
mode = sdm_PC;
 
switch (mode)
{
case sdm_Off:
tableoffset = STARTADLIBSOUNDS;
result = true;
break;
case sdm_PC:
tableoffset = STARTPCSOUNDS;
result = true;
break;
case sdm_AdLib:
tableoffset = STARTADLIBSOUNDS;
if (AdLibPresent)
result = true;
break;
default:
Quit("SD_SetSoundMode: Invalid sound mode %i", mode);
return false;
}
SoundTable = &audiosegs[tableoffset];
 
if (result && (mode != SoundMode))
{
SDL_ShutDevice();
SoundMode = mode;
SDL_StartDevice();
}
 
return(result);
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_SetMusicMode() - sets the device to use for background music
//
///////////////////////////////////////////////////////////////////////////
boolean
SD_SetMusicMode(SMMode mode)
{
boolean result = false;
 
SD_FadeOutMusic();
while (SD_MusicPlaying())
SDL_Delay(5);
 
switch (mode)
{
case smm_Off:
result = true;
break;
case smm_AdLib:
if (AdLibPresent)
result = true;
break;
}
 
if (result)
MusicMode = mode;
 
// SDL_SetTimerSpeed();
 
return(result);
}
 
int numreadysamples = 0;
byte *curAlSound = 0;
byte *curAlSoundPtr = 0;
longword curAlLengthLeft = 0;
int soundTimeCounter = 5;
int samplesPerMusicTick;
 
void SDL_IMFMusicPlayer(void *udata, Uint8 *stream, int len)
{
int stereolen = len>>1;
int sampleslen = stereolen>>1;
INT16 *stream16 = (INT16 *) (void *) stream; // expect correct alignment
 
while(1)
{
if(numreadysamples)
{
if(numreadysamples<sampleslen)
{
YM3812UpdateOne(0, stream16, numreadysamples);
stream16 += numreadysamples*2;
sampleslen -= numreadysamples;
}
else
{
YM3812UpdateOne(0, stream16, sampleslen);
numreadysamples -= sampleslen;
return;
}
}
soundTimeCounter--;
if(!soundTimeCounter)
{
soundTimeCounter = 5;
if(curAlSound != alSound)
{
curAlSound = curAlSoundPtr = alSound;
curAlLengthLeft = alLengthLeft;
}
if(curAlSound)
{
if(*curAlSoundPtr)
{
alOut(alFreqL, *curAlSoundPtr);
alOut(alFreqH, alBlock);
}
else alOut(alFreqH, 0);
curAlSoundPtr++;
curAlLengthLeft--;
if(!curAlLengthLeft)
{
curAlSound = alSound = 0;
SoundNumber = (soundnames) 0;
SoundPriority = 0;
alOut(alFreqH, 0);
}
}
}
if(sqActive)
{
do
{
if(sqHackTime > alTimeCount) break;
sqHackTime = alTimeCount + *(sqHackPtr+1);
alOut(*(byte *) sqHackPtr, *(((byte *) sqHackPtr)+1));
sqHackPtr += 2;
sqHackLen -= 4;
}
while(sqHackLen>0);
alTimeCount++;
if(!sqHackLen)
{
sqHackPtr = sqHack;
sqHackLen = sqHackSeqLen;
sqHackTime = 0;
alTimeCount = 0;
}
}
numreadysamples = samplesPerMusicTick;
}
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_Startup() - starts up the Sound Mgr
// Detects all additional sound hardware and installs my ISR
//
///////////////////////////////////////////////////////////////////////////
void
SD_Startup(void)
{
int i;
 
if (SD_Started)
return;
 
if(Mix_OpenAudio(param_samplerate, AUDIO_S16, 2, param_audiobuffer))
{
printf("Unable to open audio: %s\n", Mix_GetError());
return;
}
 
Mix_ReserveChannels(2); // reserve player and boss weapon channels
Mix_GroupChannels(2, MIX_CHANNELS-1, 1); // group remaining channels
 
// Init music
 
samplesPerMusicTick = param_samplerate / 700; // SDL_t0FastAsmService played at 700Hz
 
if(YM3812Init(1,3579545,param_samplerate))
{
printf("Unable to create virtual OPL!!\n");
}
 
for(i=1;i<0xf6;i++)
YM3812Write(0,i,0);
 
YM3812Write(0,1,0x20); // Set WSE=1
// YM3812Write(0,8,0); // Set CSM=0 & SEL=0 // already set in for statement
 
Mix_HookMusic(SDL_IMFMusicPlayer, 0);
Mix_ChannelFinished(SD_ChannelFinished);
AdLibPresent = true;
SoundBlasterPresent = true;
 
alTimeCount = 0;
 
SD_SetSoundMode(sdm_Off);
SD_SetMusicMode(smm_Off);
 
SDL_SetupDigi();
 
SD_Started = true;
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_Shutdown() - shuts down the Sound Mgr
// Removes sound ISR and turns off whatever sound hardware was active
//
///////////////////////////////////////////////////////////////////////////
void
SD_Shutdown(void)
{
if (!SD_Started)
return;
 
SD_MusicOff();
SD_StopSound();
 
for(int i = 0; i < STARTMUSIC - STARTDIGISOUNDS; i++)
{
if(SoundChunks[i]) Mix_FreeChunk(SoundChunks[i]);
if(SoundBuffers[i]) free(SoundBuffers[i]);
}
 
free(DigiList);
 
SD_Started = false;
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_PositionSound() - Sets up a stereo imaging location for the next
// sound to be played. Each channel ranges from 0 to 15.
//
///////////////////////////////////////////////////////////////////////////
void
SD_PositionSound(int leftvol,int rightvol)
{
LeftPosition = leftvol;
RightPosition = rightvol;
nextsoundpos = true;
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_PlaySound() - plays the specified sound on the appropriate hardware
//
///////////////////////////////////////////////////////////////////////////
boolean
SD_PlaySound(soundnames sound)
{
boolean ispos;
SoundCommon *s;
int lp,rp;
 
lp = LeftPosition;
rp = RightPosition;
LeftPosition = 0;
RightPosition = 0;
 
ispos = nextsoundpos;
nextsoundpos = false;
 
if (sound == -1 || (DigiMode == sds_Off && SoundMode == sdm_Off))
return 0;
 
s = (SoundCommon *) SoundTable[sound];
 
if ((SoundMode != sdm_Off) && !s)
Quit("SD_PlaySound() - Uncached sound");
 
if ((DigiMode != sds_Off) && (DigiMap[sound] != -1))
{
if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))
{
#ifdef NOTYET
if (s->priority < SoundPriority)
return 0;
 
SDL_PCStopSound();
 
SD_PlayDigitized(DigiMap[sound],lp,rp);
SoundPositioned = ispos;
SoundNumber = sound;
SoundPriority = s->priority;
#else
return 0;
#endif
}
else
{
#ifdef NOTYET
if (s->priority < DigiPriority)
return(false);
#endif
 
int channel = SD_PlayDigitized(DigiMap[sound], lp, rp);
SoundPositioned = ispos;
DigiNumber = sound;
DigiPriority = s->priority;
return channel + 1;
}
 
return(true);
}
 
if (SoundMode == sdm_Off)
return 0;
 
if (!s->length)
Quit("SD_PlaySound() - Zero length sound");
if (s->priority < SoundPriority)
return 0;
 
switch (SoundMode)
{
case sdm_PC:
// SDL_PCPlaySound((PCSound *)s);
break;
case sdm_AdLib:
SDL_ALPlaySound((AdLibSound *)s);
break;
}
 
SoundNumber = sound;
SoundPriority = s->priority;
 
return 0;
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_SoundPlaying() - returns the sound number that's playing, or 0 if
// no sound is playing
//
///////////////////////////////////////////////////////////////////////////
 
word
SD_SoundPlaying(void)
{
boolean result = false;
 
switch (SoundMode)
{
case sdm_PC:
result = pcSound? true : false;
break;
case sdm_AdLib:
result = alSound? true : false;
break;
}
 
if (result)
return(SoundNumber);
else
return(false);
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_StopSound() - if a sound is playing, stops it
//
///////////////////////////////////////////////////////////////////////////
void
SD_StopSound(void)
{
if (DigiPlaying)
SD_StopDigitized();
 
switch (SoundMode)
{
case sdm_PC:
// SDL_PCStopSound();
break;
case sdm_AdLib:
SDL_ALStopSound();
break;
}
 
SoundPositioned = false;
 
SDL_SoundFinished();
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_WaitSoundDone() - waits until the current sound is done playing
//
///////////////////////////////////////////////////////////////////////////
void
SD_WaitSoundDone(void)
{
while (SD_SoundPlaying())
SDL_Delay(5);
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_MusicOn() - turns on the sequencer
//
///////////////////////////////////////////////////////////////////////////
void
SD_MusicOn(void)
{
sqActive = true;
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_MusicOff() - turns off the sequencer and any playing notes
// returns the last music offset for music continue
//
///////////////////////////////////////////////////////////////////////////
int
SD_MusicOff(void)
{
word i;
 
sqActive = false;
switch (MusicMode)
{
case smm_AdLib:
alOut(alEffects, 0);
for (i = 0;i < sqMaxTracks;i++)
alOut(alFreqH + i + 1, 0);
break;
}
 
return (int) (sqHackPtr-sqHack);
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_StartMusic() - starts playing the music pointed to
//
///////////////////////////////////////////////////////////////////////////
void
SD_StartMusic(int chunk)
{
SD_MusicOff();
 
if (MusicMode == smm_AdLib)
{
int32_t chunkLen = CA_CacheAudioChunk(chunk);
sqHack = (word *)(void *) audiosegs[chunk]; // alignment is correct
if(*sqHack == 0) sqHackLen = sqHackSeqLen = chunkLen;
else sqHackLen = sqHackSeqLen = *sqHack++;
sqHackPtr = sqHack;
sqHackTime = 0;
alTimeCount = 0;
SD_MusicOn();
}
}
 
void
SD_ContinueMusic(int chunk, int startoffs)
{
SD_MusicOff();
 
if (MusicMode == smm_AdLib)
{
int32_t chunkLen = CA_CacheAudioChunk(chunk);
sqHack = (word *)(void *) audiosegs[chunk]; // alignment is correct
if(*sqHack == 0) sqHackLen = sqHackSeqLen = chunkLen;
else sqHackLen = sqHackSeqLen = *sqHack++;
sqHackPtr = sqHack;
 
if(startoffs >= sqHackLen)
{
Quit("SD_StartMusic: Illegal startoffs provided!");
}
 
// fast forward to correct position
// (needed to reconstruct the instruments)
 
for(int i = 0; i < startoffs; i += 2)
{
byte reg = *(byte *)sqHackPtr;
byte val = *(((byte *)sqHackPtr) + 1);
if(reg >= 0xb1 && reg <= 0xb8) val &= 0xdf; // disable play note flag
else if(reg == 0xbd) val &= 0xe0; // disable drum flags
 
alOut(reg,val);
sqHackPtr += 2;
sqHackLen -= 4;
}
sqHackTime = 0;
alTimeCount = 0;
 
SD_MusicOn();
}
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying()
// to see if the fadeout is complete
//
///////////////////////////////////////////////////////////////////////////
void
SD_FadeOutMusic(void)
{
switch (MusicMode)
{
case smm_AdLib:
// DEBUG - quick hack to turn the music off
SD_MusicOff();
break;
}
}
 
///////////////////////////////////////////////////////////////////////////
//
// SD_MusicPlaying() - returns true if music is currently playing, false if
// not
//
///////////////////////////////////////////////////////////////////////////
boolean
SD_MusicPlaying(void)
{
boolean result;
 
switch (MusicMode)
{
case smm_AdLib:
result = sqActive;
break;
default:
result = false;
break;
}
 
return(result);
}
/contrib/games/wolf3d/id_sd.h
8,7 → 8,7
#ifndef __ID_SD__
#define __ID_SD__
 
#define alOut(n,b) YM3812Write(oplChip, n, b)
#define alOut(n,b) YM3812Write(0, n, b)
 
#define TickBase 70 // 70Hz per tick - used as a base for timer 0
 
107,7 → 107,7
fixed globalsoundx, globalsoundy;
} globalsoundpos;
 
extern int channelSoundPos[];
extern globalsoundpos channelSoundPos[];
 
// Global variables
extern boolean AdLibPresent,
/contrib/games/wolf3d/wl_inter.cpp
2,7 → 2,7
 
#include "wl_def.h"
#pragma hdrstop
 
#define itoa ltoa
LRstruct LevelRatios[LRpack];
int32_t lastBreathTime = 0;
 
/contrib/games/wolf3d/wl_main.cpp
1210,11 → 1210,12
#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,7 → 1233,9
#endif
SignonScreen ();
#ifdef _KOLIBRI
kolibri_set_win_center();
#endif
#if defined _WIN32
if(!fullscreen)
1886,6 → 1889,9
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
" --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
" --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"