diff --git a/polymer/eduke32/source/jaudiolib/Makefile b/polymer/eduke32/source/jaudiolib/Makefile new file mode 100644 index 000000000..1e025e339 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/Makefile @@ -0,0 +1,47 @@ +CC=gcc +OBJ=obj +OBJNAME?=libjfaudiolib.a +PRETTY_OUTPUT?=1 +EROOT?=build +SRC=src + +include ../../$(EROOT)/Makefile.shared + +CFLAGS=-g -O2 -Wall +CPPFLAGS=-Iinclude -Isrc -DHAVE_VORBIS + +OBJECTS=$(OBJ)/drivers.o \ + $(OBJ)/fx_man.o \ + $(OBJ)/multivoc.o \ + $(OBJ)/mix.o \ + $(OBJ)/mixst.o \ + $(OBJ)/pitch.o \ + $(OBJ)/vorbis.o \ + $(OBJ)/driver_nosound.o + +ifeq ($(PLATFORM),WINDOWS) + CPPFLAGS+= -I/z/sdks/directx/dx7/include -Ithird-party/mingw32/include + OBJECTS+= $(OBJ)/driver_directsound.o + OBJNAME=libjfaudiolib_win32.a + OBJ=obj_win +else + CPPFLAGS+= -DHAVE_SDL + OBJECTS+= $(OBJ)/driver_sdl.o +endif + +# OBJECTS=$(SOURCES:%.c=$(OBJ)/%.o) + +$(OBJNAME): $(OBJECTS) + ar cr $@ $^ + +$(OBJECTS): $(OBJ)/%.o: $(SRC)/%.c + -mkdir -p $(OBJ) + $(COMPILE_STATUS) + if $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@; then $(COMPILE_OK); else $(COMPILE_FAILED); fi + +ifeq ($(PRETTY_OUTPUT),1) +.SILENT: +endif +.PHONY: clean +clean: + -rm -f $(OBJECTS) $(OBJNAME) diff --git a/polymer/eduke32/source/jaudiolib/include/fx_man.h b/polymer/eduke32/source/jaudiolib/include/fx_man.h new file mode 100644 index 000000000..161ed3159 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/include/fx_man.h @@ -0,0 +1,113 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/********************************************************************** + module: FX_MAN.H + + author: James R. Dose + date: March 17, 1994 + + Public header for FX_MAN.C + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __FX_MAN_H +#define __FX_MAN_H + +#include "inttypes.h" +#include "limits.h" +#include "sndcards.h" + +enum FX_ERRORS + { + FX_Warning = -2, + FX_Error = -1, + FX_Ok = 0, + FX_ASSVersion, + FX_SoundCardError, + FX_InvalidCard, + FX_MultiVocError, + }; + +#define FX_MUSIC_PRIORITY INT_MAX + +const char *FX_ErrorString( int32_t ErrorNumber ); +int32_t FX_Init( int32_t SoundCard, int32_t numvoices, int32_t numchannels, int32_t samplebits, unsigned mixrate, void * initdata ); +int32_t FX_Shutdown( void ); +int32_t FX_SetCallBack( void ( *function )( uint32_t ) ); +void FX_SetVolume( int32_t volume ); +int32_t FX_GetVolume( void ); + +void FX_SetReverseStereo( int32_t setting ); +int32_t FX_GetReverseStereo( void ); +void FX_SetReverb( int32_t reverb ); +void FX_SetFastReverb( int32_t reverb ); +int32_t FX_GetMaxReverbDelay( void ); +int32_t FX_GetReverbDelay( void ); +void FX_SetReverbDelay( int32_t delay ); + +int32_t FX_PauseVoice ( int32_t handle, int32_t pause ); +int32_t FX_VoiceAvailable( int32_t priority ); +int32_t FX_EndLooping( int32_t handle ); +int32_t FX_SetPan( int32_t handle, int32_t vol, int32_t left, int32_t right ); +int32_t FX_SetPitch( int32_t handle, int32_t pitchoffset ); +int32_t FX_SetFrequency( int32_t handle, int32_t frequency ); + +int32_t FX_PlayVOC( char *ptr, uint32_t ptrlength, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, + int32_t priority, uint32_t callbackval ); +int32_t FX_PlayLoopedVOC( char *ptr, uint32_t ptrlength, int32_t loopstart, int32_t loopend, + int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority, + uint32_t callbackval ); +int32_t FX_PlayWAV( char *ptr, uint32_t ptrlength, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, + int32_t priority, uint32_t callbackval ); +int32_t FX_PlayLoopedWAV( char *ptr, uint32_t ptrlength, int32_t loopstart, int32_t loopend, + int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority, + uint32_t callbackval ); +int32_t FX_PlayVOC3D( char *ptr, uint32_t ptrlength, int32_t pitchoffset, int32_t angle, int32_t distance, + int32_t priority, uint32_t callbackval ); +int32_t FX_PlayWAV3D( char *ptr, uint32_t ptrlength, int32_t pitchoffset, int32_t angle, int32_t distance, + int32_t priority, uint32_t callbackval ); + +int32_t FX_PlayAuto( char *ptr, uint32_t ptrlength, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, + int32_t priority, uint32_t callbackval ); +int32_t FX_PlayLoopedAuto( char *ptr, uint32_t ptrlength, int32_t loopstart, int32_t loopend, + int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority, + uint32_t callbackval ); +int32_t FX_PlayAuto3D( char *ptr, uint32_t ptrlength, int32_t pitchoffset, int32_t angle, int32_t distance, + int32_t priority, uint32_t callbackval ); + +int32_t FX_PlayRaw( char *ptr, uint32_t length, unsigned rate, + int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority, + uint32_t callbackval ); +int32_t FX_PlayLoopedRaw( char *ptr, uint32_t length, char *loopstart, + char *loopend, unsigned rate, int32_t pitchoffset, int32_t vol, int32_t left, + int32_t right, int32_t priority, uint32_t callbackval ); +int32_t FX_Pan3D( int32_t handle, int32_t angle, int32_t distance ); +int32_t FX_SoundActive( int32_t handle ); +int32_t FX_SoundsPlaying( void ); +int32_t FX_StopSound( int32_t handle ); +int32_t FX_StopAllSounds( void ); +int32_t FX_StartDemandFeedPlayback( void ( *function )( char **ptr, uint32_t *length ), + int32_t rate, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, + int32_t priority, uint32_t callbackval ); +int32_t FX_StartRecording( int32_t MixRate, void ( *function )( char *ptr, int32_t length ) ); +void FX_StopRecord( void ); + +#endif diff --git a/polymer/eduke32/source/jaudiolib/include/music.h b/polymer/eduke32/source/jaudiolib/include/music.h new file mode 100644 index 000000000..56942790d --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/include/music.h @@ -0,0 +1,93 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/********************************************************************** + module: MUSIC.H + + author: James R. Dose + date: March 25, 1994 + + Public header for MUSIC.C + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __MUSIC_H +#define __MUSIC_H + +#include "inttypes.h" +#include "sndcards.h" + +extern int32_t MUSIC_ErrorCode; + +enum MUSIC_ERRORS + { + MUSIC_Warning = -2, + MUSIC_Error = -1, + MUSIC_Ok = 0, + MUSIC_ASSVersion, + MUSIC_SoundCardError, + MUSIC_MPU401Error, + MUSIC_InvalidCard, + MUSIC_MidiError, + MUSIC_TaskManError, + MUSIC_FMNotDetected, + MUSIC_DPMI_Error + }; + +typedef struct + { + uint32_t tickposition; + uint32_t milliseconds; + uint32_t measure; + uint32_t beat; + uint32_t tick; + } songposition; + +#define MUSIC_LoopSong ( 1 == 1 ) +#define MUSIC_PlayOnce ( !MUSIC_LoopSong ) + +char *MUSIC_ErrorString( int32_t ErrorNumber ); +int32_t MUSIC_Init( int32_t SoundCard, int32_t Address ); +int32_t MUSIC_Shutdown( void ); +void MUSIC_SetMaxFMMidiChannel( int32_t channel ); +void MUSIC_SetVolume( int32_t volume ); +void MUSIC_SetMidiChannelVolume( int32_t channel, int32_t volume ); +void MUSIC_ResetMidiChannelVolumes( void ); +int32_t MUSIC_GetVolume( void ); +void MUSIC_SetLoopFlag( int32_t loopflag ); +int32_t MUSIC_SongPlaying( void ); +void MUSIC_Continue( void ); +void MUSIC_Pause( void ); +int32_t MUSIC_StopSong( void ); +int32_t MUSIC_PlaySong( uint8_t *song, int32_t loopflag ); +void MUSIC_SetContext( int32_t context ); +int32_t MUSIC_GetContext( void ); +void MUSIC_SetSongTick( uint32_t PositionInTicks ); +void MUSIC_SetSongTime( uint32_t milliseconds ); +void MUSIC_SetSongPosition( int32_t measure, int32_t beat, int32_t tick ); +void MUSIC_GetSongPosition( songposition *pos ); +void MUSIC_GetSongLength( songposition *pos ); +int32_t MUSIC_FadeVolume( int32_t tovolume, int32_t milliseconds ); +int32_t MUSIC_FadeActive( void ); +void MUSIC_StopFade( void ); +void MUSIC_RerouteMidiChannel( int32_t channel, int32_t ( *function )( int32_t event, int32_t c1, int32_t c2 ) ); +void MUSIC_RegisterTimbreBank( uint8_t *timbres ); + +#endif diff --git a/polymer/eduke32/source/jaudiolib/include/sndcards.h b/polymer/eduke32/source/jaudiolib/include/sndcards.h new file mode 100644 index 000000000..31cd6a858 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/include/sndcards.h @@ -0,0 +1,46 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/********************************************************************** + module: SNDCARDS.H + + author: James R. Dose + date: March 31, 1994 + + Contains enumerated type definitions for sound cards. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __SNDCARDS_H +#define __SNDCARDS_H + +#define ASS_VERSION_STRING "JonoF 20090718" + +typedef enum + { + ASS_NoSound, + ASS_SDL, + ASS_CoreAudio, + ASS_DirectSound, + ASS_NumSoundCards, + ASS_AutoDetect = -2 + } soundcardnames; + +#endif diff --git a/polymer/eduke32/source/jaudiolib/jfaudiolib.xcodeproj/project.pbxproj b/polymer/eduke32/source/jaudiolib/jfaudiolib.xcodeproj/project.pbxproj new file mode 100644 index 000000000..88ded1e65 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/jfaudiolib.xcodeproj/project.pbxproj @@ -0,0 +1,307 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + AB2E9E5F1011E65900DD2F1F /* _multivc.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E4D1011E65900DD2F1F /* _multivc.h */; }; + AB2E9E601011E65900DD2F1F /* driver_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2E9E4E1011E65900DD2F1F /* driver_coreaudio.c */; }; + AB2E9E611011E65900DD2F1F /* driver_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E4F1011E65900DD2F1F /* driver_coreaudio.h */; }; + AB2E9E641011E65900DD2F1F /* driver_nosound.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2E9E521011E65900DD2F1F /* driver_nosound.c */; }; + AB2E9E651011E65900DD2F1F /* driver_nosound.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E531011E65900DD2F1F /* driver_nosound.h */; }; + AB2E9E681011E65900DD2F1F /* drivers.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2E9E561011E65900DD2F1F /* drivers.c */; }; + AB2E9E691011E65900DD2F1F /* drivers.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E571011E65900DD2F1F /* drivers.h */; }; + AB2E9E6A1011E65900DD2F1F /* fx_man.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2E9E581011E65900DD2F1F /* fx_man.c */; }; + AB2E9E6B1011E65900DD2F1F /* linklist.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E591011E65900DD2F1F /* linklist.h */; }; + AB2E9E6C1011E65900DD2F1F /* ll_man.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E5A1011E65900DD2F1F /* ll_man.h */; }; + AB2E9E6D1011E65900DD2F1F /* multivoc.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2E9E5B1011E65900DD2F1F /* multivoc.c */; }; + AB2E9E6E1011E65900DD2F1F /* multivoc.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E5C1011E65900DD2F1F /* multivoc.h */; }; + AB2E9E6F1011E65900DD2F1F /* pitch.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2E9E5D1011E65900DD2F1F /* pitch.c */; }; + AB2E9E701011E65900DD2F1F /* pitch.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E5E1011E65900DD2F1F /* pitch.h */; }; + AB2E9E741011E66100DD2F1F /* fx_man.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E711011E66100DD2F1F /* fx_man.h */; }; + AB2E9E751011E66100DD2F1F /* music.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E721011E66100DD2F1F /* music.h */; }; + AB2E9E761011E66100DD2F1F /* sndcards.h in Headers */ = {isa = PBXBuildFile; fileRef = AB2E9E731011E66100DD2F1F /* sndcards.h */; }; + AB2EA0831012029200DD2F1F /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB2EA0821012029200DD2F1F /* AudioUnit.framework */; }; + AB2EA17710121AA900DD2F1F /* mix.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2EA17610121AA900DD2F1F /* mix.c */; }; + AB8C5612101A077700B42306 /* mixst.c in Sources */ = {isa = PBXBuildFile; fileRef = AB8C5611101A077700B42306 /* mixst.c */; }; + AB8C5828101B6B7100B42306 /* ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C5826101B6B7100B42306 /* ogg.framework */; }; + AB8C5829101B6B7100B42306 /* vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C5827101B6B7100B42306 /* vorbis.framework */; }; + AB8C5868101B6D7500B42306 /* vorbis.c in Sources */ = {isa = PBXBuildFile; fileRef = AB8C5867101B6D7500B42306 /* vorbis.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + AB2E9E421011E61700DD2F1F /* libjfaudiolib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjfaudiolib.a; sourceTree = BUILT_PRODUCTS_DIR; }; + AB2E9E4D1011E65900DD2F1F /* _multivc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _multivc.h; sourceTree = ""; }; + AB2E9E4E1011E65900DD2F1F /* driver_coreaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = driver_coreaudio.c; sourceTree = ""; }; + AB2E9E4F1011E65900DD2F1F /* driver_coreaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = driver_coreaudio.h; sourceTree = ""; }; + AB2E9E521011E65900DD2F1F /* driver_nosound.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = driver_nosound.c; sourceTree = ""; }; + AB2E9E531011E65900DD2F1F /* driver_nosound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = driver_nosound.h; sourceTree = ""; }; + AB2E9E561011E65900DD2F1F /* drivers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = drivers.c; sourceTree = ""; }; + AB2E9E571011E65900DD2F1F /* drivers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = drivers.h; sourceTree = ""; }; + AB2E9E581011E65900DD2F1F /* fx_man.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fx_man.c; sourceTree = ""; }; + AB2E9E591011E65900DD2F1F /* linklist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linklist.h; sourceTree = ""; }; + AB2E9E5A1011E65900DD2F1F /* ll_man.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ll_man.h; sourceTree = ""; }; + AB2E9E5B1011E65900DD2F1F /* multivoc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = multivoc.c; sourceTree = ""; }; + AB2E9E5C1011E65900DD2F1F /* multivoc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multivoc.h; sourceTree = ""; }; + AB2E9E5D1011E65900DD2F1F /* pitch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pitch.c; sourceTree = ""; }; + AB2E9E5E1011E65900DD2F1F /* pitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pitch.h; sourceTree = ""; }; + AB2E9E711011E66100DD2F1F /* fx_man.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fx_man.h; sourceTree = ""; }; + AB2E9E721011E66100DD2F1F /* music.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music.h; sourceTree = ""; }; + AB2E9E731011E66100DD2F1F /* sndcards.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sndcards.h; sourceTree = ""; }; + AB2EA0821012029200DD2F1F /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = ""; }; + AB2EA17610121AA900DD2F1F /* mix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mix.c; sourceTree = ""; }; + AB8C5611101A077700B42306 /* mixst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mixst.c; sourceTree = ""; }; + AB8C5826101B6B7100B42306 /* ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ogg.framework; path = "third-party/ogg.framework"; sourceTree = ""; }; + AB8C5827101B6B7100B42306 /* vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = vorbis.framework; path = "third-party/vorbis.framework"; sourceTree = ""; }; + AB8C5867101B6D7500B42306 /* vorbis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vorbis.c; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + AB2E9E401011E61600DD2F1F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AB2EA0831012029200DD2F1F /* AudioUnit.framework in Frameworks */, + AB8C5828101B6B7100B42306 /* ogg.framework in Frameworks */, + AB8C5829101B6B7100B42306 /* vorbis.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + AB2E9E301011E60300DD2F1F = { + isa = PBXGroup; + children = ( + AB8C582E101B6B7900B42306 /* Linked frameworks */, + AB2E9E481011E63F00DD2F1F /* include */, + AB2E9E471011E63900DD2F1F /* src */, + AB2E9E431011E61700DD2F1F /* Products */, + ); + sourceTree = ""; + }; + AB2E9E431011E61700DD2F1F /* Products */ = { + isa = PBXGroup; + children = ( + AB2E9E421011E61700DD2F1F /* libjfaudiolib.a */, + ); + name = Products; + sourceTree = ""; + }; + AB2E9E471011E63900DD2F1F /* src */ = { + isa = PBXGroup; + children = ( + AB2E9E4D1011E65900DD2F1F /* _multivc.h */, + AB2E9E4E1011E65900DD2F1F /* driver_coreaudio.c */, + AB2E9E4F1011E65900DD2F1F /* driver_coreaudio.h */, + AB2E9E521011E65900DD2F1F /* driver_nosound.c */, + AB2E9E531011E65900DD2F1F /* driver_nosound.h */, + AB2E9E561011E65900DD2F1F /* drivers.c */, + AB2E9E571011E65900DD2F1F /* drivers.h */, + AB2E9E581011E65900DD2F1F /* fx_man.c */, + AB2E9E591011E65900DD2F1F /* linklist.h */, + AB2E9E5A1011E65900DD2F1F /* ll_man.h */, + AB2E9E5B1011E65900DD2F1F /* multivoc.c */, + AB2E9E5C1011E65900DD2F1F /* multivoc.h */, + AB2E9E5D1011E65900DD2F1F /* pitch.c */, + AB2E9E5E1011E65900DD2F1F /* pitch.h */, + AB2EA17610121AA900DD2F1F /* mix.c */, + AB8C5611101A077700B42306 /* mixst.c */, + AB8C5867101B6D7500B42306 /* vorbis.c */, + ); + path = src; + sourceTree = ""; + }; + AB2E9E481011E63F00DD2F1F /* include */ = { + isa = PBXGroup; + children = ( + AB2E9E711011E66100DD2F1F /* fx_man.h */, + AB2E9E721011E66100DD2F1F /* music.h */, + AB2E9E731011E66100DD2F1F /* sndcards.h */, + ); + path = include; + sourceTree = ""; + }; + AB8C582E101B6B7900B42306 /* Linked frameworks */ = { + isa = PBXGroup; + children = ( + AB2EA0821012029200DD2F1F /* AudioUnit.framework */, + AB8C5827101B6B7100B42306 /* vorbis.framework */, + AB8C5826101B6B7100B42306 /* ogg.framework */, + ); + name = "Linked frameworks"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + AB2E9E3E1011E61600DD2F1F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + AB2E9E5F1011E65900DD2F1F /* _multivc.h in Headers */, + AB2E9E611011E65900DD2F1F /* driver_coreaudio.h in Headers */, + AB2E9E651011E65900DD2F1F /* driver_nosound.h in Headers */, + AB2E9E691011E65900DD2F1F /* drivers.h in Headers */, + AB2E9E6B1011E65900DD2F1F /* linklist.h in Headers */, + AB2E9E6C1011E65900DD2F1F /* ll_man.h in Headers */, + AB2E9E6E1011E65900DD2F1F /* multivoc.h in Headers */, + AB2E9E701011E65900DD2F1F /* pitch.h in Headers */, + AB2E9E741011E66100DD2F1F /* fx_man.h in Headers */, + AB2E9E751011E66100DD2F1F /* music.h in Headers */, + AB2E9E761011E66100DD2F1F /* sndcards.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + AB2E9E411011E61600DD2F1F /* jfaudiolib */ = { + isa = PBXNativeTarget; + buildConfigurationList = AB2E9E441011E61900DD2F1F /* Build configuration list for PBXNativeTarget "jfaudiolib" */; + buildPhases = ( + AB2E9E3E1011E61600DD2F1F /* Headers */, + AB2E9E3F1011E61600DD2F1F /* Sources */, + AB2E9E401011E61600DD2F1F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = jfaudiolib; + productName = jfaudiolib; + productReference = AB2E9E421011E61700DD2F1F /* libjfaudiolib.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + AB2E9E321011E60300DD2F1F /* Project object */ = { + isa = PBXProject; + buildConfigurationList = AB2E9E331011E60300DD2F1F /* Build configuration list for PBXProject "jfaudiolib" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 0; + mainGroup = AB2E9E301011E60300DD2F1F; + productRefGroup = AB2E9E431011E61700DD2F1F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + AB2E9E411011E61600DD2F1F /* jfaudiolib */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + AB2E9E3F1011E61600DD2F1F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AB2E9E601011E65900DD2F1F /* driver_coreaudio.c in Sources */, + AB2E9E641011E65900DD2F1F /* driver_nosound.c in Sources */, + AB2E9E681011E65900DD2F1F /* drivers.c in Sources */, + AB2E9E6A1011E65900DD2F1F /* fx_man.c in Sources */, + AB2E9E6D1011E65900DD2F1F /* multivoc.c in Sources */, + AB2E9E6F1011E65900DD2F1F /* pitch.c in Sources */, + AB2EA17710121AA900DD2F1F /* mix.c in Sources */, + AB8C5612101A077700B42306 /* mixst.c in Sources */, + AB8C5868101B6D7500B42306 /* vorbis.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + AB2E9E341011E60300DD2F1F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = "third-party"; + GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__; + GCC_VERSION_i386 = 4.0; + GCC_VERSION_ppc = 4.0; + MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.3; + SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT_ppc = /Developer/SDKs/MacOSX10.3.9.sdk; + }; + name = Debug; + }; + AB2E9E351011E60300DD2F1F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = "third-party"; + GCC_PREPROCESSOR_DEFINITIONS = __MACOSX__; + GCC_VERSION_i386 = 4.0; + GCC_VERSION_ppc = 4.0; + MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.3; + SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT_ppc = /Developer/SDKs/MacOSX10.3.9.sdk; + }; + name = Release; + }; + AB2E9E451011E61900DD2F1F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + PREBINDING = NO; + PRODUCT_NAME = jfaudiolib; + ZERO_LINK = YES; + }; + name = Debug; + }; + AB2E9E461011E61900DD2F1F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + PREBINDING = NO; + PRODUCT_NAME = jfaudiolib; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + AB2E9E331011E60300DD2F1F /* Build configuration list for PBXProject "jfaudiolib" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AB2E9E341011E60300DD2F1F /* Debug */, + AB2E9E351011E60300DD2F1F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + AB2E9E441011E61900DD2F1F /* Build configuration list for PBXNativeTarget "jfaudiolib" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AB2E9E451011E61900DD2F1F /* Debug */, + AB2E9E461011E61900DD2F1F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = AB2E9E321011E60300DD2F1F /* Project object */; +} diff --git a/polymer/eduke32/source/jaudiolib/src/_multivc.h b/polymer/eduke32/source/jaudiolib/src/_multivc.h new file mode 100644 index 000000000..d05675f78 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/_multivc.h @@ -0,0 +1,320 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/********************************************************************** + file: _MULTIVC.H + + author: James R. Dose + date: December 20, 1993 + + Private header for MULTIVOC.C + + (c) Copyright 1993 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#include "limits.h" +#include "inttypes.h" + +#ifndef ___MULTIVC_H +#define ___MULTIVC_H + +#define TRUE ( 1 == 1 ) +#define FALSE ( !TRUE ) + +#define VOC_8BIT 0x0 +#define VOC_CT4_ADPCM 0x1 +#define VOC_CT3_ADPCM 0x2 +#define VOC_CT2_ADPCM 0x3 +#define VOC_16BIT 0x4 +#define VOC_ALAW 0x6 +#define VOC_MULAW 0x7 +#define VOC_CREATIVE_ADPCM 0x200 + +#define T_SIXTEENBIT_STEREO 0 +#define T_8BITS 1 +#define T_MONO 2 +#define T_16BITSOURCE 4 +#define T_STEREOSOURCE 8 +#define T_LEFTQUIET 16 +#define T_RIGHTQUIET 32 +#define T_DEFAULT T_SIXTEENBIT_STEREO + +#define MV_MaxPanPosition 127 +#define MV_NumPanPositions ( MV_MaxPanPosition + 1 ) +#define MV_MaxTotalVolume 255 +//#define MV_MaxVolume 63 +#define MV_NumVoices 8 + +// mirrors FX_MUSIC_PRIORITY from fx_man.h +#define MV_MUSIC_PRIORITY INT_MAX + +#define MIX_VOLUME( volume ) \ + ( ( max( 0, min( ( volume ), 255 ) ) * ( MV_MaxVolume + 1 ) ) >> 8 ) +// ( ( max( 0, min( ( volume ), 255 ) ) ) >> 2 ) + +#define STEREO 1 +#define SIXTEEN_BIT 2 + +#define MONO_8BIT 0 +#define STEREO_8BIT ( STEREO ) +#define MONO_16BIT ( SIXTEEN_BIT ) +#define STEREO_16BIT ( STEREO | SIXTEEN_BIT ) + +#define MONO_8BIT_SAMPLE_SIZE 1 +#define MONO_16BIT_SAMPLE_SIZE 2 +#define STEREO_8BIT_SAMPLE_SIZE ( 2 * MONO_8BIT_SAMPLE_SIZE ) +#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE ) + +//#define SILENCE_16BIT 0x80008000 +#define SILENCE_16BIT 0 +#define SILENCE_8BIT 0x80808080 +//#define SILENCE_16BIT_PAS 0 + +#define MixBufferSize 256 + +#define NumberOfBuffers 16 +#define TotalBufferSize ( MixBufferSize * NumberOfBuffers ) + +#define PI 3.1415926536 + +typedef enum + { + Raw, + VOC, + DemandFeed, + WAV, + Vorbis + } wavedata; + +typedef enum + { + NoMoreData, + KeepPlaying + } playbackstatus; + + +typedef struct VoiceNode + { + struct VoiceNode *next; + struct VoiceNode *prev; + + wavedata wavetype; + char bits; + char channels; + + playbackstatus ( *GetSound )( struct VoiceNode *voice ); + + void ( *mix )( uint32_t position, uint32_t rate, + char *start, uint32_t length ); + + char *NextBlock; + char *LoopStart; + char *LoopEnd; + unsigned LoopCount; + uint32_t LoopSize; + uint32_t BlockLength; + + uint32_t PitchScale; + uint32_t FixedPointBufferSize; + + char *sound; + uint32_t length; + uint32_t SamplingRate; + uint32_t RateScale; + uint32_t position; + int32_t Playing; + int32_t Paused; + + int32_t handle; + int32_t priority; + + void ( *DemandFeed )( char **ptr, uint32_t *length ); + void *extra; + + int16_t *LeftVolume; + int16_t *RightVolume; + + uint32_t callbackval; + + } VoiceNode; + +typedef struct + { + VoiceNode *start; + VoiceNode *end; + } VList; + +typedef struct + { + uint8_t left; + uint8_t right; + } Pan; + +typedef int16_t MONO16; +typedef int8_t MONO8; + +typedef struct + { + MONO16 left; + MONO16 right; +// uint16_t left; +// uint16_t right; + } STEREO16; + +typedef struct + { + MONO16 left; + MONO16 right; + } SIGNEDSTEREO16; + +typedef struct + { +// MONO8 left; +// MONO8 right; + char left; + char right; + } STEREO8; + +typedef struct + { + char RIFF[ 4 ]; + uint32_t file_size; + char WAVE[ 4 ]; + char fmt[ 4 ]; + uint32_t format_size; + } riff_header; + +typedef struct + { + uint16_t wFormatTag; + uint16_t nChannels; + uint32_t nSamplesPerSec; + uint32_t nAvgBytesPerSec; + uint16_t nBlockAlign; + uint16_t nBitsPerSample; + } format_header; + +typedef struct + { + uint8_t DATA[ 4 ]; + uint32_t size; + } data_header; + +typedef MONO8 VOLUME8[ 256 ]; +typedef MONO16 VOLUME16[ 256 ]; + +extern Pan MV_PanTable[ MV_NumPanPositions ][ 255 + 1 ]; +extern int32_t MV_ErrorCode; +extern int32_t MV_Installed; +extern int32_t MV_MaxVolume; +extern int32_t MV_MixRate; +typedef char HARSH_CLIP_TABLE_8[ MV_NumVoices * 256 ]; + +#define MV_SetErrorCode( status ) \ + MV_ErrorCode = ( status ); + +static void MV_Mix( VoiceNode *voice, int32_t buffer ); +void MV_PlayVoice( VoiceNode *voice ); +static void MV_StopVoice( VoiceNode *voice ); +static void MV_ServiceVoc( void ); + +static playbackstatus MV_GetNextVOCBlock( VoiceNode *voice ); +static playbackstatus MV_GetNextDemandFeedBlock( VoiceNode *voice ); +static playbackstatus MV_GetNextRawBlock( VoiceNode *voice ); +static playbackstatus MV_GetNextWAVBlock( VoiceNode *voice ); +static playbackstatus MV_GetNextVorbisBlock( VoiceNode *voice ); + +static void MV_ServiceRecord( void ); +static VoiceNode *MV_GetVoice( int32_t handle ); +VoiceNode *MV_AllocVoice( int32_t priority ); + +static int16_t *MV_GetVolumeTable( int32_t vol ); + +void MV_SetVoiceMixMode( VoiceNode *voice ); +void MV_SetVoiceVolume ( VoiceNode *voice, int32_t vol, int32_t left, int32_t right ); + +static void MV_SetVoicePitch( VoiceNode *voice, uint32_t rate, int32_t pitchoffset ); +static void MV_CalcVolume( int32_t MaxLevel ); +static void MV_CalcPanTable( void ); + +void MV_ReleaseVorbisVoice( VoiceNode * voice ); + +// implemented in mix.c +void ClearBuffer_DW( void *ptr, unsigned data, int32_t length ); + +void MV_Mix8BitMono( uint32_t position, uint32_t rate, + char *start, uint32_t length ); + +void MV_Mix8BitStereo( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_Mix16BitMono( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_Mix16BitStereo( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_Mix16BitMono16( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_Mix8BitMono16( uint32_t position, uint32_t rate, + char *start, uint32_t length ); + +void MV_Mix8BitStereo16( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_Mix16BitStereo16( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_16BitReverb( char *src, char *dest, VOLUME16 *volume, int32_t count ); + +void MV_8BitReverb( int8_t *src, int8_t *dest, VOLUME16 *volume, int32_t count ); + +void MV_16BitReverbFast( char *src, char *dest, int32_t count, int32_t shift ); + +void MV_8BitReverbFast( int8_t *src, int8_t *dest, int32_t count, int32_t shift ); + +// implemented in mixst.c +void ClearBuffer_DW( void *ptr, unsigned data, int32_t length ); + +void MV_Mix8BitMono8Stereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ); + +void MV_Mix8BitStereo8Stereo( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_Mix16BitMono8Stereo( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_Mix16BitStereo8Stereo( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_Mix16BitMono16Stereo( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_Mix8BitMono16Stereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ); + +void MV_Mix8BitStereo16Stereo( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +void MV_Mix16BitStereo16Stereo( uint32_t position, + uint32_t rate, char *start, uint32_t length ); + +#endif diff --git a/polymer/eduke32/source/jaudiolib/src/driver_coreaudio.c b/polymer/eduke32/source/jaudiolib/src/driver_coreaudio.c new file mode 100644 index 000000000..6aee6ba24 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/driver_coreaudio.c @@ -0,0 +1,339 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +/** + * CoreAudio output driver for MultiVoc + * + * Inspired by the example set by the Audiere sound library available at + * https://audiere.svn.sourceforge.net/svnroot/audiere/trunk/audiere/ + * + */ + +#include +#include +#include "driver_coreaudio.h" + +enum { + CAErr_Warning = -2, + CAErr_Error = -1, + CAErr_Ok = 0, + CAErr_Uninitialised, + CAErr_FindNextComponent, + CAErr_OpenAComponent, + CAErr_AudioUnitInitialize, + CAErr_AudioUnitSetProperty, + CAErr_Mutex +}; + +static int32_t ErrorCode = CAErr_Ok; +static int32_t Initialised = 0; +static int32_t Playing = 0; +static ComponentInstance output_audio_unit; +static pthread_mutex_t mutex; + +static char *MixBuffer = 0; +static int32_t MixBufferSize = 0; +static int32_t MixBufferCount = 0; +static int32_t MixBufferCurrent = 0; +static int32_t MixBufferUsed = 0; +static void ( *MixCallBack )( void ) = 0; + +static OSStatus fillInput( + void *inRefCon, + AudioUnitRenderActionFlags inActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + AudioBuffer *ioData) +{ + UInt32 remaining, len; + char *ptr, *sptr; + + remaining = ioData->mDataByteSize; + ptr = ioData->mData; + + while (remaining > 0) { + if (MixBufferUsed == MixBufferSize) { + CoreAudioDrv_Lock(); + MixCallBack(); + CoreAudioDrv_Unlock(); + + MixBufferUsed = 0; + MixBufferCurrent++; + if (MixBufferCurrent >= MixBufferCount) { + MixBufferCurrent -= MixBufferCount; + } + } + + while (remaining > 0 && MixBufferUsed < MixBufferSize) { + sptr = MixBuffer + (MixBufferCurrent * MixBufferSize) + MixBufferUsed; + + len = MixBufferSize - MixBufferUsed; + if (remaining < len) { + len = remaining; + } + + memcpy(ptr, sptr, len); + + ptr += len; + MixBufferUsed += len; + remaining -= len; + } + } + + return noErr; +} + +int32_t CoreAudioDrv_GetError(void) +{ + return ErrorCode; +} + +const char *CoreAudioDrv_ErrorString( int32_t ErrorNumber ) +{ + const char *ErrorString; + + switch( ErrorNumber ) + { + case CAErr_Warning : + case CAErr_Error : + ErrorString = CoreAudioDrv_ErrorString( ErrorCode ); + break; + + case CAErr_Ok : + ErrorString = "CoreAudio ok."; + break; + + case CAErr_Uninitialised: + ErrorString = "CoreAudio uninitialised."; + break; + + case CAErr_FindNextComponent: + ErrorString = "CoreAudio error: FindNextComponent returned NULL."; + break; + + case CAErr_OpenAComponent: + ErrorString = "CoreAudio error: OpenAComponent failed."; + break; + + case CAErr_AudioUnitInitialize: + ErrorString = "CoreAudio error: AudioUnitInitialize failed."; + break; + + case CAErr_AudioUnitSetProperty: + ErrorString = "CoreAudio error: AudioUnitSetProperty failed."; + break; + + case CAErr_Mutex: + ErrorString = "CoreAudio error: could not initialise mutex."; + break; + + default: + ErrorString = "Unknown CoreAudio error code."; + break; + } + + return ErrorString; +} + +/* +int32_t CoreAudioDrv_InitMIDI() +{ + AudioStreamBasicDescription requestedDesc; + + requestedDesc.mFormatID = kAudioFormatMIDIStream; +} + */ + +int32_t CoreAudioDrv_Init(int32_t mixrate, int32_t numchannels, int32_t samplebits, void * initdata) +{ + OSStatus result = noErr; + Component comp; + ComponentDescription desc; + AudioStreamBasicDescription requestedDesc; + struct AudioUnitInputCallback callback; + + if (Initialised) { + CoreAudioDrv_Shutdown(); + } + + if (pthread_mutex_init(&mutex, 0) < 0) { + ErrorCode = CAErr_Mutex; + return CAErr_Error; + } + + // Setup a AudioStreamBasicDescription with the requested format + requestedDesc.mFormatID = kAudioFormatLinearPCM; + requestedDesc.mFormatFlags = kLinearPCMFormatFlagIsPacked; + requestedDesc.mChannelsPerFrame = numchannels; + requestedDesc.mSampleRate = mixrate; + + requestedDesc.mBitsPerChannel = samplebits; + if (samplebits == 16) { + requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; +#ifdef __POWERPC__ + requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; +#endif + } + + requestedDesc.mFramesPerPacket = 1; + requestedDesc.mBytesPerFrame = requestedDesc.mBitsPerChannel * \ + requestedDesc.mChannelsPerFrame / 8; + requestedDesc.mBytesPerPacket = requestedDesc.mBytesPerFrame * \ + requestedDesc.mFramesPerPacket; + + // Locate the default output audio unit + desc.componentType = kAudioUnitComponentType; + desc.componentSubType = kAudioUnitSubType_Output; + desc.componentManufacturer = kAudioUnitID_DefaultOutput; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + + comp = FindNextComponent(NULL, &desc); + if (comp == NULL) { + ErrorCode = CAErr_FindNextComponent; + pthread_mutex_destroy(&mutex); + return CAErr_Error; + } + + // Open & initialize the default output audio unit + result = OpenAComponent(comp, &output_audio_unit); + if (result != noErr) { + ErrorCode = CAErr_OpenAComponent; + CloseComponent(output_audio_unit); + pthread_mutex_destroy(&mutex); + return CAErr_Error; + } + + result = AudioUnitInitialize(output_audio_unit); + if (result != noErr) { + ErrorCode = CAErr_AudioUnitInitialize; + CloseComponent(output_audio_unit); + pthread_mutex_destroy(&mutex); + return CAErr_Error; + } + + // Set the input format of the audio unit. + result = AudioUnitSetProperty(output_audio_unit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, + &requestedDesc, + sizeof(requestedDesc)); + if (result != noErr) { + ErrorCode = CAErr_AudioUnitSetProperty; + CloseComponent(output_audio_unit); + pthread_mutex_destroy(&mutex); + return CAErr_Error; + } + + // Set the audio callback + callback.inputProc = fillInput; + callback.inputProcRefCon = 0; + AudioUnitSetProperty(output_audio_unit, + kAudioUnitProperty_SetInputCallback, + kAudioUnitScope_Input, + 0, + &callback, + sizeof(callback)); + + Initialised = 1; + + return CAErr_Ok; +} + +void CoreAudioDrv_Shutdown(void) +{ + OSStatus result; + struct AudioUnitInputCallback callback; + + if (!Initialised) { + return; + } + + // stop processing the audio unit + CoreAudioDrv_StopPlayback(); + + // Remove the input callback + callback.inputProc = 0; + callback.inputProcRefCon = 0; + result = AudioUnitSetProperty(output_audio_unit, + kAudioUnitProperty_SetInputCallback, + kAudioUnitScope_Input, + 0, + &callback, + sizeof(callback)); + result = CloseComponent(output_audio_unit); + + pthread_mutex_destroy(&mutex); + + Initialised = 0; +} + +int32_t CoreAudioDrv_BeginPlayback(char *BufferStart, int32_t BufferSize, + int32_t NumDivisions, void ( *CallBackFunc )( void ) ) +{ + if (!Initialised) { + ErrorCode = CAErr_Uninitialised; + return CAErr_Error; + } + + if (Playing) { + CoreAudioDrv_StopPlayback(); + } + + MixBuffer = BufferStart; + MixBufferSize = BufferSize; + MixBufferCount = NumDivisions; + MixBufferCurrent = 0; + MixBufferUsed = 0; + MixCallBack = CallBackFunc; + + // prime the buffer + MixCallBack(); + + AudioOutputUnitStart(output_audio_unit); + + Playing = 1; + + return CAErr_Ok; +} + +void CoreAudioDrv_StopPlayback(void) +{ + if (!Initialised || !Playing) { + return; + } + + CoreAudioDrv_Lock(); + AudioOutputUnitStop(output_audio_unit); + CoreAudioDrv_Unlock(); + + Playing = 0; +} + +void CoreAudioDrv_Lock(void) +{ + pthread_mutex_lock(&mutex); +} + +void CoreAudioDrv_Unlock(void) +{ + pthread_mutex_unlock(&mutex); +} diff --git a/polymer/eduke32/source/jaudiolib/src/driver_coreaudio.h b/polymer/eduke32/source/jaudiolib/src/driver_coreaudio.h new file mode 100644 index 000000000..48df3e352 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/driver_coreaudio.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +int32_t CoreAudioDrv_GetError(void); +const char *CoreAudioDrv_ErrorString( int32_t ErrorNumber ); +int32_t CoreAudioDrv_Init(int32_t mixrate, int32_t numchannels, int32_t samplebits, void * initdata); +void CoreAudioDrv_Shutdown(void); +int32_t CoreAudioDrv_BeginPlayback(char *BufferStart, int32_t BufferSize, + int32_t NumDivisions, void ( *CallBackFunc )( void ) ); +void CoreAudioDrv_StopPlayback(void); +void CoreAudioDrv_Lock(void); +void CoreAudioDrv_Unlock(void); \ No newline at end of file diff --git a/polymer/eduke32/source/jaudiolib/src/driver_directsound.c b/polymer/eduke32/source/jaudiolib/src/driver_directsound.c new file mode 100644 index 000000000..9a413564f --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/driver_directsound.c @@ -0,0 +1,487 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +/** + * DirectSound output driver for MultiVoc + */ + +#define WIN32_LEAN_AND_MEAN +#define DIRECTSOUND_VERSION 0x0700 +#include +#include +#include +#include +#include + +#include "driver_directsound.h" + +enum { + DSErr_Warning = -2, + DSErr_Error = -1, + DSErr_Ok = 0, + DSErr_Uninitialised, + DSErr_DirectSoundCreate, + DSErr_SetCooperativeLevel, + DSErr_CreateSoundBuffer, + DSErr_CreateSoundBufferSecondary, + DSErr_SetFormat, + DSErr_SetFormatSecondary, + DSErr_Notify, + DSErr_NotifyEvents, + DSErr_SetNotificationPositions, + DSErr_Play, + DSErr_PlaySecondary, + DSErr_CreateThread, + DSErr_CreateMutex +}; + +static int32_t ErrorCode = DSErr_Ok; +static int32_t Initialised = 0; +static int32_t Playing = 0; + +static char *MixBuffer = 0; +static int32_t MixBufferSize = 0; +static int32_t MixBufferCount = 0; +static int32_t MixBufferCurrent = 0; +static int32_t MixBufferUsed = 0; +static void ( *MixCallBack )( void ) = 0; + +static LPDIRECTSOUND lpds = 0; +static LPDIRECTSOUNDBUFFER lpdsbprimary = 0, lpdsbsec = 0; +static LPDIRECTSOUNDNOTIFY lpdsnotify = 0; +static DSBPOSITIONNOTIFY notifyPositions[3] = { { 0,0 }, { 0,0 }, { 0,0 } }; +static HANDLE mixThread = 0; +static HANDLE mutex = 0; + + +static void FillBufferPortion(char * ptr, int32_t remaining) +{ + int32_t len; + char *sptr; + + while (remaining > 0) { + if (MixBufferUsed == MixBufferSize) { + MixCallBack(); + + MixBufferUsed = 0; + MixBufferCurrent++; + if (MixBufferCurrent >= MixBufferCount) { + MixBufferCurrent -= MixBufferCount; + } + } + + while (remaining > 0 && MixBufferUsed < MixBufferSize) { + sptr = MixBuffer + (MixBufferCurrent * MixBufferSize) + MixBufferUsed; + + len = MixBufferSize - MixBufferUsed; + if (remaining < len) { + len = remaining; + } + + memcpy(ptr, sptr, len); + + ptr += len; + MixBufferUsed += len; + remaining -= len; + } + } +} + +static void FillBuffer(int32_t bufnum) +{ + HRESULT err; + LPVOID ptr, ptr2; + DWORD remaining, remaining2; + int32_t retries = 1; + + //fprintf(stderr, "DirectSound FillBuffer: filling %d\n", bufnum); + + do { + err = IDirectSoundBuffer_Lock(lpdsbsec, + notifyPositions[bufnum].dwOffset, + notifyPositions[1].dwOffset, + &ptr, &remaining, + &ptr2, &remaining2, + 0); + if (FAILED(err)) { + if (err == DSERR_BUFFERLOST) { + err = IDirectSoundBuffer_Restore(lpdsbsec); + if (FAILED(err)) { + return; + } + + if (retries-- > 0) { + continue; + } + } + fprintf(stderr, "DirectSound FillBuffer: err %x\n", (uint32_t) err); + return; + } + break; + } while (1); + + if (ptr) { + FillBufferPortion((char *) ptr, remaining); + } + if (ptr2) { + FillBufferPortion((char *) ptr2, remaining2); + } + + IDirectSoundBuffer_Unlock(lpdsbsec, ptr, remaining, ptr2, remaining2); +} + +static DWORD WINAPI fillDataThread(LPVOID lpParameter) +{ + HANDLE handles[3]; + DWORD waitret, waitret2; + + handles[0] = notifyPositions[0].hEventNotify; + handles[1] = notifyPositions[1].hEventNotify; + handles[2] = notifyPositions[2].hEventNotify; + + do { + waitret = WaitForMultipleObjects(3, handles, FALSE, INFINITE); + switch (waitret) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0+1: + waitret2 = WaitForSingleObject(mutex, INFINITE); + if (waitret2 == WAIT_OBJECT_0) { + FillBuffer(WAIT_OBJECT_0 + 1 - waitret); + ReleaseMutex(mutex); + } else { + fprintf(stderr, "DirectSound fillDataThread: wfso err %d\n", (int32_t) waitret2); + } + break; + case WAIT_OBJECT_0+2: + fprintf(stderr, "DirectSound fillDataThread: exiting\n"); + ExitThread(0); + break; + default: + fprintf(stderr, "DirectSound fillDataThread: wfmo err %d\n", (int32_t) waitret); + break; + } + } while (1); + + return 0; +} + + +int32_t DirectSoundDrv_GetError(void) +{ + return ErrorCode; +} + +const char *DirectSoundDrv_ErrorString( int32_t ErrorNumber ) +{ + const char *ErrorString; + + switch( ErrorNumber ) + { + case DSErr_Warning : + case DSErr_Error : + ErrorString = DirectSoundDrv_ErrorString( ErrorCode ); + break; + + case DSErr_Ok : + ErrorString = "DirectSound ok."; + break; + + case DSErr_Uninitialised: + ErrorString = "DirectSound uninitialised."; + break; + + case DSErr_DirectSoundCreate: + ErrorString = "DirectSound error: DirectSoundCreate failed."; + break; + + case DSErr_SetCooperativeLevel: + ErrorString = "DirectSound error: SetCooperativeLevel failed."; + break; + + case DSErr_CreateSoundBuffer: + ErrorString = "DirectSound error: primary CreateSoundBuffer failed."; + break; + + case DSErr_CreateSoundBufferSecondary: + ErrorString = "DirectSound error: secondary CreateSoundBuffer failed."; + break; + + case DSErr_SetFormat: + ErrorString = "DirectSound error: primary buffer SetFormat failed."; + break; + + case DSErr_SetFormatSecondary: + ErrorString = "DirectSound error: secondary buffer SetFormat failed."; + break; + + case DSErr_Notify: + ErrorString = "DirectSound error: failed querying secondary buffer for notify interface."; + break; + + case DSErr_NotifyEvents: + ErrorString = "DirectSound error: failed creating notify events."; + break; + + case DSErr_SetNotificationPositions: + ErrorString = "DirectSound error: failed setting notification positions."; + break; + + case DSErr_Play: + ErrorString = "DirectSound error: primary buffer Play failed."; + break; + + case DSErr_PlaySecondary: + ErrorString = "DirectSound error: secondary buffer Play failed."; + break; + + case DSErr_CreateThread: + ErrorString = "DirectSound error: failed creating mix thread."; + break; + + case DSErr_CreateMutex: + ErrorString = "DirectSound error: failed creating mix mutex."; + break; + + default: + ErrorString = "Unknown DirectSound error code."; + break; + } + + return ErrorString; + +} + + +static void TeardownDSound(HRESULT err) +{ + if (FAILED(err)) { + fprintf(stderr, "Dying error: %x\n", (uint32_t) err); + } + + if (lpdsnotify) IDirectSoundNotify_Release(lpdsnotify); + if (notifyPositions[0].hEventNotify) CloseHandle(notifyPositions[0].hEventNotify); + if (notifyPositions[1].hEventNotify) CloseHandle(notifyPositions[1].hEventNotify); + if (notifyPositions[2].hEventNotify) CloseHandle(notifyPositions[2].hEventNotify); + if (mutex) CloseHandle(mutex); + if (lpdsbsec) IDirectSoundBuffer_Release(lpdsbsec); + if (lpdsbprimary) IDirectSoundBuffer_Release(lpdsbprimary); + if (lpds) IDirectSound_Release(lpds); + notifyPositions[0].hEventNotify = + notifyPositions[1].hEventNotify = + notifyPositions[2].hEventNotify = 0; + mutex = 0; + lpdsnotify = 0; + lpdsbsec = 0; + lpdsbprimary = 0; + lpds = 0; +} + +int32_t DirectSoundDrv_Init(int32_t mixrate, int32_t numchannels, int32_t samplebits, void * initdata) +{ + HRESULT err; + DSBUFFERDESC bufdesc; + WAVEFORMATEX wfex; + + if (Initialised) { + DirectSoundDrv_Shutdown(); + } + + err = DirectSoundCreate(0, &lpds, 0); + if (FAILED( err )) { + ErrorCode = DSErr_DirectSoundCreate; + return DSErr_Error; + } + + err = IDirectSound_SetCooperativeLevel(lpds, (HWND) initdata, DSSCL_PRIORITY); + if (FAILED( err )) { + TeardownDSound(err); + ErrorCode = DSErr_SetCooperativeLevel; + return DSErr_Error; + } + + memset(&bufdesc, 0, sizeof(DSBUFFERDESC)); + bufdesc.dwSize = sizeof(DSBUFFERDESC); + bufdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; + + err = IDirectSound_CreateSoundBuffer(lpds, &bufdesc, &lpdsbprimary, 0); + if (FAILED( err )) { + TeardownDSound(err); + ErrorCode = DSErr_CreateSoundBuffer; + return DSErr_Error; + } + + memset(&wfex, 0, sizeof(WAVEFORMATEX)); + wfex.wFormatTag = WAVE_FORMAT_PCM; + wfex.nChannels = numchannels; + wfex.nSamplesPerSec = mixrate; + wfex.wBitsPerSample = samplebits; + wfex.nBlockAlign = wfex.nChannels * wfex.wBitsPerSample / 8; + wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; + + err = IDirectSoundBuffer_SetFormat(lpdsbprimary, &wfex); + if (FAILED( err )) { + TeardownDSound(err); + ErrorCode = DSErr_SetFormat; + return DSErr_Error; + } + + bufdesc.dwFlags = DSBCAPS_LOCSOFTWARE | + DSBCAPS_CTRLPOSITIONNOTIFY | + DSBCAPS_GETCURRENTPOSITION2; + bufdesc.dwBufferBytes = wfex.nBlockAlign * 2048 * 2; + bufdesc.lpwfxFormat = &wfex; + + err = IDirectSound_CreateSoundBuffer(lpds, &bufdesc, &lpdsbsec, 0); + if (FAILED( err )) { + TeardownDSound(err); + ErrorCode = DSErr_SetFormatSecondary; + return DSErr_Error; + } + + err = IDirectSoundBuffer_QueryInterface(lpdsbsec, &IID_IDirectSoundNotify, + (LPVOID *) &lpdsnotify); + if (FAILED( err )) { + TeardownDSound(err); + ErrorCode = DSErr_Notify; + return DSErr_Error; + } + + notifyPositions[0].dwOffset = 0; + notifyPositions[0].hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL); + notifyPositions[1].dwOffset = bufdesc.dwBufferBytes / 2; + notifyPositions[1].hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL); + notifyPositions[2].dwOffset = DSBPN_OFFSETSTOP; + notifyPositions[2].hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!notifyPositions[0].hEventNotify || + !notifyPositions[1].hEventNotify || + !notifyPositions[2].hEventNotify) { + TeardownDSound(DS_OK); + ErrorCode = DSErr_NotifyEvents; + return DSErr_Error; + } + + err = IDirectSoundNotify_SetNotificationPositions(lpdsnotify, 3, notifyPositions); + if (FAILED( err )) { + TeardownDSound(err); + ErrorCode = DSErr_SetNotificationPositions; + return DSErr_Error; + } + + err = IDirectSoundBuffer_Play(lpdsbprimary, 0, 0, DSBPLAY_LOOPING); + if (FAILED( err )) { + TeardownDSound(err); + ErrorCode = DSErr_Play; + return DSErr_Error; + } + + mutex = CreateMutex(0, FALSE, 0); + if (!mutex) { + TeardownDSound(DS_OK); + ErrorCode = DSErr_CreateMutex; + return DSErr_Error; + } + + Initialised = 1; + + fprintf(stderr, "DirectSound Init: yay\n"); + + return DSErr_Ok; +} + +void DirectSoundDrv_Shutdown(void) +{ + if (!Initialised) { + return; + } + + DirectSoundDrv_StopPlayback(); + + TeardownDSound(DS_OK); + + Initialised = 0; +} + +int32_t DirectSoundDrv_BeginPlayback(char *BufferStart, int32_t BufferSize, + int32_t NumDivisions, void ( *CallBackFunc )( void ) ) +{ + HRESULT err; + + if (!Initialised) { + ErrorCode = DSErr_Uninitialised; + return DSErr_Error; + } + + DirectSoundDrv_StopPlayback(); + + MixBuffer = BufferStart; + MixBufferSize = BufferSize; + MixBufferCount = NumDivisions; + MixBufferCurrent = 0; + MixBufferUsed = 0; + MixCallBack = CallBackFunc; + + // prime the buffer + FillBuffer(0); + + mixThread = CreateThread(NULL, 0, fillDataThread, 0, 0, 0); + if (!mixThread) { + ErrorCode = DSErr_CreateThread; + return DSErr_Error; + } + + SetThreadPriority(mixThread, THREAD_PRIORITY_HIGHEST); + + err = IDirectSoundBuffer_Play(lpdsbsec, 0, 0, DSBPLAY_LOOPING); + if (FAILED( err )) { + ErrorCode = DSErr_PlaySecondary; + return DSErr_Error; + } + + Playing = 1; + + return DSErr_Ok; +} + +void DirectSoundDrv_StopPlayback(void) +{ + if (!Playing) { + return; + } + + IDirectSoundBuffer_Stop(lpdsbsec); + IDirectSoundBuffer_SetCurrentPosition(lpdsbsec, 0); + + Playing = 0; +} + +void DirectSoundDrv_Lock(void) +{ + DWORD err; + + err = WaitForSingleObject(mutex, INFINITE); + if (err != WAIT_OBJECT_0) { + fprintf(stderr, "DirectSound lock: wfso %d\n", (int32_t) err); + } +} + +void DirectSoundDrv_Unlock(void) +{ + ReleaseMutex(mutex); +} diff --git a/polymer/eduke32/source/jaudiolib/src/driver_directsound.h b/polymer/eduke32/source/jaudiolib/src/driver_directsound.h new file mode 100644 index 000000000..33dfe7d7c --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/driver_directsound.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +#include "inttypes.h" + +int32_t DirectSoundDrv_GetError(void); +const char *DirectSoundDrv_ErrorString( int32_t ErrorNumber ); +int32_t DirectSoundDrv_Init(int32_t mixrate, int32_t numchannels, int32_t samplebits, void * initdata); +void DirectSoundDrv_Shutdown(void); +int32_t DirectSoundDrv_BeginPlayback(char *BufferStart, int32_t BufferSize, + int32_t NumDivisions, void ( *CallBackFunc )( void ) ); +void DirectSoundDrv_StopPlayback(void); +void DirectSoundDrv_Lock(void); +void DirectSoundDrv_Unlock(void); diff --git a/polymer/eduke32/source/jaudiolib/src/driver_nosound.c b/polymer/eduke32/source/jaudiolib/src/driver_nosound.c new file mode 100644 index 000000000..55818c8b2 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/driver_nosound.c @@ -0,0 +1,62 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +/** + * Stub driver for no output + */ + +#include "inttypes.h" + +int32_t NoSoundDrv_GetError(void) +{ + return 0; +} + +const char *NoSoundDrv_ErrorString( int32_t ErrorNumber ) +{ + return "No sound, Ok."; +} + +int32_t NoSoundDrv_Init(int32_t mixrate, int32_t numchannels, int32_t samplebits, void * initdata) +{ + return 0; +} + +void NoSoundDrv_Shutdown(void) +{ +} + +int32_t NoSoundDrv_BeginPlayback(char *BufferStart, int32_t BufferSize, + int32_t NumDivisions, void ( *CallBackFunc )( void ) ) +{ + return 0; +} + +void NoSoundDrv_StopPlayback(void) +{ +} + +void NoSoundDrv_Lock(void) +{ +} + +void NoSoundDrv_Unlock(void) +{ +} diff --git a/polymer/eduke32/source/jaudiolib/src/driver_nosound.h b/polymer/eduke32/source/jaudiolib/src/driver_nosound.h new file mode 100644 index 000000000..fcba11bbe --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/driver_nosound.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + + +int NoSoundDrv_GetError(void); +const char *NoSoundDrv_ErrorString( int ErrorNumber ); +int NoSoundDrv_Init(int mixrate, int numchannels, int samplebits, void * initdata); +void NoSoundDrv_Shutdown(void); +int NoSoundDrv_BeginPlayback(char *BufferStart, int BufferSize, + int NumDivisions, void ( *CallBackFunc )( void ) ); +void NoSoundDrv_StopPlayback(void); +void NoSoundDrv_Lock(void); +void NoSoundDrv_Unlock(void); diff --git a/polymer/eduke32/source/jaudiolib/src/driver_sdl.c b/polymer/eduke32/source/jaudiolib/src/driver_sdl.c new file mode 100644 index 000000000..3c8e8e0eb --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/driver_sdl.c @@ -0,0 +1,231 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +/** + * libSDL output driver for MultiVoc + */ + + +#include +#include "driver_sdl.h" + +enum { + SDLErr_Warning = -2, + SDLErr_Error = -1, + SDLErr_Ok = 0, + SDLErr_Uninitialised, + SDLErr_InitSubSystem, + SDLErr_OpenAudio +}; + +static int32_t ErrorCode = SDLErr_Ok; +static int32_t Initialised = 0; +static int32_t Playing = 0; +static int32_t StartedSDL = -1; + +static char *MixBuffer = 0; +static int32_t MixBufferSize = 0; +static int32_t MixBufferCount = 0; +static int32_t MixBufferCurrent = 0; +static int32_t MixBufferUsed = 0; +static void ( *MixCallBack )( void ) = 0; + +static void fillData(void * userdata, Uint8 * ptr, int32_t remaining) +{ + int32_t len; + char *sptr; + + while (remaining > 0) { + if (MixBufferUsed == MixBufferSize) { + MixCallBack(); + + MixBufferUsed = 0; + MixBufferCurrent++; + if (MixBufferCurrent >= MixBufferCount) { + MixBufferCurrent -= MixBufferCount; + } + } + + while (remaining > 0 && MixBufferUsed < MixBufferSize) { + sptr = MixBuffer + (MixBufferCurrent * MixBufferSize) + MixBufferUsed; + + len = MixBufferSize - MixBufferUsed; + if (remaining < len) { + len = remaining; + } + + memcpy(ptr, sptr, len); + + ptr += len; + MixBufferUsed += len; + remaining -= len; + } + } +} + + +int32_t SDLDrv_GetError(void) +{ + return ErrorCode; +} + +const char *SDLDrv_ErrorString( int32_t ErrorNumber ) +{ + const char *ErrorString; + + switch( ErrorNumber ) { + case SDLErr_Warning : + case SDLErr_Error : + ErrorString = SDLDrv_ErrorString( ErrorCode ); + break; + + case SDLErr_Ok : + ErrorString = "SDL Audio ok."; + break; + + case SDLErr_Uninitialised: + ErrorString = "SDL Audio uninitialised."; + break; + + case SDLErr_InitSubSystem: + ErrorString = "SDL Audio: error in Init or InitSubSystem."; + break; + + case SDLErr_OpenAudio: + ErrorString = "SDL Audio: error in OpenAudio."; + break; + + default: + ErrorString = "Unknown SDL Audio error code."; + break; + } + + return ErrorString; +} + +int32_t SDLDrv_Init(int32_t mixrate, int32_t numchannels, int32_t samplebits, void * initdata) +{ + Uint32 inited; + Uint32 err = 0; + SDL_AudioSpec spec; + + if (Initialised) { + SDLDrv_Shutdown(); + } + + inited = SDL_WasInit(SDL_INIT_EVERYTHING); + + if (inited == 0) { + // nothing was initialised + err = SDL_Init(SDL_INIT_AUDIO); + StartedSDL = 0; + } else if (inited & SDL_INIT_AUDIO) { + err = SDL_InitSubSystem(SDL_INIT_AUDIO); + StartedSDL = 1; + } + + if (err < 0) { + ErrorCode = SDLErr_InitSubSystem; + return SDLErr_Error; + } + + spec.freq = mixrate; + spec.format = (samplebits == 8) ? AUDIO_U8 : AUDIO_S16SYS; + spec.channels = numchannels; + spec.samples = 256; + spec.callback = fillData; + spec.userdata = 0; + + err = SDL_OpenAudio(&spec, NULL); + if (err < 0) { + ErrorCode = SDLErr_OpenAudio; + return SDLErr_Error; + } + + Initialised = 1; + + return SDLErr_Ok; +} + +void SDLDrv_Shutdown(void) +{ + if (!Initialised) { + return; + } + + if (StartedSDL > 0) { + SDL_QuitSubSystem(SDL_INIT_AUDIO); + } else if (StartedSDL == 0) { + SDL_Quit(); + } + + StartedSDL = -1; +} + +int32_t SDLDrv_BeginPlayback(char *BufferStart, int32_t BufferSize, + int32_t NumDivisions, void ( *CallBackFunc )( void ) ) +{ + if (!Initialised) { + ErrorCode = SDLErr_Uninitialised; + return SDLErr_Error; + } + + if (Playing) { + SDLDrv_StopPlayback(); + } + + MixBuffer = BufferStart; + MixBufferSize = BufferSize; + MixBufferCount = NumDivisions; + MixBufferCurrent = 0; + MixBufferUsed = 0; + MixCallBack = CallBackFunc; + + // prime the buffer + MixCallBack(); + + SDL_PauseAudio(0); + + Playing = 1; + + return SDLErr_Ok; +} + +void SDLDrv_StopPlayback(void) +{ + if (!Initialised || !Playing) { + return; + } + + SDL_PauseAudio(1); + + Playing = 0; +} + +void SDLDrv_Lock(void) +{ + SDL_LockAudio(); +} + +void SDLDrv_Unlock(void) +{ + SDL_UnlockAudio(); +} + diff --git a/polymer/eduke32/source/jaudiolib/src/driver_sdl.h b/polymer/eduke32/source/jaudiolib/src/driver_sdl.h new file mode 100644 index 000000000..36c04ec2c --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/driver_sdl.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + + +int32_t SDLDrv_GetError(void); +const char *SDLDrv_ErrorString( int32_t ErrorNumber ); +int32_t SDLDrv_Init(int32_t mixrate, int32_t numchannels, int32_t samplebits, void * initdata); +void SDLDrv_Shutdown(void); +int32_t SDLDrv_BeginPlayback(char *BufferStart, int32_t BufferSize, + int32_t NumDivisions, void ( *CallBackFunc )( void ) ); +void SDLDrv_StopPlayback(void); +void SDLDrv_Lock(void); +void SDLDrv_Unlock(void); diff --git a/polymer/eduke32/source/jaudiolib/src/drivers.c b/polymer/eduke32/source/jaudiolib/src/drivers.c new file mode 100644 index 000000000..a8f394cdb --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/drivers.c @@ -0,0 +1,174 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +/** + * Abstraction layer for hiding the various supported sound devices + * behind a common and opaque interface called on by MultiVoc. + */ + +#include "drivers.h" + +#include "driver_nosound.h" + +#ifdef HAVE_SDL +# include "driver_sdl.h" +#endif + +#ifdef __APPLE__ +# include "driver_coreaudio.h" +#endif + +#ifdef WIN32 +# include "driver_directsound.h" +#endif + +int32_t ASS_SoundDriver = -1; + +#define UNSUPPORTED { 0,0,0,0,0,0,0,0, }, + +static struct { + int32_t (* GetError)(void); + const char * (* ErrorString)(int32_t); + int32_t (* Init)(int32_t, int32_t, int32_t, void *); + void (* Shutdown)(void); + int32_t (* BeginPlayback)(char *, int32_t, int32_t, void ( * )(void) ); + void (* StopPlayback)(void); + void (* Lock)(void); + void (* Unlock)(void); +} SoundDrivers[ASS_NumSoundCards] = { + + // Everyone gets the "no sound" driver + { + NoSoundDrv_GetError, + NoSoundDrv_ErrorString, + NoSoundDrv_Init, + NoSoundDrv_Shutdown, + NoSoundDrv_BeginPlayback, + NoSoundDrv_StopPlayback, + NoSoundDrv_Lock, + NoSoundDrv_Unlock, + }, + + // Simple DirectMedia Layer + #ifdef HAVE_SDL + { + SDLDrv_GetError, + SDLDrv_ErrorString, + SDLDrv_Init, + SDLDrv_Shutdown, + SDLDrv_BeginPlayback, + SDLDrv_StopPlayback, + SDLDrv_Lock, + SDLDrv_Unlock, + }, + #else + UNSUPPORTED + #endif + + // OS X CoreAudio + #ifdef __APPLE__ + { + CoreAudioDrv_GetError, + CoreAudioDrv_ErrorString, + CoreAudioDrv_Init, + CoreAudioDrv_Shutdown, + CoreAudioDrv_BeginPlayback, + CoreAudioDrv_StopPlayback, + CoreAudioDrv_Lock, + CoreAudioDrv_Unlock, + }, + #else + UNSUPPORTED + #endif + + // Windows DirectSound + #ifdef WIN32 + { + DirectSoundDrv_GetError, + DirectSoundDrv_ErrorString, + DirectSoundDrv_Init, + DirectSoundDrv_Shutdown, + DirectSoundDrv_BeginPlayback, + DirectSoundDrv_StopPlayback, + DirectSoundDrv_Lock, + DirectSoundDrv_Unlock, + }, + #else + UNSUPPORTED + #endif +}; + + +int32_t SoundDriver_IsSupported(int32_t driver) +{ + return (SoundDrivers[driver].GetError != 0); +} + + +int32_t SoundDriver_GetError(void) +{ + if (!SoundDriver_IsSupported(ASS_SoundDriver)) { + return -1; + } + return SoundDrivers[ASS_SoundDriver].GetError(); +} + +const char * SoundDriver_ErrorString( int32_t ErrorNumber ) +{ + if (ASS_SoundDriver < 0 || ASS_SoundDriver >= ASS_NumSoundCards) { + return "No sound driver selected."; + } + if (!SoundDriver_IsSupported(ASS_SoundDriver)) { + return "Unsupported sound driver selected."; + } + return SoundDrivers[ASS_SoundDriver].ErrorString(ErrorNumber); +} + +int32_t SoundDriver_Init(int32_t mixrate, int32_t numchannels, int32_t samplebits, void * initdata) +{ + return SoundDrivers[ASS_SoundDriver].Init(mixrate, numchannels, samplebits, initdata); +} + +void SoundDriver_Shutdown(void) +{ + SoundDrivers[ASS_SoundDriver].Shutdown(); +} + +int32_t SoundDriver_BeginPlayback(char *BufferStart, int32_t BufferSize, + int32_t NumDivisions, void ( *CallBackFunc )( void ) ) +{ + return SoundDrivers[ASS_SoundDriver].BeginPlayback(BufferStart, + BufferSize, NumDivisions, CallBackFunc); +} + +void SoundDriver_StopPlayback(void) +{ + SoundDrivers[ASS_SoundDriver].StopPlayback(); +} + +void SoundDriver_Lock(void) +{ + SoundDrivers[ASS_SoundDriver].Lock(); +} + +void SoundDriver_Unlock(void) +{ + SoundDrivers[ASS_SoundDriver].Unlock(); +} diff --git a/polymer/eduke32/source/jaudiolib/src/drivers.h b/polymer/eduke32/source/jaudiolib/src/drivers.h new file mode 100644 index 000000000..4a25f68cf --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/drivers.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +#ifndef DRIVERS_H +#define DRIVERS_H + +#include "inttypes.h" +#include "sndcards.h" + +extern int32_t ASS_SoundDriver; + +int32_t SoundDriver_IsSupported(int32_t driver); + +int32_t SoundDriver_GetError(void); +const char * SoundDriver_ErrorString( int32_t ErrorNumber ); +int32_t SoundDriver_Init(int32_t mixrate, int32_t numchannels, int32_t samplebits, void * initdata); +void SoundDriver_Shutdown(void); +int32_t SoundDriver_BeginPlayback( char *BufferStart, + int32_t BufferSize, int32_t NumDivisions, + void ( *CallBackFunc )( void ) ); +void SoundDriver_StopPlayback(void); +void SoundDriver_Lock(void); +void SoundDriver_Unlock(void); + +#endif diff --git a/polymer/eduke32/source/jaudiolib/src/fx_man.c b/polymer/eduke32/source/jaudiolib/src/fx_man.c new file mode 100644 index 000000000..fe71f8be4 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/fx_man.c @@ -0,0 +1,1069 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/********************************************************************** + module: FX_MAN.C + + author: James R. Dose + date: March 17, 1994 + + Device independant sound effect routines. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#include +#include +#include "sndcards.h" +#include "drivers.h" +#include "multivoc.h" +#include "fx_man.h" + +#define TRUE ( 1 == 1 ) +#define FALSE ( !TRUE ) + +int32_t FX_ErrorCode = FX_Ok; +int32_t FX_Installed = FALSE; + +#define FX_SetErrorCode( status ) \ + FX_ErrorCode = ( status ); + + +/*--------------------------------------------------------------------- + Function: FX_ErrorString + + Returns a pointer to the error message associated with an error + number. A -1 returns a pointer the current error. +---------------------------------------------------------------------*/ + +const char *FX_ErrorString +( + int32_t ErrorNumber +) + +{ + const char *ErrorString; + + switch (ErrorNumber) + { + case FX_Warning : + case FX_Error : + ErrorString = FX_ErrorString(FX_ErrorCode); + break; + + case FX_Ok : + ErrorString = "Fx ok."; + break; + + case FX_ASSVersion : + ErrorString = "Apogee Sound System Version " ASS_VERSION_STRING " " + "Programmed by Jim Dose\n" + "(c) Copyright 1995 James R. Dose. All Rights Reserved.\n"; + break; + + case FX_SoundCardError : + ErrorString = SoundDriver_ErrorString(SoundDriver_GetError()); + break; + + case FX_InvalidCard : + ErrorString = "Invalid Sound Fx device."; + break; + + case FX_MultiVocError : + ErrorString = MV_ErrorString(MV_Error); + break; + + default : + ErrorString = "Unknown Fx error code."; + break; + } + + return(ErrorString); +} + + +/*--------------------------------------------------------------------- + Function: FX_Init + + Selects which sound device to use. +---------------------------------------------------------------------*/ + +int32_t FX_Init +( + int32_t SoundCard, + int32_t numvoices, + int32_t numchannels, + int32_t samplebits, + unsigned mixrate, + void * initdata +) + +{ + int32_t status; + int32_t devicestatus; + + if (FX_Installed) + { + FX_Shutdown(); + } + + if (SoundCard == ASS_AutoDetect) + { +#if defined __APPLE__ + SoundCard = ASS_CoreAudio; +#elif defined WIN32 + SoundCard = ASS_DirectSound; +#elif defined HAVE_SDL + SoundCard = ASS_SDL; +#else + SoundCard = ASS_NoSound; +#endif + } + + if (SoundCard < 0 || SoundCard >= ASS_NumSoundCards) + { + FX_SetErrorCode(FX_InvalidCard); + status = FX_Error; + return status; + } + + if (SoundDriver_IsSupported(SoundCard) == 0) + { + // unsupported cards fall back to no sound + SoundCard = ASS_NoSound; + } + + status = FX_Ok; + devicestatus = MV_Init(SoundCard, mixrate, numvoices, numchannels, samplebits, initdata); + if (devicestatus != MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + status = FX_Error; + } + + if (status == FX_Ok) + { + FX_Installed = TRUE; + } + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: FX_Shutdown + + Terminates use of sound device. +---------------------------------------------------------------------*/ + +int32_t FX_Shutdown +( + void +) + +{ + int32_t status; + + if (!FX_Installed) + { + return(FX_Ok); + } + + status = MV_Shutdown(); + if (status != MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + status = FX_Error; + } + + FX_Installed = FALSE; + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: FX_SetCallback + + Sets the function to call when a voice is done. +---------------------------------------------------------------------*/ + +int32_t FX_SetCallBack +( + void (*function)(uint32_t) +) + +{ + int32_t status; + + status = FX_Ok; + + MV_SetCallBack(function); + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: FX_SetVolume + + Sets the volume of the current sound device. +---------------------------------------------------------------------*/ + +void FX_SetVolume +( + int32_t volume +) + +{ + MV_SetVolume(volume); +} + + +/*--------------------------------------------------------------------- + Function: FX_GetVolume + + Returns the volume of the current sound device. +---------------------------------------------------------------------*/ + +int32_t FX_GetVolume +( + void +) + +{ + int32_t volume; + + volume = MV_GetVolume(); + + return(volume); +} + + +/*--------------------------------------------------------------------- + Function: FX_SetReverseStereo + + Set the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +void FX_SetReverseStereo +( + int32_t setting +) + +{ + MV_SetReverseStereo(setting); +} + + +/*--------------------------------------------------------------------- + Function: FX_GetReverseStereo + + Returns the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +int32_t FX_GetReverseStereo +( + void +) + +{ + return MV_GetReverseStereo(); +} + + +/*--------------------------------------------------------------------- + Function: FX_SetReverb + + Sets the reverb level. +---------------------------------------------------------------------*/ + +void FX_SetReverb +( + int32_t reverb +) + +{ + MV_SetReverb(reverb); +} + + +/*--------------------------------------------------------------------- + Function: FX_SetFastReverb + + Sets the reverb level. +---------------------------------------------------------------------*/ + +void FX_SetFastReverb +( + int32_t reverb +) + +{ + MV_SetFastReverb(reverb); +} + + +/*--------------------------------------------------------------------- + Function: FX_GetMaxReverbDelay + + Returns the maximum delay time for reverb. +---------------------------------------------------------------------*/ + +int32_t FX_GetMaxReverbDelay +( + void +) + +{ + return MV_GetMaxReverbDelay(); +} + + +/*--------------------------------------------------------------------- + Function: FX_GetReverbDelay + + Returns the current delay time for reverb. +---------------------------------------------------------------------*/ + +int32_t FX_GetReverbDelay +( + void +) + +{ + return MV_GetReverbDelay(); +} + + +/*--------------------------------------------------------------------- + Function: FX_SetReverbDelay + + Sets the delay level of reverb to add to mix. +---------------------------------------------------------------------*/ + +void FX_SetReverbDelay +( + int32_t delay +) + +{ + MV_SetReverbDelay(delay); +} + + +/*--------------------------------------------------------------------- + Function: FX_VoiceAvailable + + Checks if a voice can be play at the specified priority. +---------------------------------------------------------------------*/ + +int32_t FX_VoiceAvailable +( + int32_t priority +) + +{ + return MV_VoiceAvailable(priority); +} + +/*--------------------------------------------------------------------- +Function: FX_PauseVoice + +Stops the voice associated with the specified handle from looping +without stoping the sound. +---------------------------------------------------------------------*/ + +int32_t FX_PauseVoice +( + int32_t handle, + int32_t pause +) + +{ + int32_t status; + + status = MV_PauseVoice(handle, pause); + if (status == MV_Error) + { + FX_SetErrorCode(FX_MultiVocError); + status = FX_Warning; + } + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: FX_EndLooping + + Stops the voice associated with the specified handle from looping + without stoping the sound. +---------------------------------------------------------------------*/ + +int32_t FX_EndLooping +( + int32_t handle +) + +{ + int32_t status; + + status = MV_EndLooping(handle); + if (status == MV_Error) + { + FX_SetErrorCode(FX_MultiVocError); + status = FX_Warning; + } + + return(status); +} + +/*--------------------------------------------------------------------- + Function: FX_SetPan + + Sets the stereo and mono volume level of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +int32_t FX_SetPan +( + int32_t handle, + int32_t vol, + int32_t left, + int32_t right +) + +{ + int32_t status; + + status = MV_SetPan(handle, vol, left, right); + if (status == MV_Error) + { + FX_SetErrorCode(FX_MultiVocError); + status = FX_Warning; + } + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: FX_SetPitch + + Sets the pitch of the voice associated with the specified handle. +---------------------------------------------------------------------*/ + +int32_t FX_SetPitch +( + int32_t handle, + int32_t pitchoffset +) + +{ + int32_t status; + + status = MV_SetPitch(handle, pitchoffset); + if (status == MV_Error) + { + FX_SetErrorCode(FX_MultiVocError); + status = FX_Warning; + } + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: FX_SetFrequency + + Sets the frequency of the voice associated with the specified handle. +---------------------------------------------------------------------*/ + +int32_t FX_SetFrequency +( + int32_t handle, + int32_t frequency +) + +{ + int32_t status; + + status = MV_SetFrequency(handle, frequency); + if (status == MV_Error) + { + FX_SetErrorCode(FX_MultiVocError); + status = FX_Warning; + } + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayVOC + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int32_t FX_PlayVOC +( + char *ptr, + uint32_t ptrlength, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t handle; + + handle = MV_PlayVOC(ptr, ptrlength, pitchoffset, vol, left, right, + priority, callbackval); + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return(handle); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayLoopedVOC + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int32_t FX_PlayLoopedVOC +( + char *ptr, + uint32_t ptrlength, + int32_t loopstart, + int32_t loopend, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t handle; + + handle = MV_PlayLoopedVOC(ptr, ptrlength, loopstart, loopend, pitchoffset, + vol, left, right, priority, callbackval); + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return(handle); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayWAV + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int32_t FX_PlayWAV +( + char *ptr, + uint32_t ptrlength, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t handle; + + handle = MV_PlayWAV(ptr, ptrlength, pitchoffset, vol, left, right, + priority, callbackval); + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return(handle); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayWAV + + Begin playback of sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int32_t FX_PlayLoopedWAV +( + char *ptr, + uint32_t ptrlength, + int32_t loopstart, + int32_t loopend, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t handle; + + handle = MV_PlayLoopedWAV(ptr, ptrlength, loopstart, loopend, + pitchoffset, vol, left, right, priority, callbackval); + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return(handle); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayVOC3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int32_t FX_PlayVOC3D +( + char *ptr, + uint32_t ptrlength, + int32_t pitchoffset, + int32_t angle, + int32_t distance, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t handle; + + handle = MV_PlayVOC3D(ptr, ptrlength, pitchoffset, angle, distance, + priority, callbackval); + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return(handle); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayWAV3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int32_t FX_PlayWAV3D +( + char *ptr, + uint32_t ptrlength, + int32_t pitchoffset, + int32_t angle, + int32_t distance, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t handle; + + handle = MV_PlayWAV3D(ptr, ptrlength, pitchoffset, angle, distance, + priority, callbackval); + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return(handle); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayRaw + + Begin playback of raw sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int32_t FX_PlayRaw +( + char *ptr, + uint32_t length, + unsigned rate, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t handle; + + handle = MV_PlayRaw(ptr, length, rate, pitchoffset, + vol, left, right, priority, callbackval); + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return(handle); +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayLoopedRaw + + Begin playback of raw sound data with the given volume and priority. +---------------------------------------------------------------------*/ + +int32_t FX_PlayLoopedRaw +( + char *ptr, + uint32_t length, + char *loopstart, + char *loopend, + unsigned rate, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t handle; + + handle = MV_PlayLoopedRaw(ptr, length, loopstart, loopend, + rate, pitchoffset, vol, left, right, priority, callbackval); + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return(handle); +} + + +/*--------------------------------------------------------------------- + Function: FX_Pan3D + + Set the angle and distance from the listener of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +int32_t FX_Pan3D +( + int32_t handle, + int32_t angle, + int32_t distance +) + +{ + int32_t status; + + status = MV_Pan3D(handle, angle, distance); + if (status != MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + status = FX_Warning; + } + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: FX_SoundActive + + Tests if the specified sound is currently playing. +---------------------------------------------------------------------*/ + +int32_t FX_SoundActive +( + int32_t handle +) + +{ + return(MV_VoicePlaying(handle)); +} + + +/*--------------------------------------------------------------------- + Function: FX_SoundsPlaying + + Reports the number of voices playing. +---------------------------------------------------------------------*/ + +int32_t FX_SoundsPlaying +( + void +) + +{ + return(MV_VoicesPlaying()); +} + + +/*--------------------------------------------------------------------- + Function: FX_StopSound + + Halts playback of a specific voice +---------------------------------------------------------------------*/ + +int32_t FX_StopSound +( + int32_t handle +) + +{ + int32_t status; + + status = MV_Kill(handle); + if (status != MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + return(FX_Warning); + } + + return(FX_Ok); +} + + +/*--------------------------------------------------------------------- + Function: FX_StopAllSounds + + Halts playback of all sounds. +---------------------------------------------------------------------*/ + +int32_t FX_StopAllSounds +( + void +) + +{ + int32_t status; + + status = MV_KillAllVoices(); + if (status != MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + return(FX_Warning); + } + + return(FX_Ok); +} + + +/*--------------------------------------------------------------------- + Function: FX_StartDemandFeedPlayback + + Plays a digitized sound from a user controlled buffering system. +---------------------------------------------------------------------*/ + +int32_t FX_StartDemandFeedPlayback +( + void (*function)(char **ptr, uint32_t *length), + int32_t rate, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t handle; + + handle = MV_StartDemandFeedPlayback(function, rate, + pitchoffset, vol, left, right, priority, callbackval); + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return(handle); +} + + +/*--------------------------------------------------------------------- + Function: FX_StartRecording + + Starts the sound recording engine. +---------------------------------------------------------------------*/ + +int32_t FX_StartRecording +( + int32_t MixRate, + void (*function)(char *ptr, int32_t length) +) + +{ + int32_t status; + + FX_SetErrorCode(FX_InvalidCard); + status = FX_Warning; + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: FX_StopRecord + + Stops the sound record engine. +---------------------------------------------------------------------*/ + +void FX_StopRecord +( + void +) + +{ +} + + +/*--------------------------------------------------------------------- + Function: FX_PlayAuto + + Play a sound, autodetecting the format. +---------------------------------------------------------------------*/ +int32_t FX_PlayAuto(char *ptr, uint32_t length, int32_t pitchoffset, int32_t vol, + int32_t left, int32_t right, int32_t priority, uint32_t callbackval) +{ + int32_t handle = -1; + + if (!memcmp("Creative Voice File\x1a", ptr, 20)) + { + handle = MV_PlayVOC(ptr, length, pitchoffset, vol, left, right, priority, callbackval); + } + else if (!memcmp("RIFF", ptr, 4) && !memcmp("WAVE", ptr + 8, 4)) + { + handle = MV_PlayWAV(ptr, length, pitchoffset, vol, left, right, priority, callbackval); + } + else if (!memcmp("OggS", ptr, 4)) + { + handle = MV_PlayVorbis(ptr, length, pitchoffset, vol, left, right, priority, callbackval); + } + + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return handle; +} + +/*--------------------------------------------------------------------- + Function: FX_PlayLoopedAuto + + Play a looped sound, autodetecting the format. +---------------------------------------------------------------------*/ +int32_t FX_PlayLoopedAuto(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, + int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority, + uint32_t callbackval) +{ + int32_t handle = -1; + + if (!memcmp("Creative Voice File\x1a", ptr, 20)) + { + handle = MV_PlayLoopedVOC(ptr, length, loopstart, loopend, pitchoffset, + vol, left, right, priority, callbackval); + } + else if (!memcmp("RIFF", ptr, 4) && !memcmp("WAVE", ptr + 8, 4)) + { + handle = MV_PlayLoopedWAV(ptr, length, loopstart, loopend, pitchoffset, + vol, left, right, priority, callbackval); + } + else if (!memcmp("OggS", ptr, 4)) + { + handle = MV_PlayLoopedVorbis(ptr, length, loopstart, loopend, pitchoffset, + vol, left, right, priority, callbackval); + } + + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return handle; +} + +/*--------------------------------------------------------------------- + Function: FX_PlayAuto3D + + Play a positioned sound, autodetecting the format. +---------------------------------------------------------------------*/ +int32_t FX_PlayAuto3D(char *ptr, uint32_t length, int32_t pitchoffset, int32_t angle, + int32_t distance, int32_t priority, uint32_t callbackval) +{ + int32_t handle = -1; + + if (!memcmp("Creative Voice File\x1a", ptr, 20)) + { + handle = MV_PlayVOC3D(ptr, length, pitchoffset, angle, distance, priority, callbackval); + } + else if (!memcmp("RIFF", ptr, 4) && !memcmp("WAVE", ptr + 8, 4)) + { + handle = MV_PlayWAV3D(ptr, length, pitchoffset, angle, distance, priority, callbackval); + } + else if (!memcmp("OggS", ptr, 4)) + { + handle = MV_PlayVorbis3D(ptr, length, pitchoffset, angle, distance, priority, callbackval); + } + + if (handle < MV_Ok) + { + FX_SetErrorCode(FX_MultiVocError); + handle = FX_Warning; + } + + return handle; +} diff --git a/polymer/eduke32/source/jaudiolib/src/linklist.h b/polymer/eduke32/source/jaudiolib/src/linklist.h new file mode 100644 index 000000000..8a7aa5fcc --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/linklist.h @@ -0,0 +1,118 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef __linklist_h +#define __linklist_h +#ifdef __cplusplus +extern "C" { +#endif + + +#define NewNode(type) ((type*)SafeMalloc(sizeof(type))) + + +#define LL_CreateNewLinkedList(rootnode,type,next,prev) \ + { \ + (rootnode) = NewNode(type); \ + (rootnode)->prev = (rootnode); \ + (rootnode)->next = (rootnode); \ + } + + + +#define LL_AddNode(rootnode, newnode, next, prev) \ + { \ + (newnode)->next = (rootnode); \ + (newnode)->prev = (rootnode)->prev; \ + (rootnode)->prev->next = (newnode); \ + (rootnode)->prev = (newnode); \ + } + +#define LL_TransferList(oldroot,newroot,next,prev) \ + { \ + if ((oldroot)->prev != (oldroot)) \ + { \ + (oldroot)->prev->next = (newroot); \ + (oldroot)->next->prev = (newroot)->prev; \ + (newroot)->prev->next = (oldroot)->next; \ + (newroot)->prev = (oldroot)->prev; \ + (oldroot)->next = (oldroot); \ + (oldroot)->prev = (oldroot); \ + } \ + } + +#define LL_ReverseList(root,type,next,prev) \ + { \ + type *newend,*trav,*tprev; \ + \ + newend = (root)->next; \ + for(trav = (root)->prev; trav != newend; trav = tprev) \ + { \ + tprev = trav->prev; \ + LL_MoveNode(trav,newend,next,prev); \ + } \ + } + + +#define LL_RemoveNode(node,next,prev) \ + { \ + (node)->prev->next = (node)->next; \ + (node)->next->prev = (node)->prev; \ + (node)->next = (node); \ + (node)->prev = (node); \ + } + + +#define LL_SortedInsertion(rootnode,insertnode,next,prev,type,sortparm) \ + { \ + type *hoya; \ + \ + hoya = (rootnode)->next; \ + while((hoya != (rootnode)) && ((insertnode)->sortparm > hoya->sortparm)) \ + { \ + hoya = hoya->next; \ + } \ + LL_AddNode(hoya,(insertnode),next,prev); \ + } + +#define LL_MoveNode(node,newroot,next,prev) \ + { \ + LL_RemoveNode((node),next,prev); \ + LL_AddNode((newroot),(node),next,prev); \ + } + +#define LL_ListEmpty(list,next,prev) \ + ( \ + ((list)->next == (list)) && \ + ((list)->prev == (list)) \ + ) + +#define LL_Free(list) SafeFree(list) +#define LL_Reset(list,next,prev) (list)->next = (list)->prev = (list) +#define LL_New LL_CreateNewLinkedList +#define LL_Remove LL_RemoveNode +#define LL_Add LL_AddNode +#define LL_Empty LL_ListEmpty +#define LL_Move LL_MoveNode + + +#ifdef __cplusplus +}; +#endif +#endif diff --git a/polymer/eduke32/source/jaudiolib/src/ll_man.h b/polymer/eduke32/source/jaudiolib/src/ll_man.h new file mode 100644 index 000000000..0fb891ae1 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/ll_man.h @@ -0,0 +1,76 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/********************************************************************** + module: LL_MAN.H + + author: James R. Dose + date: February 4, 1994 + + Public header for LL_MAN.C. Linked list management routines. + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __LL_MAN_H +#define __LL_MAN_H + +enum LL_Errors + { + LL_Warning = -2, + LL_Error = -1, + LL_Ok = 0 + }; + +typedef struct list + { + void *start; + void *end; + } list; + +void LL_AddNode( char *node, char **head, char **tail, int32_t next, int32_t prev ); +void LL_RemoveNode( char *node, char **head, char **tail, int32_t next, int32_t prev ); +void LL_UnlockMemory( void ); +int32_t LL_LockMemory( void ); + +#define LL_AddToHead( type, listhead, node ) \ + LL_AddNode( ( char * )( node ), \ + ( char ** )&( ( listhead )->start ), \ + ( char ** )&( ( listhead )->end ), \ + ( int32_t )&( ( type * ) 0 )->next, \ + ( int32_t )&( ( type * ) 0 )->prev ) + +#define LL_AddToTail( type, listhead, node ) \ + LL_AddNode( ( char * )( node ), \ + ( char ** )&( ( listhead )->end ), \ + ( char ** )&( ( listhead )->start ), \ + ( int32_t )&( ( type * ) 0 )->prev, \ + ( int32_t )&( ( type * ) 0 )->next ) + +#define LL_Remove( type, listhead, node ) \ + LL_RemoveNode( ( char * )( node ), \ + ( char ** )&( ( listhead )->start ), \ + ( char ** )&( ( listhead )->end ), \ + ( int32_t )&( ( type * ) 0 )->next, \ + ( int32_t )&( ( type * ) 0 )->prev ) + +#define LL_NextNode( node ) ( ( node )->next ) +#define LL_PreviousNode( node ) ( ( node )->prev ) + +#endif diff --git a/polymer/eduke32/source/jaudiolib/src/mix.c b/polymer/eduke32/source/jaudiolib/src/mix.c new file mode 100644 index 000000000..24afcafb6 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/mix.c @@ -0,0 +1,353 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +#include "_multivc.h" + +extern char *MV_HarshClipTable; +extern char *MV_MixDestination; // pointer to the next output sample +extern uint32_t MV_MixPosition; // return value of where the source pointer got to +extern int16_t *MV_LeftVolume; +extern int16_t *MV_RightVolume; +extern int32_t MV_SampleSize; +extern int32_t MV_RightChannelOffset; + +#ifdef __POWERPC__ +# define BIGENDIAN +#endif + +void ClearBuffer_DW( void *ptr, unsigned data, int32_t length ) +{ + unsigned *ptrdw = ptr; + while (length--) { + *(ptrdw++) = data; + } +} + +/* + JBF: + + position = offset of starting sample in start + rate = resampling increment + start = sound data + length = count of samples to mix + */ + +// 8-bit mono source, 8-bit mono output +void MV_Mix8BitMono( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint8_t *source = (uint8_t *) start; + uint8_t *dest = (uint8_t *) MV_MixDestination; + int32_t sample0; + + while (length--) { + sample0 = source[position >> 16]; + position += rate; + + sample0 = MV_LeftVolume[sample0] + *dest; + sample0 = MV_HarshClipTable[sample0 + 128]; + + *dest = sample0 & 255; + + dest += MV_SampleSize; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 8-bit mono source, 8-bit stereo output +void MV_Mix8BitStereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint8_t *source = (uint8_t *) start; + uint8_t *dest = (uint8_t *) MV_MixDestination; + int32_t sample0, sample1; + + while (length--) { + sample0 = source[position >> 16]; + sample1 = sample0; + position += rate; + + sample0 = MV_LeftVolume[sample0] + *dest; + sample1 = MV_RightVolume[sample1] + *(dest + MV_RightChannelOffset); + sample0 = MV_HarshClipTable[sample0 + 128]; + sample1 = MV_HarshClipTable[sample1 + 128]; + + *dest = sample0 & 255; + *(dest + MV_RightChannelOffset) = sample1 & 255; + + dest += MV_SampleSize; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 8-bit mono source, 16-bit mono output +void MV_Mix16BitMono( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint8_t *source = (uint8_t *) start; + int16_t *dest = (int16_t *) MV_MixDestination; + int32_t sample0; + + while (length--) { + sample0 = source[position >> 16]; + position += rate; + + sample0 = MV_LeftVolume[sample0] + *dest; + if (sample0 < -32768) sample0 = -32768; + else if (sample0 > 32767) sample0 = 32767; + + *dest = (int16_t) sample0; + + dest += MV_SampleSize / 2; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 8-bit mono source, 16-bit stereo output +void MV_Mix16BitStereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint8_t *source = (uint8_t *) start; + int16_t *dest = (int16_t *) MV_MixDestination; + int32_t sample0, sample1; + + while (length--) { + sample0 = source[position >> 16]; + sample1 = sample0; + position += rate; + + sample0 = MV_LeftVolume[sample0] + *dest; + sample1 = MV_RightVolume[sample1] + *(dest + MV_RightChannelOffset / 2); + if (sample0 < -32768) sample0 = -32768; + else if (sample0 > 32767) sample0 = 32767; + if (sample1 < -32768) sample1 = -32768; + else if (sample1 > 32767) sample1 = 32767; + + *dest = (int16_t) sample0; + *(dest + MV_RightChannelOffset/2) = (int16_t) sample1; + + dest += MV_SampleSize / 2; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 16-bit mono source, 16-bit mono output +void MV_Mix16BitMono16( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint16_t *source = (uint16_t *) start; + int16_t *dest = (int16_t *) MV_MixDestination; + int32_t sample0l, sample0h, sample0; + + while (length--) { + sample0 = source[position >> 16]; +#ifdef BIGENDIAN + sample0l = sample0 >> 8; + sample0h = (sample0 & 255) ^ 128; +#else + sample0l = sample0 & 255; + sample0h = (sample0 >> 8) ^ 128; +#endif + position += rate; + + sample0l = MV_LeftVolume[sample0l] >> 8; + sample0h = MV_LeftVolume[sample0h]; + sample0 = sample0l + sample0h + 128 + *dest; + if (sample0 < -32768) sample0 = -32768; + else if (sample0 > 32767) sample0 = 32767; + + *dest = (int16_t) sample0; + + dest += MV_SampleSize / 2; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 16-bit mono source, 8-bit mono output +void MV_Mix8BitMono16( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + int8_t *source = (int8_t *) start + 1; + uint8_t *dest = (uint8_t *) MV_MixDestination; + int32_t sample0; + + while (length--) { + sample0 = source[(position >> 16) << 1]; + position += rate; + + sample0 = MV_LeftVolume[sample0 + 128] + *dest; + sample0 = MV_HarshClipTable[sample0 + 128]; + + *dest = sample0 & 255; + + dest += MV_SampleSize; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 16-bit mono source, 8-bit stereo output +void MV_Mix8BitStereo16( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + int8_t *source = (int8_t *) start + 1; + uint8_t *dest = (uint8_t *) MV_MixDestination; + int32_t sample0, sample1; + + while (length--) { + sample0 = source[(position >> 16) << 1]; + sample1 = sample0; + position += rate; + + sample0 = MV_LeftVolume[sample0 + 128] + *dest; + sample1 = MV_RightVolume[sample1 + 128] + *(dest + MV_RightChannelOffset); + sample0 = MV_HarshClipTable[sample0 + 128]; + sample1 = MV_HarshClipTable[sample1 + 128]; + + *dest = sample0 & 255; + *(dest + MV_RightChannelOffset) = sample1 & 255; + + dest += MV_SampleSize; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 16-bit mono source, 16-bit stereo output +void MV_Mix16BitStereo16( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint16_t *source = (uint16_t *) start; + int16_t *dest = (int16_t *) MV_MixDestination; + int32_t sample0l, sample0h, sample0; + int32_t sample1l, sample1h, sample1; + + while (length--) { + sample0 = source[position >> 16]; +#ifdef BIGENDIAN + sample0l = sample0 >> 8; + sample0h = (sample0 & 255) ^ 128; +#else + sample0l = sample0 & 255; + sample0h = (sample0 >> 8) ^ 128; +#endif + sample1l = sample0l; + sample1h = sample0h; + position += rate; + + sample0l = MV_LeftVolume[sample0l] >> 8; + sample0h = MV_LeftVolume[sample0h]; + sample1l = MV_RightVolume[sample1l] >> 8; + sample1h = MV_RightVolume[sample1h]; + sample0 = sample0l + sample0h + 128 + *dest; + sample1 = sample1l + sample1h + 128 + *(dest + MV_RightChannelOffset/2); + if (sample0 < -32768) sample0 = -32768; + else if (sample0 > 32767) sample0 = 32767; + if (sample1 < -32768) sample1 = -32768; + else if (sample1 > 32767) sample1 = 32767; + + *dest = (int16_t) sample0; + *(dest + MV_RightChannelOffset/2) = (int16_t) sample1; + + dest += MV_SampleSize / 2; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +void MV_16BitReverb( char *src, char *dest, VOLUME16 *volume, int32_t count ) +{ + uint16_t * input = (uint16_t *) src; + int16_t * output = (int16_t *) dest; + int16_t sample0l, sample0h, sample0; + + do { + sample0 = *input; +#ifdef BIGENDIAN + sample0l = sample0 >> 8; + sample0h = (sample0 & 255) ^ 128; +#else + sample0l = sample0 & 255; + sample0h = (sample0 >> 8) ^ 128; +#endif + + sample0l = ((int16_t *) volume)[sample0l] >> 8; + sample0h = ((int16_t *) volume)[sample0h]; + *output = (int16_t) (sample0l + sample0h + 128); + + input++; + output++; + } while (count-- > 0); +} + +void MV_8BitReverb( int8_t *src, int8_t *dest, VOLUME16 *volume, int32_t count ) +{ + uint8_t * input = (uint8_t *) src; + uint8_t * output = (uint8_t *) dest; + + do { + *output = ((int16_t *) volume)[*input] + 128; + + input++; + output++; + } while (count-- > 0); +} + +void MV_16BitReverbFast( char *src, char *dest, int32_t count, int32_t shift ) +{ + int16_t * input = (int16_t *) src; + int16_t * output = (int16_t *) dest; + + do { + *output = *input >> shift; + + input++; + output++; + } while (count-- > 0); +} + +void MV_8BitReverbFast( int8_t *src, int8_t *dest, int32_t count, int32_t shift ) +{ + uint8_t sample0, c; + + c = 128 - (128 >> shift); + + do { + sample0 = *((uint8_t *) src) >> shift; + *dest = sample0 + c + ((sample0 ^ 128) >> 7); + + src++; + dest++; + } while (count-- > 0); +} + diff --git a/polymer/eduke32/source/jaudiolib/src/mixst.c b/polymer/eduke32/source/jaudiolib/src/mixst.c new file mode 100644 index 000000000..e9ea69893 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/mixst.c @@ -0,0 +1,297 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +#include "_multivc.h" + +extern char *MV_HarshClipTable; +extern char *MV_MixDestination; // pointer to the next output sample +extern uint32_t MV_MixPosition; // return value of where the source pointer got to +extern int16_t *MV_LeftVolume; +extern int16_t *MV_RightVolume; +extern int32_t MV_SampleSize; +extern int32_t MV_RightChannelOffset; + +#ifdef __POWERPC__ +# define BIGENDIAN +#endif + +/* + JBF: + + position = offset of starting sample in start + rate = resampling increment + start = sound data + length = count of samples to mix + */ + +// 8-bit stereo source, 8-bit mono output +void MV_Mix8BitMono8Stereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint8_t *source = (uint8_t *) start; + uint8_t *dest = (uint8_t *) MV_MixDestination; + int32_t sample0, sample1; + + while (length--) { + sample0 = source[(position >> 16) << 1]; + sample1 = source[((position >> 16) << 1) + 1]; + position += rate; + + sample0 = (MV_LeftVolume[sample0] + MV_LeftVolume[sample1]) / 2 + *dest; + sample0 = MV_HarshClipTable[sample0 + 128]; + + *dest = sample0 & 255; + + dest += MV_SampleSize; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 8-bit stereo source, 8-bit stereo output +void MV_Mix8BitStereo8Stereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint8_t *source = (uint8_t *) start; + uint8_t *dest = (uint8_t *) MV_MixDestination; + int32_t sample0, sample1; + + while (length--) { + sample0 = source[(position >> 16) << 1]; + sample1 = source[((position >> 16) << 1) + 1]; + position += rate; + + sample0 = MV_LeftVolume[sample0] + *dest; + sample1 = MV_RightVolume[sample1] + *(dest + MV_RightChannelOffset); + sample0 = MV_HarshClipTable[sample0 + 128]; + sample1 = MV_HarshClipTable[sample1 + 128]; + + *dest = sample0 & 255; + *(dest + MV_RightChannelOffset) = sample1 & 255; + + dest += MV_SampleSize; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 8-bit stereo source, 16-bit mono output +void MV_Mix16BitMono8Stereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint8_t *source = (uint8_t *) start; + int16_t *dest = (int16_t *) MV_MixDestination; + int32_t sample0, sample1; + + while (length--) { + sample0 = source[(position >> 16) << 1]; + sample1 = source[((position >> 16) << 1) + 1]; + position += rate; + + sample0 = (MV_LeftVolume[sample0] + MV_LeftVolume[sample1]) / 2 + *dest; + if (sample0 < -32768) sample0 = -32768; + else if (sample0 > 32767) sample0 = 32767; + + *dest = (int16_t) sample0; + + dest += MV_SampleSize / 2; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 8-bit stereo source, 16-bit stereo output +void MV_Mix16BitStereo8Stereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint8_t *source = (uint8_t *) start; + int16_t *dest = (int16_t *) MV_MixDestination; + int32_t sample0, sample1; + + while (length--) { + sample0 = source[(position >> 16) << 1]; + sample1 = source[((position >> 16) << 1) + 1]; + position += rate; + + sample0 = MV_LeftVolume[sample0] + *dest; + sample1 = MV_RightVolume[sample1] + *(dest + MV_RightChannelOffset / 2); + if (sample0 < -32768) sample0 = -32768; + else if (sample0 > 32767) sample0 = 32767; + if (sample1 < -32768) sample1 = -32768; + else if (sample1 > 32767) sample1 = 32767; + + *dest = (int16_t) sample0; + *(dest + MV_RightChannelOffset/2) = (int16_t) sample1; + + dest += MV_SampleSize / 2; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 16-bit stereo source, 16-bit mono output +void MV_Mix16BitMono16Stereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint16_t *source = (uint16_t *) start; + int16_t *dest = (int16_t *) MV_MixDestination; + int32_t sample0l, sample0h, sample0; + int32_t sample1l, sample1h, sample1; + + while (length--) { + sample0 = source[(position >> 16) << 1]; + sample1 = source[((position >> 16) << 1) + 1]; +#ifdef BIGENDIAN + sample0l = sample0 >> 8; + sample0h = (sample0 & 255) ^ 128; + sample1l = sample1 >> 8; + sample1h = (sample1 & 255) ^ 128; +#else + sample0l = sample0 & 255; + sample0h = (sample0 >> 8) ^ 128; + sample1l = sample1 & 255; + sample1h = (sample1 >> 8) ^ 128; +#endif + position += rate; + + sample0l = MV_LeftVolume[sample0l] >> 8; + sample0h = MV_LeftVolume[sample0h]; + sample0 = sample0l + sample0h + 128; + sample1l = MV_LeftVolume[sample1l] >> 8; + sample1h = MV_LeftVolume[sample1h]; + sample1 = sample1l + sample1h + 128; + + sample0 = (sample0 + sample1) / 2 + *dest; + if (sample0 < -32768) sample0 = -32768; + else if (sample0 > 32767) sample0 = 32767; + + *dest = (int16_t) sample0; + + dest += MV_SampleSize / 2; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 16-bit stereo source, 8-bit mono output +void MV_Mix8BitMono16Stereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + int8_t *source = (int8_t *) start + 1; + uint8_t *dest = (uint8_t *) MV_MixDestination; + int32_t sample0, sample1; + + while (length--) { + sample0 = source[(position >> 16) << 2]; + sample1 = source[((position >> 16) << 2) + 2]; + position += rate; + + sample0 = MV_LeftVolume[sample0 + 128]; + sample1 = MV_LeftVolume[sample1 + 128]; + sample0 = (sample0 + sample1) / 2 + *dest; + sample0 = MV_HarshClipTable[sample0 + 128]; + + *dest = sample0 & 255; + + dest += MV_SampleSize; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 16-bit stereo source, 8-bit stereo output +void MV_Mix8BitStereo16Stereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + int8_t *source = (int8_t *) start + 1; + uint8_t *dest = (uint8_t *) MV_MixDestination; + int32_t sample0, sample1; + + while (length--) { + sample0 = source[(position >> 16) << 2]; + sample1 = source[((position >> 16) << 2) + 2]; + position += rate; + + sample0 = MV_LeftVolume[sample0 + 128] + *dest; + sample1 = MV_RightVolume[sample1 + 128] + *(dest + MV_RightChannelOffset); + sample0 = MV_HarshClipTable[sample0 + 128]; + sample1 = MV_HarshClipTable[sample1 + 128]; + + *dest = sample0 & 255; + *(dest + MV_RightChannelOffset) = sample1 & 255; + + dest += MV_SampleSize; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} + +// 16-bit stereo source, 16-bit stereo output +void MV_Mix16BitStereo16Stereo( uint32_t position, uint32_t rate, + char *start, uint32_t length ) +{ + uint16_t *source = (uint16_t *) start; + int16_t *dest = (int16_t *) MV_MixDestination; + int32_t sample0l, sample0h, sample0; + int32_t sample1l, sample1h, sample1; + + while (length--) { + sample0 = source[(position >> 16) << 1]; + sample1 = source[((position >> 16) << 1) + 1]; +#ifdef BIGENDIAN + sample0l = sample0 >> 8; + sample0h = (sample0 & 255) ^ 128; + sample1l = sample1 >> 8; + sample1h = (sample1 & 255) ^ 128; +#else + sample0l = sample0 & 255; + sample0h = (sample0 >> 8) ^ 128; + sample1l = sample1 & 255; + sample1h = (sample1 >> 8) ^ 128; +#endif + position += rate; + + sample0l = MV_LeftVolume[sample0l] >> 8; + sample0h = MV_LeftVolume[sample0h]; + sample1l = MV_RightVolume[sample1l] >> 8; + sample1h = MV_RightVolume[sample1h]; + sample0 = sample0l + sample0h + 128 + *dest; + sample1 = sample1l + sample1h + 128 + *(dest + MV_RightChannelOffset/2); + if (sample0 < -32768) sample0 = -32768; + else if (sample0 > 32767) sample0 = 32767; + if (sample1 < -32768) sample1 = -32768; + else if (sample1 > 32767) sample1 = 32767; + + *dest = (int16_t) sample0; + *(dest + MV_RightChannelOffset/2) = (int16_t) sample1; + + dest += MV_SampleSize / 2; + } + + MV_MixPosition = position; + MV_MixDestination = (char *) dest; +} diff --git a/polymer/eduke32/source/jaudiolib/src/multivoc.c b/polymer/eduke32/source/jaudiolib/src/multivoc.c new file mode 100644 index 000000000..f2fad54f2 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/multivoc.c @@ -0,0 +1,2910 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/********************************************************************** + module: MULTIVOC.C + + author: James R. Dose + date: December 20, 1993 + + Routines to provide multichannel digitized sound playback for + Sound Blaster compatible sound cards. + + (c) Copyright 1993 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#include +#include +#include +#include +#include +#include "linklist.h" +#include "sndcards.h" +#include "drivers.h" +#include "pitch.h" +#include "multivoc.h" +#include "_multivc.h" + +#ifdef __POWERPC__ +#define LITTLE16 SWAP16 +#define LITTLE32 SWAP32 +#else +#define LITTLE16 +#define LITTLE32 +#endif + +static inline uint16_t SWAP16(uint16_t s) +{ + return (s >> 8) | (s << 8); +} + +static inline uint32_t SWAP32(uint32_t s) +{ + return (s >> 24) | (s << 24) | ((s&0xff00) << 8) | ((s & 0xff0000) >> 8); +} + +#define min(x,y) ((x) < (y) ? (x) : (y)) +#define max(x,y) ((x) > (y) ? (x) : (y)) + +#define RoundFixed( fixedval, bits ) \ + ( \ + ( \ + (fixedval) + ( 1 << ( (bits) - 1 ) )\ + ) >> (bits) \ + ) + +#define IS_QUIET( ptr ) ( ( void * )( ptr ) == ( void * )&MV_VolumeTable[ 0 ] ) + +static int32_t MV_ReverbLevel; +static int32_t MV_ReverbDelay; +static VOLUME16 *MV_ReverbTable = NULL; + +//static int16_t MV_VolumeTable[ MV_MaxVolume + 1 ][ 256 ]; +static int16_t MV_VolumeTable[ 255 + 1 ][ 256 ]; + +//static Pan MV_PanTable[ MV_NumPanPositions ][ MV_MaxVolume + 1 ]; +Pan MV_PanTable[ MV_NumPanPositions ][ 255 + 1 ]; + +int32_t MV_Installed = FALSE; +static int32_t MV_TotalVolume = MV_MaxTotalVolume; +static int32_t MV_MaxVoices = 1; +static int32_t MV_Recording; + +static int32_t MV_BufferSize = MixBufferSize; +static int32_t MV_BufferLength; + +static int32_t MV_NumberOfBuffers = NumberOfBuffers; + +static int32_t MV_MixMode = MONO_8BIT; +static int32_t MV_Channels = 1; +static int32_t MV_Bits = 8; + +static int32_t MV_Silence = SILENCE_8BIT; +static int32_t MV_SwapLeftRight = FALSE; + +static int32_t MV_RequestedMixRate; +int32_t MV_MixRate; + +static int32_t MV_BuffShift; + +static int32_t MV_TotalMemory; + +static int32_t MV_BufferEmpty[ NumberOfBuffers ]; +char *MV_MixBuffer[ NumberOfBuffers + 1 ]; + +static VoiceNode *MV_Voices = NULL; + +static volatile VoiceNode VoiceList; +static volatile VoiceNode VoicePool; + +static int32_t MV_MixPage = 0; +static int32_t MV_VoiceHandle = MV_MinVoiceHandle; + +static void (*MV_CallBackFunc)(uint32_t) = NULL; +static void (*MV_RecordFunc)(char *ptr, int32_t length) = NULL; +static void (*MV_MixFunction)(VoiceNode *voice, int32_t buffer); + +int32_t MV_MaxVolume = 255; + +char *MV_HarshClipTable; +char *MV_MixDestination; +int16_t *MV_LeftVolume; +int16_t *MV_RightVolume; +int32_t MV_SampleSize = 1; +int32_t MV_RightChannelOffset; + +uint32_t MV_MixPosition; + +int32_t MV_ErrorCode = MV_Ok; + +static int32_t lockdepth = 0; +static int32_t DisableInterrupts(void) +{ + if (lockdepth++ > 0) + { + return 0; + } + SoundDriver_Lock(); + return 0; +} + +static void RestoreInterrupts(int32_t a) +{ + if (--lockdepth > 0) + { + return; + } + SoundDriver_Unlock(); +} + + +/*--------------------------------------------------------------------- + Function: MV_ErrorString + + Returns a pointer to the error message associated with an error + number. A -1 returns a pointer the current error. +---------------------------------------------------------------------*/ + +const char *MV_ErrorString +( + int32_t ErrorNumber +) + +{ + const char *ErrorString; + + switch (ErrorNumber) + { + case MV_Warning : + case MV_Error : + ErrorString = MV_ErrorString(MV_ErrorCode); + break; + + case MV_Ok : + ErrorString = "Multivoc ok."; + break; + + case MV_UnsupportedCard : + ErrorString = "Selected sound card is not supported by Multivoc."; + break; + + case MV_NotInstalled : + ErrorString = "Multivoc not installed."; + break; + + case MV_DriverError : + ErrorString = SoundDriver_ErrorString(SoundDriver_GetError()); + break; + + case MV_NoVoices : + ErrorString = "No free voices available to Multivoc."; + break; + + case MV_NoMem : + ErrorString = "Out of memory in Multivoc."; + break; + + case MV_VoiceNotFound : + ErrorString = "No voice with matching handle found."; + break; + + case MV_InvalidVOCFile : + ErrorString = "Invalid VOC file passed in to Multivoc."; + break; + + case MV_InvalidWAVFile : + ErrorString = "Invalid WAV file passed in to Multivoc."; + break; + + case MV_InvalidVorbisFile : + ErrorString = "Invalid OggVorbis file passed in to Multivoc."; + break; + + case MV_InvalidMixMode : + ErrorString = "Invalid mix mode request in Multivoc."; + break; + + case MV_NullRecordFunction : + ErrorString = "Null record function passed to MV_StartRecording."; + break; + + default : + ErrorString = "Unknown Multivoc error code."; + break; + } + + return(ErrorString); +} + + +/*--------------------------------------------------------------------- + Function: MV_Mix + + Mixes the sound into the buffer. +---------------------------------------------------------------------*/ + +static void MV_Mix +( + VoiceNode *voice, + int32_t buffer +) + +{ + char *start; + int32_t length; + int32_t voclength; + uint32_t position; + uint32_t rate; + uint32_t FixedPointBufferSize; + + if ((voice->length == 0) && (voice->GetSound(voice) != KeepPlaying)) + { + return; + } + + length = MixBufferSize; + FixedPointBufferSize = voice->FixedPointBufferSize; + + MV_MixDestination = MV_MixBuffer[ buffer ]; + MV_LeftVolume = voice->LeftVolume; + MV_RightVolume = voice->RightVolume; + + if ((MV_Channels == 2) && (IS_QUIET(MV_LeftVolume))) + { + MV_LeftVolume = MV_RightVolume; + MV_MixDestination += MV_RightChannelOffset; + } + + // Add this voice to the mix + while (length > 0) + { + start = voice->sound; + rate = voice->RateScale; + position = voice->position; + + // Check if the last sample in this buffer would be + // beyond the length of the sample block + if ((position + FixedPointBufferSize) >= voice->length) + { + if (position < voice->length) + { + voclength = (voice->length - position + rate - voice->channels) / rate; + } + else + { + voice->GetSound(voice); + return; + } + } + else + { + voclength = length; + } + + if (voice->mix) + { + voice->mix(position, rate, start, voclength); + } + + voice->position = MV_MixPosition; + + length -= voclength; + + if (voice->position >= voice->length) + { + // Get the next block of sound + if (voice->GetSound(voice) != KeepPlaying) + { + return; + } + + if (length > 0) + { + // Get the position of the last sample in the buffer + FixedPointBufferSize = voice->RateScale * (length - voice->channels); + } + } + } +} + + +/*--------------------------------------------------------------------- + Function: MV_PlayVoice + + Adds a voice to the play list. +---------------------------------------------------------------------*/ + +void MV_PlayVoice +( + VoiceNode *voice +) + +{ + int32_t flags; + + flags = DisableInterrupts(); + LL_SortedInsertion(&VoiceList, voice, prev, next, VoiceNode, priority); + + RestoreInterrupts(flags); +} + + +/*--------------------------------------------------------------------- + Function: MV_StopVoice + + Removes the voice from the play list and adds it to the free list. +---------------------------------------------------------------------*/ + +void MV_StopVoice +( + VoiceNode *voice +) + +{ + int32_t flags; + + flags = DisableInterrupts(); + + // move the voice from the play list to the free list + LL_Remove(voice, next, prev); + LL_Add((VoiceNode*) &VoicePool, voice, next, prev); + + RestoreInterrupts(flags); + + if (voice->wavetype == Vorbis) + { + MV_ReleaseVorbisVoice(voice); + } +} + + +/*--------------------------------------------------------------------- + Function: MV_ServiceVoc + + Starts playback of the waiting buffer and mixes the next one. + + JBF: no synchronisation happens inside MV_ServiceVoc nor the + supporting functions it calls. This would cause a deadlock + between the mixer thread in the driver vs the nested + locking in the user-space functions of MultiVoc. The call + to MV_ServiceVoc is synchronised in the driver. + + Known functions called by MV_ServiceVoc and its helpers: + MV_Mix (and its MV_Mix*bit* workers) + MV_GetNextVOCBlock + MV_GetNextWAVBlock + MV_SetVoiceMixMode +---------------------------------------------------------------------*/ +void MV_ServiceVoc +( + void +) + +{ + VoiceNode *voice; + VoiceNode *next; + char *buffer; + //int32_t flags; + + // Toggle which buffer we'll mix next + MV_MixPage++; + if (MV_MixPage >= MV_NumberOfBuffers) + { + MV_MixPage -= MV_NumberOfBuffers; + } + + if (MV_ReverbLevel == 0) + { + // Initialize buffer + //Commented out so that the buffer is always cleared. + //This is so the guys at Echo Speech can mix into the + //buffer even when no sounds are playing. + //if ( !MV_BufferEmpty[ MV_MixPage ] ) + { + ClearBuffer_DW(MV_MixBuffer[ MV_MixPage ], MV_Silence, MV_BufferSize >> 2); + MV_BufferEmpty[ MV_MixPage ] = TRUE; + } + } + else + { + char *end; + char *source; + char *dest; + int32_t count; + int32_t length; + + end = MV_MixBuffer[ 0 ] + MV_BufferLength;; + dest = MV_MixBuffer[ MV_MixPage ]; + source = MV_MixBuffer[ MV_MixPage ] - MV_ReverbDelay; + if (source < MV_MixBuffer[ 0 ]) + { + source += MV_BufferLength; + } + + length = MV_BufferSize; + while (length > 0) + { + count = length; + if (source + count > end) + { + count = end - source; + } + + if (MV_Bits == 16) + { + if (MV_ReverbTable != NULL) + { + MV_16BitReverb(source, dest, MV_ReverbTable, count / 2); + } + else + { + MV_16BitReverbFast(source, dest, count / 2, MV_ReverbLevel); + } + } + else + { + if (MV_ReverbTable != NULL) + { + MV_8BitReverb((int8_t *) source, (int8_t *) dest, MV_ReverbTable, count); + } + else + { + MV_8BitReverbFast((int8_t *) source, (int8_t *) dest, count, MV_ReverbLevel); + } + } + + // if we go through the loop again, it means that we've wrapped around the buffer + source = MV_MixBuffer[ 0 ]; + dest += count; + length -= count; + } + } + + // Play any waiting voices + //flags = DisableInterrupts(); + + if (!VoiceList.next) + return; + + for (voice = VoiceList.next; voice != &VoiceList; voice = next) + { + + MV_BufferEmpty[ MV_MixPage ] = FALSE; + + if (!voice->Paused) + MV_MixFunction(voice, MV_MixPage); + + next = voice->next; + + // Is this voice done? + if (!voice->Playing && !voice->Paused) + { + //JBF: prevent a deadlock caused by MV_StopVoice grabbing the mutex again + //MV_StopVoice( voice ); + LL_Remove(voice, next, prev); + LL_Add((VoiceNode*) &VoicePool, voice, next, prev); + + if (MV_CallBackFunc) + { + MV_CallBackFunc(voice->callbackval); + } + } + } + + //RestoreInterrupts(flags); +} + + +/*--------------------------------------------------------------------- + Function: MV_GetNextVOCBlock + + Interperate the information of a VOC format sound file. +---------------------------------------------------------------------*/ + +playbackstatus MV_GetNextVOCBlock +( + VoiceNode *voice +) + +{ + uint8_t *ptr; + int32_t blocktype; + int32_t lastblocktype; + uint32_t blocklength; + uint32_t samplespeed; + uint32_t tc; + int32_t packtype; + int32_t voicemode; + int32_t done; + unsigned BitsPerSample; + unsigned Channels; + unsigned Format; + + if (voice->BlockLength > 0) + { + voice->position -= voice->length; + voice->sound += (voice->length >> 16) * (voice->channels * voice->bits / 8); + voice->length = min(voice->BlockLength, 0x8000); + voice->BlockLength -= voice->length; + voice->length <<= 16; + return(KeepPlaying); + } + + ptr = (uint8_t *)voice->NextBlock; + + voice->Playing = TRUE; + voice->Paused = FALSE; + + voicemode = 0; + lastblocktype = 0; + packtype = 0; + + done = FALSE; + while (!done) + { + // Stop playing if we get a NULL pointer + if (ptr == NULL) + { + voice->Playing = FALSE; + done = TRUE; + break; + } + + blocktype = (int32_t)*ptr; + blocklength = LITTLE32(*(uint32_t *)(ptr + 1)) & 0x00ffffff; + ptr += 4; + + switch (blocktype) + { + case 0 : + // End of data + if ((voice->LoopStart == NULL) || + ((intptr_t) voice->LoopStart >= ((intptr_t) ptr - 4))) + { + voice->Playing = FALSE; + done = TRUE; + } + else + { + voice->NextBlock = voice->LoopStart; + voice->BlockLength = 0; + voice->position = 0; + return MV_GetNextVOCBlock(voice); + } + break; + + case 1 : + // Sound data block + voice->bits = 8; + voice->channels = voicemode + 1; + if (lastblocktype != 8) + { + tc = (uint32_t)*ptr << 8; + packtype = *(ptr + 1); + } + + ptr += 2; + blocklength -= 2; + + samplespeed = 256000000L / (voice->channels * (65536 - tc)); + + // Skip packed or stereo data + if ((packtype != 0) || (voicemode != 0 && voicemode != 1)) + { + ptr += blocklength; + } + else + { + done = TRUE; + } + voicemode = 0; + break; + + case 2 : + // Sound continuation block + samplespeed = voice->SamplingRate; + done = TRUE; + break; + + case 3 : + // Silence + // Not implimented. + ptr += blocklength; + break; + + case 4 : + // Marker + // Not implimented. + ptr += blocklength; + break; + + case 5 : + // ASCII string + // Not implimented. + ptr += blocklength; + break; + + case 6 : + // Repeat begin + if (voice->LoopEnd == NULL) + { + voice->LoopCount = LITTLE16(*(uint16_t *)ptr); + voice->LoopStart = (char *)((intptr_t) ptr + blocklength); + } + ptr += blocklength; + break; + + case 7 : + // Repeat end + ptr += blocklength; + if (lastblocktype == 6) + { + voice->LoopCount = 0; + } + else + { + if ((voice->LoopCount > 0) && (voice->LoopStart != NULL)) + { + ptr = (uint8_t *) voice->LoopStart; + if (voice->LoopCount < 0xffff) + { + voice->LoopCount--; + if (voice->LoopCount == 0) + { + voice->LoopStart = NULL; + } + } + } + } + break; + + case 8 : + // Extended block + voice->bits = 8; + voice->channels = 1; + tc = LITTLE16(*(uint16_t *)ptr); + packtype = *(ptr + 2); + voicemode = *(ptr + 3); + ptr += blocklength; + break; + + case 9 : + // New sound data block + samplespeed = LITTLE32(*(uint32_t *)ptr); + BitsPerSample = (unsigned)*(ptr + 4); + Channels = (unsigned)*(ptr + 5); + Format = (unsigned)LITTLE16(*(uint16_t *)(ptr + 6)); + + if ((BitsPerSample == 8) && (Channels == 1 || Channels == 2) && + (Format == VOC_8BIT)) + { + ptr += 12; + blocklength -= 12; + voice->bits = 8; + voice->channels = Channels; + done = TRUE; + } + else if ((BitsPerSample == 16) && (Channels == 1 || Channels == 2) && + (Format == VOC_16BIT)) + { + ptr += 12; + blocklength -= 12; + voice->bits = 16; + voice->channels = Channels; + done = TRUE; + } + else + { + ptr += blocklength; + } + break; + + default : + // Unknown data. Probably not a VOC file. + voice->Playing = FALSE; + done = TRUE; + break; + } + + lastblocktype = blocktype; + } + + if (voice->Playing) + { + voice->NextBlock = (char *)ptr + blocklength; + voice->sound = (char *)ptr; + + voice->SamplingRate = samplespeed; + voice->RateScale = (voice->SamplingRate * voice->PitchScale) / MV_MixRate; + + // Multiply by MixBufferSize - 1 + voice->FixedPointBufferSize = (voice->RateScale * MixBufferSize) - + voice->RateScale; + + if (voice->LoopEnd != NULL) + { + if (blocklength > (uint32_t)voice->LoopEnd) + { + blocklength = (uint32_t)voice->LoopEnd; + } + else + { + voice->LoopEnd = (char *)blocklength; + } + + voice->LoopStart = voice->sound + (uint32_t)voice->LoopStart; + voice->LoopEnd = voice->sound + (uint32_t)voice->LoopEnd; + voice->LoopSize = voice->LoopEnd - voice->LoopStart; + } + + if (voice->bits == 16) + { + blocklength /= 2; + } + if (voice->channels == 2) + { + blocklength /= 2; + } + + voice->position = 0; + voice->length = min(blocklength, 0x8000); + voice->BlockLength = blocklength - voice->length; + voice->length <<= 16; + + MV_SetVoiceMixMode(voice); + + return(KeepPlaying); + } + + return(NoMoreData); +} + + +/*--------------------------------------------------------------------- + Function: MV_GetNextDemandFeedBlock + + Controls playback of demand fed data. +---------------------------------------------------------------------*/ + +playbackstatus MV_GetNextDemandFeedBlock +( + VoiceNode *voice +) + +{ + if (voice->BlockLength > 0) + { + voice->position -= voice->length; + voice->sound += voice->length >> 16; + voice->length = min(voice->BlockLength, 0x8000); + voice->BlockLength -= voice->length; + voice->length <<= 16; + + return(KeepPlaying); + } + + if (voice->DemandFeed == NULL) + { + return(NoMoreData); + } + + voice->position = 0; + (voice->DemandFeed)(&voice->sound, &voice->BlockLength); + voice->length = min(voice->BlockLength, 0x8000); + voice->BlockLength -= voice->length; + voice->length <<= 16; + + if ((voice->length > 0) && (voice->sound != NULL)) + { + return(KeepPlaying); + } + return(NoMoreData); +} + + +/*--------------------------------------------------------------------- + Function: MV_GetNextRawBlock + + Controls playback of demand fed data. +---------------------------------------------------------------------*/ + +playbackstatus MV_GetNextRawBlock +( + VoiceNode *voice +) + +{ + if (voice->BlockLength <= 0) + { + if (voice->LoopStart == NULL) + { + voice->Playing = FALSE; + return(NoMoreData); + } + + voice->BlockLength = voice->LoopSize; + voice->NextBlock = voice->LoopStart; + voice->length = 0; + voice->position = 0; + } + + voice->sound = voice->NextBlock; + voice->position -= voice->length; + voice->length = min(voice->BlockLength, 0x8000); + voice->NextBlock += voice->length * (voice->channels * voice->bits / 8); + voice->BlockLength -= voice->length; + voice->length <<= 16; + + return(KeepPlaying); +} + + +/*--------------------------------------------------------------------- + Function: MV_GetNextWAVBlock + + Controls playback of demand fed data. +---------------------------------------------------------------------*/ + +playbackstatus MV_GetNextWAVBlock +( + VoiceNode *voice +) + +{ + if (voice->BlockLength <= 0) + { + if (voice->LoopStart == NULL) + { + voice->Playing = FALSE; + return(NoMoreData); + } + + voice->BlockLength = voice->LoopSize; + voice->NextBlock = voice->LoopStart; + voice->length = 0; + voice->position = 0; + } + + voice->sound = voice->NextBlock; + voice->position -= voice->length; + voice->length = min(voice->BlockLength, 0x8000); + voice->NextBlock += voice->length * (voice->channels * voice->bits / 8); + voice->BlockLength -= voice->length; + voice->length <<= 16; + + return(KeepPlaying); +} + + +/*--------------------------------------------------------------------- + Function: MV_ServiceRecord + + Starts recording of the waiting buffer. +---------------------------------------------------------------------*/ + +static void MV_ServiceRecord +( + void +) + +{ + if (MV_RecordFunc) + { + MV_RecordFunc(MV_MixBuffer[ 0 ] + MV_MixPage * MixBufferSize, + MixBufferSize); + } + + // Toggle which buffer we'll mix next + MV_MixPage++; + if (MV_MixPage >= NumberOfBuffers) + { + MV_MixPage = 0; + } +} + + +/*--------------------------------------------------------------------- + Function: MV_GetVoice + + Locates the voice with the specified handle. +---------------------------------------------------------------------*/ + +VoiceNode *MV_GetVoice +( + int32_t handle +) + +{ + VoiceNode *voice; + int32_t flags; + + flags = DisableInterrupts(); + + for (voice = VoiceList.next; voice != &VoiceList; voice = voice->next) + { + if (handle == voice->handle) + { + break; + } + } + + RestoreInterrupts(flags); + + if (voice == &VoiceList) + { + MV_SetErrorCode(MV_VoiceNotFound); + voice = 0; + } + + return(voice); +} + + +/*--------------------------------------------------------------------- + Function: MV_VoicePlaying + + Checks if the voice associated with the specified handle is + playing. +---------------------------------------------------------------------*/ + +int32_t MV_VoicePlaying +( + int32_t handle +) + +{ + VoiceNode *voice; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(FALSE); + } + + voice = MV_GetVoice(handle); + + if (voice == NULL) + { + return(FALSE); + } + + return(TRUE); +} + + +/*--------------------------------------------------------------------- + Function: MV_KillAllVoices + + Stops output of all currently active voices. +---------------------------------------------------------------------*/ + +int32_t MV_KillAllVoices +( + void +) + +{ + VoiceNode * voice, * next; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + // Remove all the voices from the list + for (voice = VoiceList.next; voice != &VoiceList; voice = next) + { + next = voice->next; + if (voice->priority < MV_MUSIC_PRIORITY) + { + MV_Kill(voice->handle); + } + } + + return(MV_Ok); +} + + +/*--------------------------------------------------------------------- + Function: MV_Kill + + Stops output of the voice associated with the specified handle. +---------------------------------------------------------------------*/ + +int32_t MV_Kill +( + int32_t handle +) + +{ + VoiceNode *voice; + int32_t flags; + uint32_t callbackval; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + flags = DisableInterrupts(); + + voice = MV_GetVoice(handle); + if (voice == NULL) + { + RestoreInterrupts(flags); + MV_SetErrorCode(MV_VoiceNotFound); + return(MV_Error); + } + + callbackval = voice->callbackval; + + MV_StopVoice(voice); + + RestoreInterrupts(flags); + + if (MV_CallBackFunc) + { + MV_CallBackFunc(callbackval); + } + + return(MV_Ok); +} + + +/*--------------------------------------------------------------------- + Function: MV_VoicesPlaying + + Determines the number of currently active voices. +---------------------------------------------------------------------*/ + +int32_t MV_VoicesPlaying +( + void +) + +{ + VoiceNode *voice; + int32_t NumVoices = 0; + int32_t flags; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(0); + } + + flags = DisableInterrupts(); + + for (voice = VoiceList.next; voice != &VoiceList; voice = voice->next) + { + NumVoices++; + } + + RestoreInterrupts(flags); + + return(NumVoices); +} + + +/*--------------------------------------------------------------------- + Function: MV_AllocVoice + + Retrieve an inactive or lower priority voice for output. +---------------------------------------------------------------------*/ + +VoiceNode *MV_AllocVoice +( + int32_t priority +) + +{ + VoiceNode *voice; + VoiceNode *node; + int32_t flags; + +//return( NULL ); + if (MV_Recording) + { + return(NULL); + } + + flags = DisableInterrupts(); + + // Check if we have any free voices + if (LL_Empty(&VoicePool, next, prev)) + { + // check if we have a higher priority than a voice that is playing. + voice = VoiceList.next; + for (node = voice->next; node != &VoiceList; node = node->next) + { + if (node->priority < voice->priority) + { + voice = node; + } + } + + if (priority >= voice->priority) + { + MV_Kill(voice->handle); + } + } + + // Check if any voices are in the voice pool + if (LL_Empty(&VoicePool, next, prev)) + { + // No free voices + RestoreInterrupts(flags); + return(NULL); + } + + voice = VoicePool.next; + LL_Remove(voice, next, prev); + RestoreInterrupts(flags); + + // Find a free voice handle + do + { + MV_VoiceHandle++; + if (MV_VoiceHandle < MV_MinVoiceHandle) + { + MV_VoiceHandle = MV_MinVoiceHandle; + } + } + while (MV_VoicePlaying(MV_VoiceHandle)); + + voice->handle = MV_VoiceHandle; + + return(voice); +} + + +/*--------------------------------------------------------------------- + Function: MV_VoiceAvailable + + Checks if a voice can be play at the specified priority. +---------------------------------------------------------------------*/ + +int32_t MV_VoiceAvailable +( + int32_t priority +) + +{ + VoiceNode *voice; + VoiceNode *node; + int32_t flags; + + // Check if we have any free voices + if (!LL_Empty(&VoicePool, next, prev)) + { + return(TRUE); + } + + flags = DisableInterrupts(); + + // check if we have a higher priority than a voice that is playing. + voice = VoiceList.next; + for (node = VoiceList.next; node != &VoiceList; node = node->next) + { + if (node->priority < voice->priority) + { + voice = node; + } + } + + RestoreInterrupts(flags); + + if ((voice != &VoiceList) && (priority >= voice->priority)) + { + return(TRUE); + } + + return(FALSE); +} + + +/*--------------------------------------------------------------------- + Function: MV_SetVoicePitch + + Sets the pitch for the specified voice. +---------------------------------------------------------------------*/ + +void MV_SetVoicePitch +( + VoiceNode *voice, + uint32_t rate, + int32_t pitchoffset +) + +{ + voice->SamplingRate = rate; + voice->PitchScale = PITCH_GetScale(pitchoffset); + voice->RateScale = (rate * voice->PitchScale) / MV_MixRate; + + // Multiply by MixBufferSize - 1 + voice->FixedPointBufferSize = (voice->RateScale * MixBufferSize) - + voice->RateScale; +} + + +/*--------------------------------------------------------------------- + Function: MV_SetPitch + + Sets the pitch for the voice associated with the specified handle. +---------------------------------------------------------------------*/ + +int32_t MV_SetPitch +( + int32_t handle, + int32_t pitchoffset +) + +{ + VoiceNode *voice; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + voice = MV_GetVoice(handle); + if (voice == NULL) + { + MV_SetErrorCode(MV_VoiceNotFound); + return(MV_Error); + } + + MV_SetVoicePitch(voice, voice->SamplingRate, pitchoffset); + + return(MV_Ok); +} + + +/*--------------------------------------------------------------------- + Function: MV_SetFrequency + + Sets the frequency for the voice associated with the specified handle. +---------------------------------------------------------------------*/ + +int32_t MV_SetFrequency +( + int32_t handle, + int32_t frequency +) + +{ + VoiceNode *voice; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + voice = MV_GetVoice(handle); + if (voice == NULL) + { + MV_SetErrorCode(MV_VoiceNotFound); + return(MV_Error); + } + + MV_SetVoicePitch(voice, frequency, 0); + + return(MV_Ok); +} + + +/*--------------------------------------------------------------------- + Function: MV_GetVolumeTable + + Returns a pointer to the volume table associated with the specified + volume. +---------------------------------------------------------------------*/ + +static int16_t *MV_GetVolumeTable +( + int32_t vol +) + +{ + int32_t volume; + int16_t *table; + + volume = MIX_VOLUME(vol); + + table = (int16_t *) &MV_VolumeTable[ volume ]; + + return(table); +} + + +/*--------------------------------------------------------------------- + Function: MV_SetVoiceMixMode + + Selects which method should be used to mix the voice. + + 8Bit 16Bit 8Bit 16Bit | 8Bit 16Bit 8Bit 16Bit | + Mono Mono Ster Ster | Mono Mono Ster Ster | Mixer + Out Out Out Out | In In In In | +--------------------------+---------------------------+------------- + X | X | Mix8BitMono16 + X | X | Mix8BitMono + X | X | Mix8BitStereo16 + X | X | Mix8BitStereo + X | X | Mix16BitMono16 + X | X | Mix16BitMono + X | X | Mix16BitStereo16 + X | X | Mix16BitStereo +--------------------------+---------------------------+------------- + X | X | Mix16BitStereo16Stereo + X | X | Mix16BitStereo8Stereo + X | X | Mix8BitStereo16Stereo + X | X | Mix8BitStereo8Stereo + X | X | Mix16BitMono16Stereo + X | X | Mix16BitMono8Stereo + X | X | Mix8BitMono16Stereo + X | X | Mix8BitMono8Stereo + +---------------------------------------------------------------------*/ + +void MV_SetVoiceMixMode +( + VoiceNode *voice +) + +{ + //int32_t flags; + int32_t test; + + //flags = DisableInterrupts(); + + test = T_DEFAULT; + if (MV_Bits == 8) + { + test |= T_8BITS; + } + + if (MV_Channels == 1) + { + test |= T_MONO; + } + else + { + if (IS_QUIET(voice->RightVolume)) + { + test |= T_RIGHTQUIET; + } + else if (IS_QUIET(voice->LeftVolume)) + { + test |= T_LEFTQUIET; + } + } + + if (voice->bits == 16) + { + test |= T_16BITSOURCE; + } + + if (voice->channels == 2) + { + test |= T_STEREOSOURCE; + test &= ~(T_RIGHTQUIET | T_LEFTQUIET); + } + + switch (test) + { + case T_8BITS | T_MONO | T_16BITSOURCE : + voice->mix = MV_Mix8BitMono16; + break; + + case T_8BITS | T_MONO : + voice->mix = MV_Mix8BitMono; + break; + + case T_8BITS | T_16BITSOURCE | T_LEFTQUIET : + MV_LeftVolume = MV_RightVolume; + voice->mix = MV_Mix8BitMono16; + break; + + case T_8BITS | T_LEFTQUIET : + MV_LeftVolume = MV_RightVolume; + voice->mix = MV_Mix8BitMono; + break; + + case T_8BITS | T_16BITSOURCE | T_RIGHTQUIET : + voice->mix = MV_Mix8BitMono16; + break; + + case T_8BITS | T_RIGHTQUIET : + voice->mix = MV_Mix8BitMono; + break; + + case T_8BITS | T_16BITSOURCE : + voice->mix = MV_Mix8BitStereo16; + break; + + case T_8BITS : + voice->mix = MV_Mix8BitStereo; + break; + + case T_MONO | T_16BITSOURCE : + voice->mix = MV_Mix16BitMono16; + break; + + case T_MONO : + voice->mix = MV_Mix16BitMono; + break; + + case T_16BITSOURCE | T_LEFTQUIET : + MV_LeftVolume = MV_RightVolume; + voice->mix = MV_Mix16BitMono16; + break; + + case T_LEFTQUIET : + MV_LeftVolume = MV_RightVolume; + voice->mix = MV_Mix16BitMono; + break; + + case T_16BITSOURCE | T_RIGHTQUIET : + voice->mix = MV_Mix16BitMono16; + break; + + case T_RIGHTQUIET : + voice->mix = MV_Mix16BitMono; + break; + + case T_16BITSOURCE : + voice->mix = MV_Mix16BitStereo16; + break; + + case T_SIXTEENBIT_STEREO : + voice->mix = MV_Mix16BitStereo; + break; + + case T_16BITSOURCE | T_STEREOSOURCE: + voice->mix = MV_Mix16BitStereo16Stereo; + break; + + case T_16BITSOURCE | T_STEREOSOURCE | T_8BITS: + voice->mix = MV_Mix8BitStereo16Stereo; + break; + + case T_16BITSOURCE | T_STEREOSOURCE | T_MONO: + voice->mix = MV_Mix16BitMono16Stereo; + break; + + case T_16BITSOURCE | T_STEREOSOURCE | T_8BITS | T_MONO: + voice->mix = MV_Mix8BitMono16Stereo; + break; + + case T_STEREOSOURCE: + voice->mix = MV_Mix16BitStereo8Stereo; + break; + + case T_STEREOSOURCE | T_8BITS: + voice->mix = MV_Mix8BitStereo8Stereo; + break; + + case T_STEREOSOURCE | T_MONO: + voice->mix = MV_Mix16BitMono8Stereo; + break; + + case T_STEREOSOURCE | T_8BITS | T_MONO: + voice->mix = MV_Mix8BitMono8Stereo; + break; + + default : + voice->mix = 0; + } + + //RestoreInterrupts( flags ); +} + + +/*--------------------------------------------------------------------- + Function: MV_SetVoiceVolume + + Sets the stereo and mono volume level of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +void MV_SetVoiceVolume +( + VoiceNode *voice, + int32_t vol, + int32_t left, + int32_t right +) + +{ + if (MV_Channels == 1) + { + left = vol; + right = vol; + } + + if (MV_SwapLeftRight) + { + // SBPro uses reversed panning + voice->LeftVolume = MV_GetVolumeTable(right); + voice->RightVolume = MV_GetVolumeTable(left); + } + else + { + voice->LeftVolume = MV_GetVolumeTable(left); + voice->RightVolume = MV_GetVolumeTable(right); + } + + MV_SetVoiceMixMode(voice); +} + +/*--------------------------------------------------------------------- +Function: MV_PauseVoice + +Pauses the voice associated with the specified handle +without stoping the sound. +---------------------------------------------------------------------*/ + +int32_t MV_PauseVoice +( + int32_t handle, + int32_t pause +) + +{ + VoiceNode *voice; + int32_t flags; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + flags = DisableInterrupts(); + + voice = MV_GetVoice(handle); + if (voice == NULL) + { + RestoreInterrupts(flags); + MV_SetErrorCode(MV_VoiceNotFound); + return(MV_Warning); + } + + voice->Paused = pause; + + RestoreInterrupts(flags); + + return(MV_Ok); +} + + +/*--------------------------------------------------------------------- + Function: MV_EndLooping + + Stops the voice associated with the specified handle from looping + without stoping the sound. +---------------------------------------------------------------------*/ + +int32_t MV_EndLooping +( + int32_t handle +) + +{ + VoiceNode *voice; + int32_t flags; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + flags = DisableInterrupts(); + + voice = MV_GetVoice(handle); + if (voice == NULL) + { + RestoreInterrupts(flags); + MV_SetErrorCode(MV_VoiceNotFound); + return(MV_Warning); + } + + voice->LoopCount = 0; + voice->LoopStart = NULL; + voice->LoopEnd = NULL; + + RestoreInterrupts(flags); + + return(MV_Ok); +} + + +/*--------------------------------------------------------------------- + Function: MV_SetPan + + Sets the stereo and mono volume level of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +int32_t MV_SetPan +( + int32_t handle, + int32_t vol, + int32_t left, + int32_t right +) + +{ + VoiceNode *voice; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + voice = MV_GetVoice(handle); + if (voice == NULL) + { + MV_SetErrorCode(MV_VoiceNotFound); + return(MV_Warning); + } + + MV_SetVoiceVolume(voice, vol, left, right); + + return(MV_Ok); +} + + +/*--------------------------------------------------------------------- + Function: MV_Pan3D + + Set the angle and distance from the listener of the voice associated + with the specified handle. +---------------------------------------------------------------------*/ + +int32_t MV_Pan3D +( + int32_t handle, + int32_t angle, + int32_t distance +) + +{ + int32_t left; + int32_t right; + int32_t mid; + int32_t volume; + int32_t status; + + if (distance < 0) + { + distance = -distance; + angle += MV_NumPanPositions / 2; + } + + volume = MIX_VOLUME(distance); + + // Ensure angle is within 0 - 31 + angle &= MV_MaxPanPosition; + + left = MV_PanTable[ angle ][ volume ].left; + right = MV_PanTable[ angle ][ volume ].right; + mid = max(0, 255 - distance); + + status = MV_SetPan(handle, mid, left, right); + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: MV_SetReverb + + Sets the level of reverb to add to mix. +---------------------------------------------------------------------*/ + +void MV_SetReverb +( + int32_t reverb +) + +{ + MV_ReverbLevel = MIX_VOLUME(reverb); + MV_ReverbTable = &MV_VolumeTable[ MV_ReverbLevel ]; +} + + +/*--------------------------------------------------------------------- + Function: MV_SetFastReverb + + Sets the level of reverb to add to mix. +---------------------------------------------------------------------*/ + +void MV_SetFastReverb +( + int32_t reverb +) + +{ + MV_ReverbLevel = max(0, min(16, reverb)); + MV_ReverbTable = NULL; +} + + +/*--------------------------------------------------------------------- + Function: MV_GetMaxReverbDelay + + Returns the maximum delay time for reverb. +---------------------------------------------------------------------*/ + +int32_t MV_GetMaxReverbDelay +( + void +) + +{ + int32_t maxdelay; + + maxdelay = MixBufferSize * MV_NumberOfBuffers; + + return maxdelay; +} + + +/*--------------------------------------------------------------------- + Function: MV_GetReverbDelay + + Returns the current delay time for reverb. +---------------------------------------------------------------------*/ + +int32_t MV_GetReverbDelay +( + void +) + +{ + return MV_ReverbDelay / MV_SampleSize; +} + + +/*--------------------------------------------------------------------- + Function: MV_SetReverbDelay + + Sets the delay level of reverb to add to mix. +---------------------------------------------------------------------*/ + +void MV_SetReverbDelay +( + int32_t delay +) + +{ + int32_t maxdelay; + + maxdelay = MV_GetMaxReverbDelay(); + MV_ReverbDelay = max(MixBufferSize, min(delay, maxdelay)); + MV_ReverbDelay *= MV_SampleSize; +} + + +/*--------------------------------------------------------------------- + Function: MV_SetMixMode + + Prepares Multivoc to play stereo of mono digitized sounds. +---------------------------------------------------------------------*/ + +int32_t MV_SetMixMode +( + int32_t numchannels, + int32_t samplebits +) + +{ + int32_t mode; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + mode = 0; + if (numchannels == 2) + { + mode |= STEREO; + } + if (samplebits == 16) + { + mode |= SIXTEEN_BIT; + } + + MV_MixMode = mode; + + MV_Channels = 1; + if (MV_MixMode & STEREO) + { + MV_Channels = 2; + } + + MV_Bits = 8; + if (MV_MixMode & SIXTEEN_BIT) + { + MV_Bits = 16; + } + + MV_BuffShift = 7 + MV_Channels; + MV_SampleSize = sizeof(MONO8) * MV_Channels; + + if (MV_Bits == 8) + { + MV_Silence = SILENCE_8BIT; + } + else + { + MV_Silence = SILENCE_16BIT; + MV_BuffShift += 1; + MV_SampleSize *= 2; + } + + MV_BufferSize = MixBufferSize * MV_SampleSize; + MV_NumberOfBuffers = TotalBufferSize / MV_BufferSize; + MV_BufferLength = TotalBufferSize; + + MV_RightChannelOffset = MV_SampleSize / 2; + + return(MV_Ok); +} + + +/*--------------------------------------------------------------------- + Function: MV_StartPlayback + + Starts the sound playback engine. +---------------------------------------------------------------------*/ + +int32_t MV_StartPlayback +( + void +) + +{ + int32_t status; + int32_t buffer; + + // Initialize the buffers + ClearBuffer_DW(MV_MixBuffer[ 0 ], MV_Silence, TotalBufferSize >> 2); + for (buffer = 0; buffer < MV_NumberOfBuffers; buffer++) + { + MV_BufferEmpty[ buffer ] = TRUE; + } + + // Set the mix buffer variables + MV_MixPage = 1; + + MV_MixFunction = MV_Mix; + +//JIM +// MV_MixRate = MV_RequestedMixRate; +// return( MV_Ok ); + + // Start playback + status = SoundDriver_BeginPlayback(MV_MixBuffer[0], MV_BufferSize, + MV_NumberOfBuffers, MV_ServiceVoc); + if (status != MV_Ok) + { + MV_SetErrorCode(MV_DriverError); + return MV_Error; + } + + MV_MixRate = MV_RequestedMixRate; + + return(MV_Ok); +} + + +/*--------------------------------------------------------------------- + Function: MV_StopPlayback + + Stops the sound playback engine. +---------------------------------------------------------------------*/ + +void MV_StopPlayback +( + void +) + +{ + VoiceNode *voice; + VoiceNode *next; + int32_t flags; + + // Stop sound playback + SoundDriver_StopPlayback(); + + // Make sure all callbacks are done. + flags = DisableInterrupts(); + + for (voice = VoiceList.next; voice != &VoiceList; voice = next) + { + next = voice->next; + + MV_StopVoice(voice); + + if (MV_CallBackFunc) + { + MV_CallBackFunc(voice->callbackval); + } + } + + RestoreInterrupts(flags); +} + + +/*--------------------------------------------------------------------- + Function: MV_StartRecording + + Starts the sound recording engine. +---------------------------------------------------------------------*/ + +int32_t MV_StartRecording +( + int32_t MixRate, + void (*function)(char *ptr, int32_t length) +) + +{ + MV_SetErrorCode(MV_UnsupportedCard); + return(MV_Error); +} + + +/*--------------------------------------------------------------------- + Function: MV_StopRecord + + Stops the sound record engine. +---------------------------------------------------------------------*/ + +void MV_StopRecord +( + void +) + +{ +} + + +/*--------------------------------------------------------------------- + Function: MV_StartDemandFeedPlayback + + Plays a digitized sound from a user controlled buffering system. +---------------------------------------------------------------------*/ + +int32_t MV_StartDemandFeedPlayback +( + void (*function)(char **ptr, uint32_t *length), + int32_t rate, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + VoiceNode *voice; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + // Request a voice from the voice pool + voice = MV_AllocVoice(priority); + if (voice == NULL) + { + MV_SetErrorCode(MV_NoVoices); + return(MV_Error); + } + + voice->wavetype = DemandFeed; + voice->bits = 8; + voice->channels = 1; + voice->GetSound = MV_GetNextDemandFeedBlock; + voice->NextBlock = NULL; + voice->DemandFeed = function; + voice->LoopStart = NULL; + voice->LoopCount = 0; + voice->BlockLength = 0; + voice->position = 0; + voice->sound = NULL; + voice->length = 0; + voice->BlockLength = 0; + voice->Playing = TRUE; + voice->next = NULL; + voice->prev = NULL; + voice->priority = priority; + voice->callbackval = callbackval; + + MV_SetVoicePitch(voice, rate, pitchoffset); + MV_SetVoiceVolume(voice, vol, left, right); + MV_PlayVoice(voice); + + return(voice->handle); +} + + +/*--------------------------------------------------------------------- + Function: MV_PlayRaw + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int32_t MV_PlayRaw +( + char *ptr, + uint32_t length, + unsigned rate, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t status; + + status = MV_PlayLoopedRaw(ptr, length, NULL, NULL, rate, pitchoffset, + vol, left, right, priority, callbackval); + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: MV_PlayLoopedRaw + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int32_t MV_PlayLoopedRaw +( + char *ptr, + uint32_t length, + char *loopstart, + char *loopend, + unsigned rate, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + VoiceNode *voice; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + // Request a voice from the voice pool + voice = MV_AllocVoice(priority); + if (voice == NULL) + { + MV_SetErrorCode(MV_NoVoices); + return(MV_Error); + } + + voice->wavetype = Raw; + voice->bits = 8; + voice->channels = 1; + voice->GetSound = MV_GetNextRawBlock; + voice->Playing = TRUE; + voice->NextBlock = ptr; + voice->position = 0; + voice->BlockLength = length; + voice->length = 0; + voice->next = NULL; + voice->prev = NULL; + voice->priority = priority; + voice->callbackval = callbackval; + voice->LoopStart = loopstart; + voice->LoopEnd = loopend; + voice->LoopSize = (voice->LoopEnd - voice->LoopStart) + 1; + + MV_SetVoicePitch(voice, rate, pitchoffset); + MV_SetVoiceVolume(voice, vol, left, right); + MV_PlayVoice(voice); + + return(voice->handle); +} + + +/*--------------------------------------------------------------------- + Function: MV_PlayWAV + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int32_t MV_PlayWAV +( + char *ptr, + uint32_t length, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t status; + + status = MV_PlayLoopedWAV(ptr, length, -1, -1, pitchoffset, vol, left, right, + priority, callbackval); + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: MV_PlayWAV3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int32_t MV_PlayWAV3D +( + char *ptr, + uint32_t length, + int32_t pitchoffset, + int32_t angle, + int32_t distance, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t left; + int32_t right; + int32_t mid; + int32_t volume; + int32_t status; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + if (distance < 0) + { + distance = -distance; + angle += MV_NumPanPositions / 2; + } + + volume = MIX_VOLUME(distance); + + // Ensure angle is within 0 - 31 + angle &= MV_MaxPanPosition; + + left = MV_PanTable[ angle ][ volume ].left; + right = MV_PanTable[ angle ][ volume ].right; + mid = max(0, 255 - distance); + + status = MV_PlayWAV(ptr, length, pitchoffset, mid, left, right, priority, + callbackval); + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: MV_PlayLoopedWAV + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int32_t MV_PlayLoopedWAV +( + char *ptr, + uint32_t ptrlength, + int32_t loopstart, + int32_t loopend, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + riff_header riff; + format_header format; + data_header data; + VoiceNode *voice; + int32_t length; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + memcpy(&riff, ptr, sizeof(riff_header)); + riff.file_size = LITTLE32(riff.file_size); + riff.format_size = LITTLE32(riff.format_size); + + if ((memcmp(riff.RIFF, "RIFF", 4) != 0) || + (memcmp(riff.WAVE, "WAVE", 4) != 0) || + (memcmp(riff.fmt, "fmt ", 4) != 0)) + { + MV_SetErrorCode(MV_InvalidWAVFile); + return(MV_Error); + } + + memcpy(&format, ptr + sizeof(riff_header), sizeof(format_header)); + format.wFormatTag = LITTLE16(format.wFormatTag); + format.nChannels = LITTLE16(format.nChannels); + format.nSamplesPerSec = LITTLE32(format.nSamplesPerSec); + format.nAvgBytesPerSec = LITTLE32(format.nAvgBytesPerSec); + format.nBlockAlign = LITTLE16(format.nBlockAlign); + format.nBitsPerSample = LITTLE16(format.nBitsPerSample); + + memcpy(&data, ptr + sizeof(riff_header) + riff.format_size, sizeof(data_header)); + data.size = LITTLE32(data.size); + + // Check if it's PCM data. + if (format.wFormatTag != 1) + { + MV_SetErrorCode(MV_InvalidWAVFile); + return(MV_Error); + } + + if (format.nChannels != 1 && format.nChannels != 2) + { + MV_SetErrorCode(MV_InvalidWAVFile); + return(MV_Error); + } + + if ((format.nBitsPerSample != 8) && + (format.nBitsPerSample != 16)) + { + MV_SetErrorCode(MV_InvalidWAVFile); + return(MV_Error); + } + + if (memcmp(data.DATA, "data", 4) != 0) + { + MV_SetErrorCode(MV_InvalidWAVFile); + return(MV_Error); + } + + // Request a voice from the voice pool + voice = MV_AllocVoice(priority); + if (voice == NULL) + { + MV_SetErrorCode(MV_NoVoices); + return(MV_Error); + } + + voice->wavetype = WAV; + voice->bits = format.nBitsPerSample; + voice->channels = format.nChannels; + voice->GetSound = MV_GetNextWAVBlock; + + length = data.size; + if (voice->bits == 16) + { + data.size &= ~1; + length /= 2; + } + if (voice->channels == 2) + { + data.size &= ~1; + length /= 2; + } + + voice->Playing = TRUE; + voice->DemandFeed = NULL; + voice->LoopStart = NULL; + voice->LoopCount = 0; + voice->position = 0; + voice->length = 0; + voice->BlockLength = length; + voice->NextBlock = (char *)((intptr_t) ptr + sizeof(riff_header) + riff.format_size + sizeof(data_header)); + voice->next = NULL; + voice->prev = NULL; + voice->priority = priority; + voice->callbackval = callbackval; + voice->LoopStart = loopstart >= 0 ? voice->NextBlock : NULL; + voice->LoopEnd = NULL; + voice->LoopSize = length; + + MV_SetVoicePitch(voice, format.nSamplesPerSec, pitchoffset); + MV_SetVoiceVolume(voice, vol, left, right); + MV_PlayVoice(voice); + + return(voice->handle); +} + + +/*--------------------------------------------------------------------- + Function: MV_PlayVOC3D + + Begin playback of sound data at specified angle and distance + from listener. +---------------------------------------------------------------------*/ + +int32_t MV_PlayVOC3D +( + char *ptr, + uint32_t ptrlength, + int32_t pitchoffset, + int32_t angle, + int32_t distance, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t left; + int32_t right; + int32_t mid; + int32_t volume; + int32_t status; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + if (distance < 0) + { + distance = -distance; + angle += MV_NumPanPositions / 2; + } + + volume = MIX_VOLUME(distance); + + // Ensure angle is within 0 - 31 + angle &= MV_MaxPanPosition; + + left = MV_PanTable[ angle ][ volume ].left; + right = MV_PanTable[ angle ][ volume ].right; + mid = max(0, 255 - distance); + + status = MV_PlayVOC(ptr, ptrlength, pitchoffset, mid, left, right, priority, + callbackval); + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: MV_PlayVOC + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int32_t MV_PlayVOC +( + char *ptr, + uint32_t ptrlength, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + int32_t status; + + status = MV_PlayLoopedVOC(ptr, ptrlength, -1, -1, pitchoffset, vol, left, right, + priority, callbackval); + + return(status); +} + + +/*--------------------------------------------------------------------- + Function: MV_PlayLoopedVOC + + Begin playback of sound data with the given sound levels and + priority. +---------------------------------------------------------------------*/ + +int32_t MV_PlayLoopedVOC +( + char *ptr, + uint32_t ptrlength, + int32_t loopstart, + int32_t loopend, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval +) + +{ + VoiceNode *voice; + int32_t status; + + if (!MV_Installed) + { + MV_SetErrorCode(MV_NotInstalled); + return(MV_Error); + } + + // Make sure it's a valid VOC file. + status = memcmp(ptr, "Creative Voice File", 19); + if (status != 0) + { + MV_SetErrorCode(MV_InvalidVOCFile); + return(MV_Error); + } + + // Request a voice from the voice pool + voice = MV_AllocVoice(priority); + if (voice == NULL) + { + MV_SetErrorCode(MV_NoVoices); + return(MV_Error); + } + + voice->wavetype = VOC; + voice->bits = 8; + voice->channels = 1; + voice->GetSound = MV_GetNextVOCBlock; + voice->NextBlock = ptr + LITTLE16(*(uint16_t *)(ptr + 0x14)); + voice->DemandFeed = NULL; + voice->LoopStart = NULL; + voice->LoopCount = 0; + voice->BlockLength = 0; + voice->PitchScale = PITCH_GetScale(pitchoffset); + voice->length = 0; + voice->next = NULL; + voice->prev = NULL; + voice->priority = priority; + voice->callbackval = callbackval; + voice->LoopStart = loopstart >= 0 ? voice->NextBlock : 0; + voice->LoopEnd = 0; + voice->LoopSize = loopend - loopstart + 1; + + if (loopstart < 0) + { + voice->LoopStart = NULL; + voice->LoopEnd = NULL; + } + + MV_SetVoiceVolume(voice, vol, left, right); + MV_PlayVoice(voice); + + return(voice->handle); +} + + +/*--------------------------------------------------------------------- + Function: MV_CreateVolumeTable + + Create the table used to convert sound data to a specific volume + level. +---------------------------------------------------------------------*/ + +void MV_CreateVolumeTable +( + int32_t index, + int32_t volume, + int32_t MaxVolume +) + +{ + int32_t val; + int32_t level; + int32_t i; + + level = (volume * MaxVolume) / MV_MaxTotalVolume; + if (MV_Bits == 16) + { + for (i = 0; i < 65536; i += 256) + { + val = i - 0x8000; + val *= level; + val /= MV_MaxVolume; + MV_VolumeTable[ index ][ i / 256 ] = val; + } + } + else + { + for (i = 0; i < 256; i++) + { + val = i - 0x80; + val *= level; + val /= MV_MaxVolume; + MV_VolumeTable[ volume ][ i ] = val; + } + } +} + + +/*--------------------------------------------------------------------- + Function: MV_CalcVolume + + Create the table used to convert sound data to a specific volume + level. +---------------------------------------------------------------------*/ + +void MV_CalcVolume +( + int32_t MaxVolume +) + +{ + int32_t volume; + + for (volume = 0; volume < 128; volume++) + { + MV_HarshClipTable[ volume ] = 0; + MV_HarshClipTable[ volume + 384 ] = 255; + } + for (volume = 0; volume < 256; volume++) + { + MV_HarshClipTable[ volume + 128 ] = volume; + } + + // For each volume level, create a translation table with the + // appropriate volume calculated. + for (volume = 0; volume <= MV_MaxVolume; volume++) + { + MV_CreateVolumeTable(volume, volume, MaxVolume); + } +} + + +/*--------------------------------------------------------------------- + Function: MV_CalcPanTable + + Create the table used to determine the stereo volume level of + a sound located at a specific angle and distance from the listener. +---------------------------------------------------------------------*/ + +void MV_CalcPanTable +( + void +) + +{ + int32_t level; + int32_t angle; + int32_t distance; + int32_t HalfAngle; + int32_t ramp; + + HalfAngle = (MV_NumPanPositions / 2); + + for (distance = 0; distance <= MV_MaxVolume; distance++) + { + level = (255 * (MV_MaxVolume - distance)) / MV_MaxVolume; + for (angle = 0; angle <= HalfAngle / 2; angle++) + { + ramp = level - ((level * angle) / + (MV_NumPanPositions / 4)); + + MV_PanTable[ angle ][ distance ].left = ramp; + MV_PanTable[ HalfAngle - angle ][ distance ].left = ramp; + MV_PanTable[ HalfAngle + angle ][ distance ].left = level; + MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].left = level; + + MV_PanTable[ angle ][ distance ].right = level; + MV_PanTable[ HalfAngle - angle ][ distance ].right = level; + MV_PanTable[ HalfAngle + angle ][ distance ].right = ramp; + MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].right = ramp; + } + } +} + + +/*--------------------------------------------------------------------- + Function: MV_SetVolume + + Sets the volume of digitized sound playback. +---------------------------------------------------------------------*/ + +void MV_SetVolume +( + int32_t volume +) + +{ + volume = max(0, volume); + volume = min(volume, MV_MaxTotalVolume); + + MV_TotalVolume = volume; + + // Calculate volume table + MV_CalcVolume(volume); +} + + +/*--------------------------------------------------------------------- + Function: MV_GetVolume + + Returns the volume of digitized sound playback. +---------------------------------------------------------------------*/ + +int32_t MV_GetVolume +( + void +) + +{ + return(MV_TotalVolume); +} + + +/*--------------------------------------------------------------------- + Function: MV_SetCallBack + + Set the function to call when a voice stops. +---------------------------------------------------------------------*/ + +void MV_SetCallBack +( + void (*function)(uint32_t) +) + +{ + MV_CallBackFunc = function; +} + + +/*--------------------------------------------------------------------- + Function: MV_SetReverseStereo + + Set the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +void MV_SetReverseStereo +( + int32_t setting +) + +{ + MV_SwapLeftRight = setting; +} + + +/*--------------------------------------------------------------------- + Function: MV_GetReverseStereo + + Returns the orientation of the left and right channels. +---------------------------------------------------------------------*/ + +int32_t MV_GetReverseStereo +( + void +) + +{ + return(MV_SwapLeftRight); +} + + +/*--------------------------------------------------------------------- + Function: MV_Init + + Perform the initialization of variables and memory used by + Multivoc. +---------------------------------------------------------------------*/ + +int32_t MV_Init +( + int32_t soundcard, + int32_t MixRate, + int32_t Voices, + int32_t numchannels, + int32_t samplebits, + void * initdata +) + +{ + char *ptr; + int32_t status; + int32_t buffer; + int32_t index; + + if (MV_Installed) + { + MV_Shutdown(); + } + + MV_SetErrorCode(MV_Ok); + + MV_TotalMemory = Voices * sizeof(VoiceNode) + sizeof(HARSH_CLIP_TABLE_8) + TotalBufferSize; + ptr = (char *) malloc(MV_TotalMemory); + if (!ptr) + { + MV_SetErrorCode(MV_NoMem); + return(MV_Error); + } + + MV_Voices = (VoiceNode *)ptr; + ptr += Voices * sizeof(VoiceNode); + + MV_HarshClipTable = ptr; + ptr += sizeof(HARSH_CLIP_TABLE_8); + + // Set number of voices before calculating volume table + MV_MaxVoices = Voices; + + LL_Reset((VoiceNode*) &VoiceList, next, prev); + LL_Reset((VoiceNode*) &VoicePool, next, prev); + + for (index = 0; index < Voices; index++) + { + LL_Add((VoiceNode*) &VoicePool, &MV_Voices[ index ], next, prev); + } + + MV_SetReverseStereo(FALSE); + + ASS_SoundDriver = soundcard; + + // Initialize the sound card + status = SoundDriver_Init(MixRate, numchannels, samplebits, initdata); + if (status != MV_Ok) + { + MV_SetErrorCode(MV_DriverError); + } + + if (MV_ErrorCode != MV_Ok) + { + status = MV_ErrorCode; + + free(MV_Voices); + MV_Voices = NULL; + MV_HarshClipTable = NULL; + MV_TotalMemory = 0; + + MV_SetErrorCode(status); + return(MV_Error); + } + + MV_Installed = TRUE; + MV_CallBackFunc = NULL; + MV_RecordFunc = NULL; + MV_Recording = FALSE; + MV_ReverbLevel = 0; + MV_ReverbTable = NULL; + + // Set the sampling rate + MV_RequestedMixRate = MixRate; + + // Set Mixer to play stereo digitized sound + MV_SetMixMode(numchannels, samplebits); + MV_ReverbDelay = MV_BufferSize * 3; + + // Make sure we don't cross a physical page + MV_MixBuffer[ MV_NumberOfBuffers ] = ptr; + for (buffer = 0; buffer < MV_NumberOfBuffers; buffer++) + { + MV_MixBuffer[ buffer ] = ptr; + ptr += MV_BufferSize; + } + + // Calculate pan table + MV_CalcPanTable(); + + MV_SetVolume(MV_MaxTotalVolume); + + // Start the playback engine + status = MV_StartPlayback(); + if (status != MV_Ok) + { + // Preserve error code while we shutdown. + status = MV_ErrorCode; + MV_Shutdown(); + MV_SetErrorCode(status); + return(MV_Error); + } + + return(MV_Ok); +} + + +/*--------------------------------------------------------------------- + Function: MV_Shutdown + + Restore any resources allocated by Multivoc back to the system. +---------------------------------------------------------------------*/ + +int32_t MV_Shutdown +( + void +) + +{ + int32_t buffer; + + if (!MV_Installed) + { + return(MV_Ok); + } + + MV_KillAllVoices(); + + MV_Installed = FALSE; + + // Stop the sound recording engine + if (MV_Recording) + { + MV_StopRecord(); + } + + // Stop the sound playback engine + MV_StopPlayback(); + + // Shutdown the sound card + SoundDriver_Shutdown(); + + // Free any voices we allocated + free(MV_Voices); + MV_Voices = NULL; + MV_TotalMemory = 0; + + LL_Reset((VoiceNode*) &VoiceList, next, prev); + LL_Reset((VoiceNode*) &VoicePool, next, prev); + + MV_MaxVoices = 1; + + // Release the descriptor from our mix buffer + for (buffer = 0; buffer < NumberOfBuffers; buffer++) + { + MV_MixBuffer[ buffer ] = NULL; + } + + return(MV_Ok); +} + +// vim:ts=3:expandtab: diff --git a/polymer/eduke32/source/jaudiolib/src/multivoc.h b/polymer/eduke32/source/jaudiolib/src/multivoc.h new file mode 100644 index 000000000..9c42ecd1d --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/multivoc.h @@ -0,0 +1,119 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/********************************************************************** + file: MULTIVOC.H + + author: James R. Dose + date: December 20, 1993 + + Public header for MULTIVOC.C + + (c) Copyright 1993 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __MULTIVOC_H +#define __MULTIVOC_H + +#define MV_MinVoiceHandle 1 + +extern int32_t MV_ErrorCode; + +enum MV_Errors + { + MV_Warning = -2, + MV_Error = -1, + MV_Ok = 0, + MV_UnsupportedCard, + MV_NotInstalled, + MV_DriverError, + MV_NoVoices, + MV_NoMem, + MV_VoiceNotFound, + MV_InvalidVOCFile, + MV_InvalidWAVFile, + MV_InvalidVorbisFile, + MV_InvalidMixMode, + MV_NullRecordFunction + }; + +const char *MV_ErrorString( int32_t ErrorNumber ); +int32_t MV_VoicePlaying( int32_t handle ); +int32_t MV_KillAllVoices( void ); +int32_t MV_Kill( int32_t handle ); +int32_t MV_VoicesPlaying( void ); +int32_t MV_VoiceAvailable( int32_t priority ); +int32_t MV_SetPitch( int32_t handle, int32_t pitchoffset ); +int32_t MV_SetFrequency( int32_t handle, int32_t frequency ); +int32_t MV_PauseVoice( int32_t handle, int32_t pause ); +int32_t MV_EndLooping( int32_t handle ); +int32_t MV_SetPan( int32_t handle, int32_t vol, int32_t left, int32_t right ); +int32_t MV_Pan3D( int32_t handle, int32_t angle, int32_t distance ); +void MV_SetReverb( int32_t reverb ); +void MV_SetFastReverb( int32_t reverb ); +int32_t MV_GetMaxReverbDelay( void ); +int32_t MV_GetReverbDelay( void ); +void MV_SetReverbDelay( int32_t delay ); +int32_t MV_SetMixMode( int32_t numchannels, int32_t samplebits ); +int32_t MV_StartPlayback( void ); +void MV_StopPlayback( void ); +int32_t MV_StartRecording( int32_t MixRate, void ( *function )( char *ptr, int32_t length ) ); +void MV_StopRecord( void ); +int32_t MV_StartDemandFeedPlayback( void ( *function )( char **ptr, uint32_t *length ), + int32_t rate, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, + int32_t priority, uint32_t callbackval ); +int32_t MV_PlayRaw( char *ptr, uint32_t length, + unsigned rate, int32_t pitchoffset, int32_t vol, int32_t left, + int32_t right, int32_t priority, uint32_t callbackval ); +int32_t MV_PlayLoopedRaw( char *ptr, uint32_t length, + char *loopstart, char *loopend, unsigned rate, int32_t pitchoffset, + int32_t vol, int32_t left, int32_t right, int32_t priority, + uint32_t callbackval ); +int32_t MV_PlayWAV( char *ptr, uint32_t length, int32_t pitchoffset, int32_t vol, int32_t left, + int32_t right, int32_t priority, uint32_t callbackval ); +int32_t MV_PlayWAV3D( char *ptr, uint32_t length, int32_t pitchoffset, int32_t angle, int32_t distance, + int32_t priority, uint32_t callbackval ); +int32_t MV_PlayLoopedWAV( char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, + int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority, + uint32_t callbackval ); +int32_t MV_PlayVOC3D( char *ptr, uint32_t length, int32_t pitchoffset, int32_t angle, int32_t distance, + int32_t priority, uint32_t callbackval ); +int32_t MV_PlayVOC( char *ptr, uint32_t length, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, + int32_t priority, uint32_t callbackval ); +int32_t MV_PlayLoopedVOC( char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, + int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority, + uint32_t callbackval ); +int32_t MV_PlayVorbis3D( char *ptr, uint32_t length, int32_t pitchoffset, int32_t angle, int32_t distance, + int32_t priority, uint32_t callbackval ); +int32_t MV_PlayVorbis( char *ptr, uint32_t length, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, + int32_t priority, uint32_t callbackval ); +int32_t MV_PlayLoopedVorbis( char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, + int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority, + uint32_t callbackval ); +void MV_CreateVolumeTable( int32_t index, int32_t volume, int32_t MaxVolume ); +void MV_SetVolume( int32_t volume ); +int32_t MV_GetVolume( void ); +void MV_SetCallBack( void ( *function )( uint32_t ) ); +void MV_SetReverseStereo( int32_t setting ); +int32_t MV_GetReverseStereo( void ); +int32_t MV_Init( int32_t soundcard, int32_t MixRate, int32_t Voices, int32_t numchannels, + int32_t samplebits, void * initdata ); +int32_t MV_Shutdown( void ); + +#endif diff --git a/polymer/eduke32/source/jaudiolib/src/pitch.c b/polymer/eduke32/source/jaudiolib/src/pitch.c new file mode 100644 index 000000000..824f0cd04 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/pitch.c @@ -0,0 +1,187 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/********************************************************************** + module: PITCH.C + + author: James R. Dose + date: June 14, 1993 + + Routines for pitch scaling. + + (c) Copyright 1993 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#include +//#include +#include "pitch.h" + +#define MAXDETUNE 25 + +static uint32_t PitchTable[ 12 ][ MAXDETUNE ] = + { + { 0x10000, 0x10097, 0x1012f, 0x101c7, 0x10260, 0x102f9, 0x10392, 0x1042c, + 0x104c6, 0x10561, 0x105fb, 0x10696, 0x10732, 0x107ce, 0x1086a, 0x10907, + 0x109a4, 0x10a41, 0x10adf, 0x10b7d, 0x10c1b, 0x10cba, 0x10d59, 0x10df8, + 0x10e98 }, + { 0x10f38, 0x10fd9, 0x1107a, 0x1111b, 0x111bd, 0x1125f, 0x11302, 0x113a5, + 0x11448, 0x114eb, 0x1158f, 0x11634, 0x116d8, 0x1177e, 0x11823, 0x118c9, + 0x1196f, 0x11a16, 0x11abd, 0x11b64, 0x11c0c, 0x11cb4, 0x11d5d, 0x11e06, + 0x11eaf }, + { 0x11f59, 0x12003, 0x120ae, 0x12159, 0x12204, 0x122b0, 0x1235c, 0x12409, + 0x124b6, 0x12563, 0x12611, 0x126bf, 0x1276d, 0x1281c, 0x128cc, 0x1297b, + 0x12a2b, 0x12adc, 0x12b8d, 0x12c3e, 0x12cf0, 0x12da2, 0x12e55, 0x12f08, + 0x12fbc }, + { 0x1306f, 0x13124, 0x131d8, 0x1328d, 0x13343, 0x133f9, 0x134af, 0x13566, + 0x1361d, 0x136d5, 0x1378d, 0x13846, 0x138fe, 0x139b8, 0x13a72, 0x13b2c, + 0x13be6, 0x13ca1, 0x13d5d, 0x13e19, 0x13ed5, 0x13f92, 0x1404f, 0x1410d, + 0x141cb }, + { 0x1428a, 0x14349, 0x14408, 0x144c8, 0x14588, 0x14649, 0x1470a, 0x147cc, + 0x1488e, 0x14951, 0x14a14, 0x14ad7, 0x14b9b, 0x14c5f, 0x14d24, 0x14dea, + 0x14eaf, 0x14f75, 0x1503c, 0x15103, 0x151cb, 0x15293, 0x1535b, 0x15424, + 0x154ee }, + { 0x155b8, 0x15682, 0x1574d, 0x15818, 0x158e4, 0x159b0, 0x15a7d, 0x15b4a, + 0x15c18, 0x15ce6, 0x15db4, 0x15e83, 0x15f53, 0x16023, 0x160f4, 0x161c5, + 0x16296, 0x16368, 0x1643a, 0x1650d, 0x165e1, 0x166b5, 0x16789, 0x1685e, + 0x16934 }, + { 0x16a09, 0x16ae0, 0x16bb7, 0x16c8e, 0x16d66, 0x16e3e, 0x16f17, 0x16ff1, + 0x170ca, 0x171a5, 0x17280, 0x1735b, 0x17437, 0x17513, 0x175f0, 0x176ce, + 0x177ac, 0x1788a, 0x17969, 0x17a49, 0x17b29, 0x17c09, 0x17cea, 0x17dcc, + 0x17eae }, + { 0x17f91, 0x18074, 0x18157, 0x1823c, 0x18320, 0x18406, 0x184eb, 0x185d2, + 0x186b8, 0x187a0, 0x18888, 0x18970, 0x18a59, 0x18b43, 0x18c2d, 0x18d17, + 0x18e02, 0x18eee, 0x18fda, 0x190c7, 0x191b5, 0x192a2, 0x19391, 0x19480, + 0x1956f }, + { 0x1965f, 0x19750, 0x19841, 0x19933, 0x19a25, 0x19b18, 0x19c0c, 0x19d00, + 0x19df4, 0x19ee9, 0x19fdf, 0x1a0d5, 0x1a1cc, 0x1a2c4, 0x1a3bc, 0x1a4b4, + 0x1a5ad, 0x1a6a7, 0x1a7a1, 0x1a89c, 0x1a998, 0x1aa94, 0x1ab90, 0x1ac8d, + 0x1ad8b }, + { 0x1ae89, 0x1af88, 0x1b088, 0x1b188, 0x1b289, 0x1b38a, 0x1b48c, 0x1b58f, + 0x1b692, 0x1b795, 0x1b89a, 0x1b99f, 0x1baa4, 0x1bbaa, 0x1bcb1, 0x1bdb8, + 0x1bec0, 0x1bfc9, 0x1c0d2, 0x1c1dc, 0x1c2e6, 0x1c3f1, 0x1c4fd, 0x1c609, + 0x1c716 }, + { 0x1c823, 0x1c931, 0x1ca40, 0x1cb50, 0x1cc60, 0x1cd70, 0x1ce81, 0x1cf93, + 0x1d0a6, 0x1d1b9, 0x1d2cd, 0x1d3e1, 0x1d4f6, 0x1d60c, 0x1d722, 0x1d839, + 0x1d951, 0x1da69, 0x1db82, 0x1dc9c, 0x1ddb6, 0x1ded1, 0x1dfec, 0x1e109, + 0x1e225 }, + { 0x1e343, 0x1e461, 0x1e580, 0x1e6a0, 0x1e7c0, 0x1e8e0, 0x1ea02, 0x1eb24, + 0x1ec47, 0x1ed6b, 0x1ee8f, 0x1efb4, 0x1f0d9, 0x1f1ff, 0x1f326, 0x1f44e, + 0x1f576, 0x1f69f, 0x1f7c9, 0x1f8f3, 0x1fa1e, 0x1fb4a, 0x1fc76, 0x1fda3, + 0x1fed1 } + }; + + +//static int32_t PITCH_Installed = FALSE; + + +/*--------------------------------------------------------------------- + Function: PITCH_Init + + Initializes pitch table. +---------------------------------------------------------------------*/ +/* +void PITCH_Init + ( + void + ) + + { + int32_t note; + int32_t detune; + + if ( !PITCH_Installed ) + { + for( note = 0; note < 12; note++ ) + { + for( detune = 0; detune < MAXDETUNE; detune++ ) + { + PitchTable[ note ][ detune ] = 0x10000 * + pow( 2, ( note * MAXDETUNE + detune ) / ( 12.0 * MAXDETUNE ) ); + } + } + + PITCH_Installed = TRUE; + } + } +*/ + + +/*--------------------------------------------------------------------- + Function: PITCH_GetScale + + Returns a fixed-point value to scale number the specified amount. +---------------------------------------------------------------------*/ + +uint32_t PITCH_GetScale + ( + int32_t pitchoffset + ) + + { + uint32_t scale; + int32_t octaveshift; + int32_t noteshift; + int32_t note; + int32_t detune; + +// if ( !PITCH_Installed ) +// { +// PITCH_Init(); +// } + + if ( pitchoffset == 0 ) + { + return( PitchTable[ 0 ][ 0 ] ); + } + + noteshift = pitchoffset % 1200; + if ( noteshift < 0 ) + { + noteshift += 1200; + } + + note = noteshift / 100; + detune = ( noteshift % 100 ) / ( 100 / MAXDETUNE ); + octaveshift = ( pitchoffset - noteshift ) / 1200; + + if ( detune < 0 ) + { + detune += ( 100 / MAXDETUNE ); + note--; + if ( note < 0 ) + { + note += 12; + octaveshift--; + } + } + + scale = PitchTable[ note ][ detune ]; + + if ( octaveshift < 0 ) + { + scale >>= -octaveshift; + } + else + { + scale <<= octaveshift; + } + + return( scale ); + } + diff --git a/polymer/eduke32/source/jaudiolib/src/pitch.h b/polymer/eduke32/source/jaudiolib/src/pitch.h new file mode 100644 index 000000000..8bead2435 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/pitch.h @@ -0,0 +1,47 @@ +/* +Copyright (C) 1994-1995 Apogee Software, Ltd. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +/********************************************************************** + module: PITCH.H + + author: James R. Dose + date: June 14, 1994 + + Public header for PITCH.C + + (c) Copyright 1994 James R. Dose. All Rights Reserved. +**********************************************************************/ + +#ifndef __PITCH_H +#define __PITCH_H + +#include "inttypes.h" + +enum PITCH_ERRORS + { + PITCH_Warning = -2, + PITCH_Error = -1, + PITCH_Ok = 0, + }; + +//void PITCH_Init( void ); +uint32_t PITCH_GetScale( int32_t pitchoffset ); +void PITCH_UnlockMemory( void ); +int32_t PITCH_LockMemory( void ); +#endif diff --git a/polymer/eduke32/source/jaudiolib/src/vorbis.c b/polymer/eduke32/source/jaudiolib/src/vorbis.c new file mode 100644 index 000000000..1688e0e42 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/src/vorbis.c @@ -0,0 +1,424 @@ +/* + Copyright (C) 2009 Jonathon Fowler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +/** + * OggVorbis source support for MultiVoc + */ + +#ifdef __APPLE__ +# include +#else +# include "vorbis/vorbisfile.h" +#endif + +#include +#include +#include +#include +#include +#include "pitch.h" +#include "multivoc.h" +#include "_multivc.h" + +#define min(x,y) ((x) < (y) ? (x) : (y)) +#define max(x,y) ((x) > (y) ? (x) : (y)) + + +typedef struct { + void * ptr; + size_t length; + size_t pos; + + OggVorbis_File vf; + + char block[0x8000]; + int32_t blockused; + int32_t lastbitstream; +} vorbis_data; + +static size_t read_vorbis(void * ptr, size_t size, size_t nmemb, void * datasource) +{ + vorbis_data * vorb = (vorbis_data *) datasource; + size_t nread = 0; + size_t bytes; + + errno = 0; + + if (vorb->length == vorb->pos) { + return 0; + } + + for (; nmemb > 0; nmemb--, nread++) { + bytes = vorb->length - vorb->pos; + if (size < bytes) { + bytes = size; + } + + memcpy(ptr, vorb->ptr + vorb->pos, bytes); + vorb->pos += bytes; + ptr += bytes; + + if (vorb->length == vorb->pos) { + nread++; + break; + } + } + + return nread; +} + +static int32_t seek_vorbis(void * datasource, ogg_int64_t offset, int32_t whence) +{ + vorbis_data * vorb = (vorbis_data *) datasource; + + switch (whence) { + case SEEK_SET: vorb->pos = 0; break; + case SEEK_CUR: break; + case SEEK_END: vorb->pos = vorb->length; break; + } + + vorb->pos += offset; + if (vorb->pos < 0) { + vorb->pos = 0; + } else if (vorb->pos > vorb->length) { + vorb->pos = vorb->length; + } + + return vorb->pos; +} + +static int32_t close_vorbis(void * datasource) +{ + return 0; +} + +static int32_t tell_vorbis(void * datasource) +{ + vorbis_data * vorb = (vorbis_data *) datasource; + + return vorb->pos; +} + +static ov_callbacks vorbis_callbacks = { + read_vorbis, + seek_vorbis, + close_vorbis, + tell_vorbis +}; + + +/*--------------------------------------------------------------------- +Function: MV_GetNextVorbisBlock + +Controls playback of OggVorbis data +---------------------------------------------------------------------*/ + +playbackstatus MV_GetNextVorbisBlock +( + VoiceNode *voice + ) + +{ + vorbis_data * vd = (vorbis_data *) voice->extra; + int32_t bytes, bytesread; + int32_t bitstream, err; + + voice->Playing = TRUE; + + if ( voice->BlockLength > 0 ) + { + voice->position -= voice->length; + voice->sound += voice->length >> 16; + voice->length = min( voice->BlockLength, 0x8000 ); + voice->BlockLength -= voice->length; + voice->length <<= 16; + + return( KeepPlaying ); + } + + bytesread = 0; + do { + bytes = ov_read(&vd->vf, vd->block + bytesread, sizeof(vd->block) - bytesread, 0, 2, 1, &bitstream); + //fprintf(stderr, "ov_read = %d\n", bytes); + if (bytes == OV_HOLE) continue; + if (bytes == 0) { + if (voice->LoopStart) { + err = ov_pcm_seek_page(&vd->vf, 0); + if (err != 0) { + fprintf(stderr, "MV_GetNextVorbisBlock ov_pcm_seek_page_lap: err %d\n", err); + } else { + continue; + } + } else { + break; + } + } else if (bytes < 0) { + fprintf(stderr, "MV_GetNextVorbisBlock ov_read: err %d\n", bytes); + voice->Playing = FALSE; + return NoMoreData; + } + + bytesread += bytes; + } while (bytesread < sizeof(vd->block)); + + if (bytesread == 0) { + voice->Playing = FALSE; + return NoMoreData; + } + + if (bitstream != vd->lastbitstream) { + vorbis_info * vi = 0; + + vi = ov_info(&vd->vf, -1); + if (!vi) { + voice->Playing = FALSE; + return NoMoreData; + } + + if (vi->channels != 1 && vi->channels != 2) { + voice->Playing = FALSE; + return NoMoreData; + } + + voice->channels = vi->channels; + voice->SamplingRate = vi->rate; + voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate; + MV_SetVoiceMixMode( voice ); + } + vd->lastbitstream = bitstream; + + vd->blockused = bytesread; + bytesread /= 2 * voice->channels; + + voice->position = 0; + voice->sound = vd->block; + voice->BlockLength = bytesread; + voice->length = min( voice->BlockLength, 0x8000 ); + voice->BlockLength -= voice->length; + voice->length <<= 16; + + return( KeepPlaying ); +} + + +/*--------------------------------------------------------------------- +Function: MV_PlayVorbis3D + +Begin playback of sound data at specified angle and distance +from listener. +---------------------------------------------------------------------*/ + +int32_t MV_PlayVorbis3D +( + char *ptr, + uint32_t ptrlength, + int32_t pitchoffset, + int32_t angle, + int32_t distance, + int32_t priority, + uint32_t callbackval + ) + +{ + int32_t left; + int32_t right; + int32_t mid; + int32_t volume; + int32_t status; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + if ( distance < 0 ) + { + distance = -distance; + angle += MV_NumPanPositions / 2; + } + + volume = MIX_VOLUME( distance ); + + // Ensure angle is within 0 - 31 + angle &= MV_MaxPanPosition; + + left = MV_PanTable[ angle ][ volume ].left; + right = MV_PanTable[ angle ][ volume ].right; + mid = max( 0, 255 - distance ); + + status = MV_PlayVorbis( ptr, ptrlength, pitchoffset, mid, left, right, priority, + callbackval ); + + return( status ); +} + + +/*--------------------------------------------------------------------- +Function: MV_PlayVorbis + +Begin playback of sound data with the given sound levels and +priority. +---------------------------------------------------------------------*/ + +int32_t MV_PlayVorbis +( + char *ptr, + uint32_t ptrlength, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval + ) + +{ + int32_t status; + + status = MV_PlayLoopedVorbis( ptr, ptrlength, -1, -1, pitchoffset, vol, left, right, + priority, callbackval ); + + return( status ); +} + + +/*--------------------------------------------------------------------- +Function: MV_PlayLoopedVorbis + +Begin playback of sound data with the given sound levels and +priority. +---------------------------------------------------------------------*/ + +int32_t MV_PlayLoopedVorbis +( + char *ptr, + uint32_t ptrlength, + int32_t loopstart, + int32_t loopend, + int32_t pitchoffset, + int32_t vol, + int32_t left, + int32_t right, + int32_t priority, + uint32_t callbackval + ) + +{ + VoiceNode *voice; + int32_t status; + vorbis_data * vd = 0; + vorbis_info * vi = 0; + + if ( !MV_Installed ) + { + MV_SetErrorCode( MV_NotInstalled ); + return( MV_Error ); + } + + vd = (vorbis_data *) malloc( sizeof(vorbis_data) ); + if (!vd) { + MV_SetErrorCode( MV_InvalidVorbisFile ); + return MV_Error; + } + + memset(vd, 0, sizeof(vorbis_data)); + vd->ptr = ptr; + vd->pos = 0; + vd->length = ptrlength; + vd->blockused = 0; + vd->lastbitstream = -1; + + status = ov_open_callbacks((void *) vd, &vd->vf, 0, 0, vorbis_callbacks); + if (status < 0) { + fprintf(stderr, "MV_PlayLoopedVorbis: err %d\n", status); + MV_SetErrorCode( MV_InvalidVorbisFile ); + return MV_Error; + } + + vi = ov_info(&vd->vf, 0); + if (!vi) { + ov_clear(&vd->vf); + free(vd); + MV_SetErrorCode( MV_InvalidVorbisFile ); + return MV_Error; + } + + if (vi->channels != 1 && vi->channels != 2) { + ov_clear(&vd->vf); + free(vd); + MV_SetErrorCode( MV_InvalidVorbisFile ); + return MV_Error; + } + + // Request a voice from the voice pool + voice = MV_AllocVoice( priority ); + if ( voice == NULL ) + { + ov_clear(&vd->vf); + free(vd); + MV_SetErrorCode( MV_NoVoices ); + return( MV_Error ); + } + + voice->wavetype = Vorbis; + voice->bits = 16; + voice->channels = vi->channels; + voice->extra = (void *) vd; + voice->GetSound = MV_GetNextVorbisBlock; + voice->NextBlock = vd->block; + voice->DemandFeed = NULL; + voice->LoopCount = 0; + voice->BlockLength = 0; + voice->PitchScale = PITCH_GetScale( pitchoffset ); + voice->length = 0; + voice->next = NULL; + voice->prev = NULL; + voice->priority = priority; + voice->callbackval = callbackval; + voice->LoopStart = (char *) (loopstart >= 0 ? TRUE : FALSE); + voice->LoopEnd = 0; + voice->LoopSize = 0; + + voice->SamplingRate = vi->rate; + voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate; + MV_SetVoiceMixMode( voice ); + + MV_SetVoiceVolume( voice, vol, left, right ); + MV_PlayVoice( voice ); + + return( voice->handle ); +} + + +void MV_ReleaseVorbisVoice( VoiceNode * voice ) +{ + vorbis_data * vd = (vorbis_data *) voice->extra; + + if (voice->wavetype != Vorbis) { + return; + } + + ov_clear(&vd->vf); + free(vd); + + voice->extra = 0; +} + diff --git a/polymer/eduke32/source/jaudiolib/third-party/README.txt b/polymer/eduke32/source/jaudiolib/third-party/README.txt new file mode 100644 index 000000000..3dbfa6736 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/README.txt @@ -0,0 +1,13 @@ +OS X frameworks compiled from the sources contained in the Max audio ripper +application by Stephen Booth. + + http://svn.sbooth.org/max/trunk/Frameworks/ogg/ + http://svn.sbooth.org/max/trunk/Frameworks/vorbis/ + http://sbooth.org/Max/ + + +MinGW binaries compiled from vanilla Xiph.org libogg-1.1.4 and libvorbis-1.2.3 +on MinGW GCC 3.4.5. + + http://xiph.org/downloads/ + diff --git a/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/ogg/config_types.h b/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/ogg/config_types.h new file mode 100644 index 000000000..a320fc854 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/ogg/config_types.h @@ -0,0 +1,11 @@ +#ifndef __CONFIG_TYPES_H__ +#define __CONFIG_TYPES_H__ + +/* these are filled in by configure */ +typedef short ogg_int16_t; +typedef unsigned short ogg_uint16_t; +typedef int ogg_int32_t; +typedef unsigned int ogg_uint32_t; +typedef long long ogg_int64_t; + +#endif diff --git a/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/ogg/ogg.h b/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/ogg/ogg.h new file mode 100644 index 000000000..ae0cfd534 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/ogg/ogg.h @@ -0,0 +1,208 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel libogg include + last mod: $Id: ogg.h 16051 2009-05-27 05:00:06Z xiphmont $ + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef struct { + void *iov_base; + size_t iov_len; +} ogg_iovec_t; + +typedef struct { + long endbyte; + int endbit; + + unsigned char *buffer; + unsigned char *ptr; + long storage; +} oggpack_buffer; + +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ + +typedef struct { + unsigned char *header; + long header_len; + unsigned char *body; + long body_len; +} ogg_page; + +/* ogg_stream_state contains the current encode/decode state of a logical + Ogg bitstream **********************************************************/ + +typedef struct { + unsigned char *body_data; /* bytes from packet bodies */ + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + + + int *lacing_vals; /* The values that will go to the segment table */ + ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact + this way, but it is simple coupled to the + lacing fifo */ + long lacing_storage; + long lacing_fill; + long lacing_packet; + long lacing_returned; + + unsigned char header[282]; /* working space for header encode */ + int header_fill; + + int e_o_s; /* set when we have buffered the last packet in the + logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + +} ogg_stream_state; + +/* ogg_packet is used to encapsulate the data and metadata belonging + to a single raw Ogg/Vorbis packet *************************************/ + +typedef struct { + unsigned char *packet; + long bytes; + long b_o_s; + long e_o_s; + + ogg_int64_t granulepos; + + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + unsigned char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} ogg_sync_state; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_writeinit(oggpack_buffer *b); +extern int oggpack_writecheck(oggpack_buffer *b); +extern void oggpack_writetrunc(oggpack_buffer *b,long bits); +extern void oggpack_writealign(oggpack_buffer *b); +extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpack_reset(oggpack_buffer *b); +extern void oggpack_writeclear(oggpack_buffer *b); +extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern long oggpack_look1(oggpack_buffer *b); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern void oggpack_adv1(oggpack_buffer *b); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_read1(oggpack_buffer *b); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); + +extern void oggpackB_writeinit(oggpack_buffer *b); +extern int oggpackB_writecheck(oggpack_buffer *b); +extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); +extern void oggpackB_writealign(oggpack_buffer *b); +extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpackB_reset(oggpack_buffer *b); +extern void oggpackB_writeclear(oggpack_buffer *b); +extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpackB_look(oggpack_buffer *b,int bits); +extern long oggpackB_look1(oggpack_buffer *b); +extern void oggpackB_adv(oggpack_buffer *b,int bits); +extern void oggpackB_adv1(oggpack_buffer *b); +extern long oggpackB_read(oggpack_buffer *b,int bits); +extern long oggpackB_read1(oggpack_buffer *b); +extern long oggpackB_bytes(oggpack_buffer *b); +extern long oggpackB_bits(oggpack_buffer *b); +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ + +extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, + int count, long e_o_s, ogg_int64_t granulepos); +extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern int ogg_sync_init(ogg_sync_state *oy); +extern int ogg_sync_clear(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); +extern int ogg_sync_destroy(ogg_sync_state *oy); +extern int ogg_sync_check(ogg_sync_state *oy); + +extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern int ogg_stream_init(ogg_stream_state *os,int serialno); +extern int ogg_stream_clear(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_check(ogg_stream_state *os); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern void ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(const ogg_page *og); +extern int ogg_page_continued(const ogg_page *og); +extern int ogg_page_bos(const ogg_page *og); +extern int ogg_page_eos(const ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(const ogg_page *og); +extern int ogg_page_serialno(const ogg_page *og); +extern long ogg_page_pageno(const ogg_page *og); +extern int ogg_page_packets(const ogg_page *og); + +extern void ogg_packet_clear(ogg_packet *op); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ diff --git a/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/ogg/os_types.h b/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/ogg/os_types.h new file mode 100644 index 000000000..a42f8007e --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/ogg/os_types.h @@ -0,0 +1,139 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 14997 2008-06-04 03:27:18Z ivo $ + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; +# elif defined(__MINGW32__) +# include + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; +# elif defined(__MWERKS__) + typedef long long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; +# else + /* MSVC/Borland */ + typedef __int64 ogg_int64_t; + typedef __int32 ogg_int32_t; + typedef unsigned __int32 ogg_uint32_t; + typedef __int16 ogg_int16_t; + typedef unsigned __int16 ogg_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include + typedef SInt16 ogg_int16_t; + typedef UInt16 ogg_uint16_t; + typedef SInt32 ogg_int32_t; + typedef UInt32 ogg_uint32_t; + typedef SInt64 ogg_int64_t; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined(__HAIKU__) + + /* Haiku */ +# include + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short ogg_int16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned ogg_uint32_t; + typedef short ogg_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#else + +# include +# include + +#endif + +#endif /* _OS_TYPES_H */ diff --git a/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/vorbis/codec.h b/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/vorbis/codec.h new file mode 100644 index 000000000..259798c61 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/vorbis/codec.h @@ -0,0 +1,243 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + + ******************************************************************** + + function: libvorbis codec headers + last mod: $Id: codec.h 16037 2009-05-26 21:10:58Z xiphmont $ + + ********************************************************************/ + +#ifndef _vorbis_codec_h_ +#define _vorbis_codec_h_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include + +typedef struct vorbis_info{ + int version; + int channels; + long rate; + + /* The below bitrate declarations are *hints*. + Combinations of the three values carry the following implications: + + all three set to the same value: + implies a fixed rate bitstream + only nominal set: + implies a VBR stream that averages the nominal bitrate. No hard + upper/lower limit + upper and or lower set: + implies a VBR bitstream that obeys the bitrate limits. nominal + may also be set to give a nominal rate. + none set: + the coder does not care to speculate. + */ + + long bitrate_upper; + long bitrate_nominal; + long bitrate_lower; + long bitrate_window; + + void *codec_setup; +} vorbis_info; + +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +typedef struct vorbis_dsp_state{ + int analysisp; + vorbis_info *vi; + + float **pcm; + float **pcmret; + int pcm_storage; + int pcm_current; + int pcm_returned; + + int preextrapolate; + int eofflag; + + long lW; + long W; + long nW; + long centerW; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + + ogg_int64_t glue_bits; + ogg_int64_t time_bits; + ogg_int64_t floor_bits; + ogg_int64_t res_bits; + + void *backend_state; +} vorbis_dsp_state; + +typedef struct vorbis_block{ + /* necessary stream state for linking to the framing abstraction */ + float **pcm; /* this is a pointer into local storage */ + oggpack_buffer opb; + + long lW; + long W; + long nW; + int pcmend; + int mode; + + int eofflag; + ogg_int64_t granulepos; + ogg_int64_t sequence; + vorbis_dsp_state *vd; /* For read-only access of configuration */ + + /* local storage to avoid remallocing; it's up to the mapping to + structure it */ + void *localstore; + long localtop; + long localalloc; + long totaluse; + struct alloc_chain *reap; + + /* bitmetrics for the frame */ + long glue_bits; + long time_bits; + long floor_bits; + long res_bits; + + void *internal; + +} vorbis_block; + +/* vorbis_block is a single block of data to be processed as part of +the analysis/synthesis stream; it belongs to a specific logical +bitstream, but is independant from other vorbis_blocks belonging to +that logical bitstream. *************************************************/ + +struct alloc_chain{ + void *ptr; + struct alloc_chain *next; +}; + +/* vorbis_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). vorbis_info and substructures are in backends.h. +*********************************************************************/ + +/* the comments are not part of vorbis_info so that vorbis_info can be + static storage */ +typedef struct vorbis_comment{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int *comment_lengths; + int comments; + char *vendor; + +} vorbis_comment; + + +/* libvorbis encodes in two abstraction layers; first we perform DSP + and produce a packet (see docs/analysis.txt). The packet is then + coded into a framed OggSquish bitstream by the second layer (see + docs/framing.txt). Decode is the reverse process; we sync/frame + the bitstream and extract individual packets, then decode the + packet back into PCM audio. + + The extra framing/packetizing is used in streaming formats, such as + files. Over the net (such as with UDP), the framing and + packetization aren't necessary as they're provided by the transport + and the streaming layer is not used */ + +/* Vorbis PRIMITIVES: general ***************************************/ + +extern void vorbis_info_init(vorbis_info *vi); +extern void vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +extern void vorbis_comment_init(vorbis_comment *vc); +extern void vorbis_comment_add(vorbis_comment *vc, const char *comment); +extern void vorbis_comment_add_tag(vorbis_comment *vc, + const char *tag, const char *contents); +extern char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count); +extern int vorbis_comment_query_count(vorbis_comment *vc, const char *tag); +extern void vorbis_comment_clear(vorbis_comment *vc); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_dsp_clear(vorbis_dsp_state *v); +extern double vorbis_granule_time(vorbis_dsp_state *v, + ogg_int64_t granulepos); + +extern const char *vorbis_version_string(void); + +/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ + +extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); +extern int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code); +extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); + +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, + ogg_packet *op); + +/* Vorbis PRIMITIVES: synthesis layer *******************************/ +extern int vorbis_synthesis_idheader(ogg_packet *op); +extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_synthesis_restart(vorbis_dsp_state *v); +extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + +extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); +extern int vorbis_synthesis_halfrate_p(vorbis_info *v); + +/* Vorbis ERRORS and return codes ***********************************/ + +#define OV_FALSE -1 +#define OV_EOF -2 +#define OV_HOLE -3 + +#define OV_EREAD -128 +#define OV_EFAULT -129 +#define OV_EIMPL -130 +#define OV_EINVAL -131 +#define OV_ENOTVORBIS -132 +#define OV_EBADHEADER -133 +#define OV_EVERSION -134 +#define OV_ENOTAUDIO -135 +#define OV_EBADPACKET -136 +#define OV_EBADLINK -137 +#define OV_ENOSEEK -138 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/vorbis/vorbisfile.h b/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/vorbis/vorbisfile.h new file mode 100644 index 000000000..ef2a36d3e --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/mingw32/include/vorbis/vorbisfile.h @@ -0,0 +1,206 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.h 16243 2009-07-10 02:49:31Z xiphmont $ + + ********************************************************************/ + +#ifndef _OV_FILE_H_ +#define _OV_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include +#include "codec.h" + +/* The function prototypes for the callbacks are basically the same as for + * the stdio functions fread, fseek, fclose, ftell. + * The one difference is that the FILE * arguments have been replaced with + * a void * - this is to be used as a pointer to whatever internal data these + * functions might need. In the stdio case, it's just a FILE * cast to a void * + * + * If you use other functions, check the docs for these functions and return + * the right values. For seek_func(), you *MUST* return -1 if the stream is + * unseekable + */ +typedef struct { + size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (*close_func) (void *datasource); + long (*tell_func) (void *datasource); +} ov_callbacks; + +#ifndef OV_EXCLUDE_STATIC_CALLBACKS + +/* a few sets of convenient callbacks, especially for use under + * Windows where ov_open_callbacks() should always be used instead of + * ov_open() to avoid problems with incompatable crt.o version linking + * issues. */ + +static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){ + if(f==NULL)return(-1); + +#ifdef __MINGW32__ + return fseeko64(f,off,whence); +#elif defined (_WIN32) + return _fseeki64(f,off,whence); +#else + return fseek(f,off,whence); +#endif +} + +/* These structs below (OV_CALLBACKS_DEFAULT etc) are defined here as + * static data. That means that every file which includes this header + * will get its own copy of these structs whether it uses them or + * not unless it #defines OV_EXCLUDE_STATIC_CALLBACKS. + * These static symbols are essential on platforms such as Windows on + * which several different versions of stdio support may be linked to + * by different DLLs, and we need to be certain we know which one + * we're using (the same one as the main application). + */ + +static ov_callbacks OV_CALLBACKS_DEFAULT = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) NULL, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) fclose, + (long (*)(void *)) NULL +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) NULL, + (long (*)(void *)) NULL +}; + +#endif + +#define NOTOPEN 0 +#define PARTOPEN 1 +#define OPENED 2 +#define STREAMSET 3 +#define INITSET 4 + +typedef struct OggVorbis_File { + void *datasource; /* Pointer to a FILE *, etc. */ + int seekable; + ogg_int64_t offset; + ogg_int64_t end; + ogg_sync_state oy; + + /* If the FILE handle isn't seekable (eg, a pipe), only the current + stream appears */ + int links; + ogg_int64_t *offsets; + ogg_int64_t *dataoffsets; + long *serialnos; + ogg_int64_t *pcmlengths; /* overloaded to maintain binary + compatability; x2 size, stores both + beginning and end values */ + vorbis_info *vi; + vorbis_comment *vc; + + /* Decoding working state local storage */ + ogg_int64_t pcm_offset; + int ready_state; + long current_serialno; + int current_link; + + double bittrack; + double samptrack; + + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + ov_callbacks callbacks; + +} OggVorbis_File; + + +extern int ov_clear(OggVorbis_File *vf); +extern int ov_fopen(char *path,OggVorbis_File *vf); +extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); + +extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); +extern int ov_test_open(OggVorbis_File *vf); + +extern long ov_bitrate(OggVorbis_File *vf,int i); +extern long ov_bitrate_instant(OggVorbis_File *vf); +extern long ov_streams(OggVorbis_File *vf); +extern long ov_seekable(OggVorbis_File *vf); +extern long ov_serialnumber(OggVorbis_File *vf,int i); + +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); +extern double ov_time_total(OggVorbis_File *vf,int i); + +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page(OggVorbis_File *vf,double pos); + +extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek_lap(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos); + +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); +extern double ov_time_tell(OggVorbis_File *vf); + +extern vorbis_info *ov_info(OggVorbis_File *vf,int link); +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); + +extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples, + int *bitstream); +extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream, + void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param); +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream); +extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2); + +extern int ov_halfrate(OggVorbis_File *vf,int flag); +extern int ov_halfrate_p(OggVorbis_File *vf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Headers b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Headers new file mode 120000 index 000000000..a177d2a6b --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Resources b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Resources new file mode 120000 index 000000000..953ee36f3 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Headers/ogg.h b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Headers/ogg.h new file mode 100644 index 000000000..9082679d9 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Headers/ogg.h @@ -0,0 +1,202 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel libogg include + last mod: $Id: ogg.h 7188 2004-07-20 07:26:04Z xiphmont $ + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef struct { + long endbyte; + int endbit; + + unsigned char *buffer; + unsigned char *ptr; + long storage; +} oggpack_buffer; + +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ + +typedef struct { + unsigned char *header; + long header_len; + unsigned char *body; + long body_len; +} ogg_page; + +/* ogg_stream_state contains the current encode/decode state of a logical + Ogg bitstream **********************************************************/ + +typedef struct { + unsigned char *body_data; /* bytes from packet bodies */ + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + + + int *lacing_vals; /* The values that will go to the segment table */ + ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact + this way, but it is simple coupled to the + lacing fifo */ + long lacing_storage; + long lacing_fill; + long lacing_packet; + long lacing_returned; + + unsigned char header[282]; /* working space for header encode */ + int header_fill; + + int e_o_s; /* set when we have buffered the last packet in the + logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + +} ogg_stream_state; + +/* ogg_packet is used to encapsulate the data and metadata belonging + to a single raw Ogg/Vorbis packet *************************************/ + +typedef struct { + unsigned char *packet; + long bytes; + long b_o_s; + long e_o_s; + + ogg_int64_t granulepos; + + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a seperate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + unsigned char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} ogg_sync_state; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_writeinit(oggpack_buffer *b); +extern void oggpack_writetrunc(oggpack_buffer *b,long bits); +extern void oggpack_writealign(oggpack_buffer *b); +extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpack_reset(oggpack_buffer *b); +extern void oggpack_writeclear(oggpack_buffer *b); +extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern long oggpack_look1(oggpack_buffer *b); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern void oggpack_adv1(oggpack_buffer *b); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_read1(oggpack_buffer *b); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); + +extern void oggpackB_writeinit(oggpack_buffer *b); +extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); +extern void oggpackB_writealign(oggpack_buffer *b); +extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpackB_reset(oggpack_buffer *b); +extern void oggpackB_writeclear(oggpack_buffer *b); +extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpackB_look(oggpack_buffer *b,int bits); +extern long oggpackB_look1(oggpack_buffer *b); +extern void oggpackB_adv(oggpack_buffer *b,int bits); +extern void oggpackB_adv1(oggpack_buffer *b); +extern long oggpackB_read(oggpack_buffer *b,int bits); +extern long oggpackB_read1(oggpack_buffer *b); +extern long oggpackB_bytes(oggpack_buffer *b); +extern long oggpackB_bits(oggpack_buffer *b); +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ + +extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern int ogg_sync_init(ogg_sync_state *oy); +extern int ogg_sync_clear(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); +extern int ogg_sync_destroy(ogg_sync_state *oy); + +extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern int ogg_stream_init(ogg_stream_state *os,int serialno); +extern int ogg_stream_clear(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern void ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(ogg_page *og); +extern int ogg_page_continued(ogg_page *og); +extern int ogg_page_bos(ogg_page *og); +extern int ogg_page_eos(ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(ogg_page *og); +extern int ogg_page_serialno(ogg_page *og); +extern long ogg_page_pageno(ogg_page *og); +extern int ogg_page_packets(ogg_page *og); + +extern void ogg_packet_clear(ogg_packet *op); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ + + + + + + diff --git a/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Headers/os_types.h b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Headers/os_types.h new file mode 100644 index 000000000..32dcb8bff --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Headers/os_types.h @@ -0,0 +1,127 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $ + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int64_t ogg_int64_t; + typedef _G_int32_t ogg_int32_t; + typedef _G_uint32_t ogg_uint32_t; + typedef _G_int16_t ogg_int16_t; + typedef _G_uint16_t ogg_uint16_t; +# elif defined(__MINGW32__) + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; +# elif defined(__MWERKS__) + typedef long long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; +# else + /* MSVC/Borland */ + typedef __int64 ogg_int64_t; + typedef __int32 ogg_int32_t; + typedef unsigned __int32 ogg_uint32_t; + typedef __int16 ogg_int16_t; + typedef unsigned __int16 ogg_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include + typedef SInt16 ogg_int16_t; + typedef UInt16 ogg_uint16_t; + typedef SInt32 ogg_int32_t; + typedef UInt32 ogg_uint32_t; + typedef SInt64 ogg_int64_t; + +#elif defined(__MACOSX__) /* MacOS X Framework build */ + +# include + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short ogg_int16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef long ogg_int64_t; + typedef int ogg_int32_t; + typedef unsigned ogg_uint32_t; + typedef short ogg_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + +#else + +# include +# include + +#endif + +#endif /* _OS_TYPES_H */ diff --git a/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Resources/English.lproj/InfoPlist.strings b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Resources/English.lproj/InfoPlist.strings new file mode 100644 index 000000000..7080cf949 Binary files /dev/null and b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Resources/English.lproj/InfoPlist.strings differ diff --git a/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Resources/Info.plist b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Resources/Info.plist new file mode 100644 index 000000000..4b6c1a8d5 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ogg + CFBundleIdentifier + com.yourcompany.yourcocoaframework + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ogg + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/ogg b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/ogg new file mode 100755 index 000000000..9e4a0555e Binary files /dev/null and b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/A/ogg differ diff --git a/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/Current b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/Current new file mode 120000 index 000000000..8c7e5a667 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/ogg b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/ogg new file mode 120000 index 000000000..aa84ee717 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/ogg.framework/ogg @@ -0,0 +1 @@ +Versions/Current/ogg \ No newline at end of file diff --git a/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Headers b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Headers new file mode 120000 index 000000000..a177d2a6b --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Resources b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Resources new file mode 120000 index 000000000..953ee36f3 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Headers/codec.h b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Headers/codec.h new file mode 100644 index 000000000..03f29bf36 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Headers/codec.h @@ -0,0 +1,240 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + + ******************************************************************** + + function: libvorbis codec headers + last mod: $Id: codec.h 7485 2004-08-05 14:54:23Z thomasvs $ + + ********************************************************************/ + +#ifndef _vorbis_codec_h_ +#define _vorbis_codec_h_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include + +typedef struct vorbis_info{ + int version; + int channels; + long rate; + + /* The below bitrate declarations are *hints*. + Combinations of the three values carry the following implications: + + all three set to the same value: + implies a fixed rate bitstream + only nominal set: + implies a VBR stream that averages the nominal bitrate. No hard + upper/lower limit + upper and or lower set: + implies a VBR bitstream that obeys the bitrate limits. nominal + may also be set to give a nominal rate. + none set: + the coder does not care to speculate. + */ + + long bitrate_upper; + long bitrate_nominal; + long bitrate_lower; + long bitrate_window; + + void *codec_setup; +} vorbis_info; + +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +typedef struct vorbis_dsp_state{ + int analysisp; + vorbis_info *vi; + + float **pcm; + float **pcmret; + int pcm_storage; + int pcm_current; + int pcm_returned; + + int preextrapolate; + int eofflag; + + long lW; + long W; + long nW; + long centerW; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + + ogg_int64_t glue_bits; + ogg_int64_t time_bits; + ogg_int64_t floor_bits; + ogg_int64_t res_bits; + + void *backend_state; +} vorbis_dsp_state; + +typedef struct vorbis_block{ + /* necessary stream state for linking to the framing abstraction */ + float **pcm; /* this is a pointer into local storage */ + oggpack_buffer opb; + + long lW; + long W; + long nW; + int pcmend; + int mode; + + int eofflag; + ogg_int64_t granulepos; + ogg_int64_t sequence; + vorbis_dsp_state *vd; /* For read-only access of configuration */ + + /* local storage to avoid remallocing; it's up to the mapping to + structure it */ + void *localstore; + long localtop; + long localalloc; + long totaluse; + struct alloc_chain *reap; + + /* bitmetrics for the frame */ + long glue_bits; + long time_bits; + long floor_bits; + long res_bits; + + void *internal; + +} vorbis_block; + +/* vorbis_block is a single block of data to be processed as part of +the analysis/synthesis stream; it belongs to a specific logical +bitstream, but is independant from other vorbis_blocks belonging to +that logical bitstream. *************************************************/ + +struct alloc_chain{ + void *ptr; + struct alloc_chain *next; +}; + +/* vorbis_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). vorbis_info and substructures are in backends.h. +*********************************************************************/ + +/* the comments are not part of vorbis_info so that vorbis_info can be + static storage */ +typedef struct vorbis_comment{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int *comment_lengths; + int comments; + char *vendor; + +} vorbis_comment; + + +/* libvorbis encodes in two abstraction layers; first we perform DSP + and produce a packet (see docs/analysis.txt). The packet is then + coded into a framed OggSquish bitstream by the second layer (see + docs/framing.txt). Decode is the reverse process; we sync/frame + the bitstream and extract individual packets, then decode the + packet back into PCM audio. + + The extra framing/packetizing is used in streaming formats, such as + files. Over the net (such as with UDP), the framing and + packetization aren't necessary as they're provided by the transport + and the streaming layer is not used */ + +/* Vorbis PRIMITIVES: general ***************************************/ + +extern void vorbis_info_init(vorbis_info *vi); +extern void vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +extern void vorbis_comment_init(vorbis_comment *vc); +extern void vorbis_comment_add(vorbis_comment *vc, char *comment); +extern void vorbis_comment_add_tag(vorbis_comment *vc, + char *tag, char *contents); +extern char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count); +extern int vorbis_comment_query_count(vorbis_comment *vc, char *tag); +extern void vorbis_comment_clear(vorbis_comment *vc); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_dsp_clear(vorbis_dsp_state *v); +extern double vorbis_granule_time(vorbis_dsp_state *v, + ogg_int64_t granulepos); + +/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ + +extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); +extern int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code); +extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); + +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, + ogg_packet *op); + +/* Vorbis PRIMITIVES: synthesis layer *******************************/ +extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_synthesis_restart(vorbis_dsp_state *v); +extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + +extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); +extern int vorbis_synthesis_halfrate_p(vorbis_info *v); + +/* Vorbis ERRORS and return codes ***********************************/ + +#define OV_FALSE -1 +#define OV_EOF -2 +#define OV_HOLE -3 + +#define OV_EREAD -128 +#define OV_EFAULT -129 +#define OV_EIMPL -130 +#define OV_EINVAL -131 +#define OV_ENOTVORBIS -132 +#define OV_EBADHEADER -133 +#define OV_EVERSION -134 +#define OV_ENOTAUDIO -135 +#define OV_EBADPACKET -136 +#define OV_EBADLINK -137 +#define OV_ENOSEEK -138 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Headers/vorbisenc.h b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Headers/vorbisenc.h new file mode 100644 index 000000000..a60081ac9 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Headers/vorbisenc.h @@ -0,0 +1,112 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: vorbis encode-engine setup + last mod: $Id: vorbisenc.h 7485 2004-08-05 14:54:23Z thomasvs $ + + ********************************************************************/ + +#ifndef _OV_ENC_H_ +#define _OV_ENC_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "codec.h" + +extern int vorbis_encode_init(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +extern int vorbis_encode_setup_managed(vorbis_info *vi, + long channels, + long rate, + + long max_bitrate, + long nominal_bitrate, + long min_bitrate); + +extern int vorbis_encode_setup_vbr(vorbis_info *vi, + long channels, + long rate, + + float quality /* quality level from 0. (lo) to 1. (hi) */ + ); + +extern int vorbis_encode_init_vbr(vorbis_info *vi, + long channels, + long rate, + + float base_quality /* quality level from 0. (lo) to 1. (hi) */ + ); + +extern int vorbis_encode_setup_init(vorbis_info *vi); + +extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg); + + /* deprecated rate management supported only for compatability */ +#define OV_ECTL_RATEMANAGE_GET 0x10 +#define OV_ECTL_RATEMANAGE_SET 0x11 +#define OV_ECTL_RATEMANAGE_AVG 0x12 +#define OV_ECTL_RATEMANAGE_HARD 0x13 + +struct ovectl_ratemanage_arg { + int management_active; + + long bitrate_hard_min; + long bitrate_hard_max; + double bitrate_hard_window; + + long bitrate_av_lo; + long bitrate_av_hi; + double bitrate_av_window; + double bitrate_av_window_center; +}; + + + /* new rate setup */ +#define OV_ECTL_RATEMANAGE2_GET 0x14 +#define OV_ECTL_RATEMANAGE2_SET 0x15 + +struct ovectl_ratemanage2_arg { + int management_active; + + long bitrate_limit_min_kbps; + long bitrate_limit_max_kbps; + long bitrate_limit_reservoir_bits; + double bitrate_limit_reservoir_bias; + + long bitrate_average_kbps; + double bitrate_average_damping; +}; + + + +#define OV_ECTL_LOWPASS_GET 0x20 +#define OV_ECTL_LOWPASS_SET 0x21 + +#define OV_ECTL_IBLOCK_GET 0x30 +#define OV_ECTL_IBLOCK_SET 0x31 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + + diff --git a/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Headers/vorbisfile.h b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Headers/vorbisfile.h new file mode 100644 index 000000000..259fa89b6 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Headers/vorbisfile.h @@ -0,0 +1,143 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.h 7485 2004-08-05 14:54:23Z thomasvs $ + + ********************************************************************/ + +#ifndef _OV_FILE_H_ +#define _OV_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include +#include "codec.h" + +/* The function prototypes for the callbacks are basically the same as for + * the stdio functions fread, fseek, fclose, ftell. + * The one difference is that the FILE * arguments have been replaced with + * a void * - this is to be used as a pointer to whatever internal data these + * functions might need. In the stdio case, it's just a FILE * cast to a void * + * + * If you use other functions, check the docs for these functions and return + * the right values. For seek_func(), you *MUST* return -1 if the stream is + * unseekable + */ +typedef struct { + size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (*close_func) (void *datasource); + long (*tell_func) (void *datasource); +} ov_callbacks; + +#define NOTOPEN 0 +#define PARTOPEN 1 +#define OPENED 2 +#define STREAMSET 3 +#define INITSET 4 + +typedef struct OggVorbis_File { + void *datasource; /* Pointer to a FILE *, etc. */ + int seekable; + ogg_int64_t offset; + ogg_int64_t end; + ogg_sync_state oy; + + /* If the FILE handle isn't seekable (eg, a pipe), only the current + stream appears */ + int links; + ogg_int64_t *offsets; + ogg_int64_t *dataoffsets; + long *serialnos; + ogg_int64_t *pcmlengths; /* overloaded to maintain binary + compatability; x2 size, stores both + beginning and end values */ + vorbis_info *vi; + vorbis_comment *vc; + + /* Decoding working state local storage */ + ogg_int64_t pcm_offset; + int ready_state; + long current_serialno; + int current_link; + + double bittrack; + double samptrack; + + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + ov_callbacks callbacks; + +} OggVorbis_File; + +extern int ov_clear(OggVorbis_File *vf); +extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); + +extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes); +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, + char *initial, long ibytes, ov_callbacks callbacks); +extern int ov_test_open(OggVorbis_File *vf); + +extern long ov_bitrate(OggVorbis_File *vf,int i); +extern long ov_bitrate_instant(OggVorbis_File *vf); +extern long ov_streams(OggVorbis_File *vf); +extern long ov_seekable(OggVorbis_File *vf); +extern long ov_serialnumber(OggVorbis_File *vf,int i); + +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); +extern double ov_time_total(OggVorbis_File *vf,int i); + +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page(OggVorbis_File *vf,double pos); + +extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek_lap(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos); + +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); +extern double ov_time_tell(OggVorbis_File *vf); + +extern vorbis_info *ov_info(OggVorbis_File *vf,int link); +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); + +extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples, + int *bitstream); +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream); +extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2); + +extern int ov_halfrate(OggVorbis_File *vf,int flag); +extern int ov_halfrate_p(OggVorbis_File *vf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + + diff --git a/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Resources/English.lproj/InfoPlist.strings b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Resources/English.lproj/InfoPlist.strings new file mode 100644 index 000000000..7080cf949 Binary files /dev/null and b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Resources/English.lproj/InfoPlist.strings differ diff --git a/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Resources/Info.plist b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Resources/Info.plist new file mode 100644 index 000000000..e73b193b3 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + vorbis + CFBundleIdentifier + com.yourcompany.yourcocoaframework + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + vorbis + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/vorbis b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/vorbis new file mode 100755 index 000000000..64b37e759 Binary files /dev/null and b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/A/vorbis differ diff --git a/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/Current b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/Current new file mode 120000 index 000000000..8c7e5a667 --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/vorbis b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/vorbis new file mode 120000 index 000000000..85a6d550c --- /dev/null +++ b/polymer/eduke32/source/jaudiolib/third-party/vorbis.framework/vorbis @@ -0,0 +1 @@ +Versions/Current/vorbis \ No newline at end of file