Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 87685 | Differences between
and this patch

Collapse All | Expand All

(-)jfduke3d_src_20051009.orig/Makefile (-8 / +13 lines)
Lines 12-18 Link Here
12
NOASM = 0
12
NOASM = 0
13
13
14
# Debugging options
14
# Debugging options
15
RELEASE?=0
15
RELEASE?=1
16
16
17
# build locations
17
# build locations
18
SRC=source/
18
SRC=source/
Lines 55-65 Link Here
55
AUDIOLIB_FX=$(OBJ)mv_mix.$o \
55
AUDIOLIB_FX=$(OBJ)mv_mix.$o \
56
	  $(OBJ)mv_mix16.$o \
56
	  $(OBJ)mv_mix16.$o \
57
	  $(OBJ)mvreverb.$o \
57
	  $(OBJ)mvreverb.$o \
58
	  $(OBJ)pitch.$o \
59
	  $(OBJ)multivoc.$o \
60
	  $(OBJ)ll_man.$o \
58
	  $(OBJ)ll_man.$o \
61
	  $(OBJ)fx_man.$o \
59
	  $(OBJ)fx_man.$o
62
	  $(OBJ)dsoundout.$o
63
AUDIOLIB_MUSIC=$(OBJ)midi.$o \
60
AUDIOLIB_MUSIC=$(OBJ)midi.$o \
64
	  $(OBJ)mpu401.$o \
61
	  $(OBJ)mpu401.$o \
65
	  $(OBJ)music.$o
62
	  $(OBJ)music.$o
Lines 96-103 Link Here
96
endif
93
endif
97
94
98
ifeq ($(RENDERTYPE),SDL)
95
ifeq ($(RENDERTYPE),SDL)
99
	override CFLAGS+= $(subst -Dmain=SDL_main,,$(shell sdl-config --cflags))
96
	override CFLAGS+= $(subst -Dmain=SDL_main,,$(shell sdl-config --cflags) -D__cdecl=" ") 
100
	AUDIOLIBOBJ=$(AUDIOLIB_MUSIC_STUB) $(AUDIOLIB_FX_STUB)
97
	LIBS+= $(shell sdl-config --libs) -lSDL_mixer
98
	AUDIOLIB_FX+= $(OBJ)dsl.$o \
99
		      $(OBJ)nodpmi.$o \
100
		      $(OBJ)unixpitch.$o \
101
		      $(OBJ)unixvoc.$o
102
103
	AUDIOLIB_MUSIC=$(OBJ)sdlmusic.$o $(OBJ)unixglob.$o
104
	AUDIOLIBOBJ=$(AUDIOLIB_MUSIC) $(AUDIOLIB_FX)
101
105
102
	ifeq (1,$(HAVE_GTK2))
106
	ifeq (1,$(HAVE_GTK2))
103
		override CFLAGS+= -DHAVE_GTK2 $(shell pkg-config --cflags gtk+-2.0)
107
		override CFLAGS+= -DHAVE_GTK2 $(shell pkg-config --cflags gtk+-2.0)
Lines 125-135 Link Here
125
build$(EXESUFFIX): $(EDITOROBJS) $(EOBJ)$(EDITORLIB) $(EOBJ)$(ENGINELIB)
129
build$(EXESUFFIX): $(EDITOROBJS) $(EOBJ)$(EDITORLIB) $(EOBJ)$(ENGINELIB)
126
	$(CC) $(CFLAGS) -o $@ $^ $(LIBS) -Wl,-Map=$@.map
130
	$(CC) $(CFLAGS) -o $@ $^ $(LIBS) -Wl,-Map=$@.map
127
131
132
AUDIOLIB=$(SRC)/jaudiolib
128
include Makefile.deps
133
include Makefile.deps
129
134
130
.PHONY: enginelib editorlib
135
.PHONY: enginelib editorlib
131
enginelib editorlib:
136
enginelib editorlib:
132
	-mkdir $(EOBJ)
137
	-mkdir -p $(EOBJ)
133
	$(MAKE) -C $(EROOT) "OBJ=$(CURDIR)/$(EOBJ)" \
138
	$(MAKE) -C $(EROOT) "OBJ=$(CURDIR)/$(EOBJ)" \
134
		SUPERBUILD=$(SUPERBUILD) POLYMOST=$(POLYMOST) \
139
		SUPERBUILD=$(SUPERBUILD) POLYMOST=$(POLYMOST) \
135
		USE_OPENGL=$(USE_OPENGL) DYNAMIC_OPENGL=$(DYNAMIC_OPENGL) \
140
		USE_OPENGL=$(USE_OPENGL) DYNAMIC_OPENGL=$(DYNAMIC_OPENGL) \
(-)jfduke3d_src_20051009.orig/Makefile.deps (+5 lines)
Lines 33-38 Link Here
33
$(OBJ)scriplib.$o: $(SRC)jmact/scriplib.c $(SRC)jmact/scriplib.h $(SRC)jmact/util_lib.h $(SRC)jmact/_scrplib.h $(INC)types.h $(EINC)compat.h
33
$(OBJ)scriplib.$o: $(SRC)jmact/scriplib.c $(SRC)jmact/scriplib.h $(SRC)jmact/util_lib.h $(SRC)jmact/_scrplib.h $(INC)types.h $(EINC)compat.h
34
34
35
# jAudioLib objects
35
# jAudioLib objects
36
$(OBJ)dsl.$o: $(SRC)jaudiolib/dsl.c $(SRC)jaudiolib/util.h
37
$(OBJ)nodpmi.$o: $(SRC)jaudiolib/nodpmi.c $(SRC)jaudiolib/dpmi.h
38
$(OBJ)unixpitch.$o: $(SRC)jaudiolib/unixpitch.c $(SRC)jaudiolib/pitch.h
39
$(OBJ)unixvoc.$o: $(SRC)jaudiolib/unixvoc.c $(SRC)jaudiolib/usrhooks.h $(SRC)jaudiolib/linklist.h $(SRC)jaudiolib/pitch.h $(SRC)jaudiolib/multivoc.h $(SRC)jaudiolib/_multivc.h
40
36
$(OBJ)audiolib_fxstub.$o: $(SRC)jaudiolib/audiolib_fxstub.c $(SRC)jaudiolib/fx_man.h
41
$(OBJ)audiolib_fxstub.$o: $(SRC)jaudiolib/audiolib_fxstub.c $(SRC)jaudiolib/fx_man.h
37
$(OBJ)audiolib_musicstub.$o: $(SRC)jaudiolib/audiolib_musicstub.c $(SRC)jaudiolib/music.h
42
$(OBJ)audiolib_musicstub.$o: $(SRC)jaudiolib/audiolib_musicstub.c $(SRC)jaudiolib/music.h
38
43
(-)jfduke3d_src_20051009.orig/source/config.c (-2 / +4 lines)
Lines 203-210 Link Here
203
   int32 i,f;
203
   int32 i,f;
204
   byte k1,k2;
204
   byte k1,k2;
205
205
206
   FXDevice = -1;
206
   FXDevice = 1;
207
   MusicDevice = -1;
207
   MusicDevice = 1;
208
   NumVoices = 4;
208
   NumVoices = 4;
209
   NumChannels = 2;
209
   NumChannels = 2;
210
   NumBits = 8;
210
   NumBits = 8;
Lines 666-671 Link Here
666
   SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLTextureMode",gltexfiltermode,false,false);
666
   SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLTextureMode",gltexfiltermode,false,false);
667
   SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLAnisotropy",glanisotropy,false,false);
667
   SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLAnisotropy",glanisotropy,false,false);
668
   SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLUseTextureCompr",glusetexcompr,false,false);
668
   SCRIPT_PutNumber( scripthandle, "Screen Setup", "GLUseTextureCompr",glusetexcompr,false,false);
669
   SCRIPT_PutNumber( scripthandle, "Sound Setup", "FXDevice",FXDevice,false,false);
670
   SCRIPT_PutNumber( scripthandle, "Sound Setup", "MusicDevice",MusicDevice,false,false);
669
   SCRIPT_PutNumber( scripthandle, "Sound Setup", "FXVolume",FXVolume,false,false);
671
   SCRIPT_PutNumber( scripthandle, "Sound Setup", "FXVolume",FXVolume,false,false);
670
   SCRIPT_PutNumber( scripthandle, "Sound Setup", "MusicVolume",MusicVolume,false,false);
672
   SCRIPT_PutNumber( scripthandle, "Sound Setup", "MusicVolume",MusicVolume,false,false);
671
   SCRIPT_PutNumber( scripthandle, "Sound Setup", "SoundToggle",SoundToggle,false,false);
673
   SCRIPT_PutNumber( scripthandle, "Sound Setup", "SoundToggle",SoundToggle,false,false);
(-)jfduke3d_src_20051009.orig/source/jaudiolib/debugio.h (+30 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
*/
20
#ifndef __DEBUGIO_H
21
#define __DEBUGIO_H
22
23
void DB_SetXY( int x, int y );
24
void DB_PutChar( char ch );
25
int  DB_PrintString( char *string );
26
int  DB_PrintNum( int number );
27
int  DB_PrintUnsigned( unsigned long number, int radix );
28
int  DB_printf( char *fmt, ... );
29
30
#endif
(-)jfduke3d_src_20051009.orig/source/jaudiolib/dma.h (+83 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
*/
20
/**********************************************************************
21
   file:   DMA.H
22
23
   author: James R. Dose
24
   date:   February 4, 1994
25
26
   Public header file for DMA.C
27
28
   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
29
**********************************************************************/
30
31
#ifndef __DMA_H
32
#define __DMA_H
33
34
enum DMA_ERRORS
35
   {
36
   DMA_Error = -1,
37
   DMA_Ok    = 0,
38
   DMA_ChannelOutOfRange,
39
   DMA_InvalidChannel
40
   };
41
42
enum DMA_Modes
43
   {
44
   DMA_SingleShotRead,
45
   DMA_SingleShotWrite,
46
   DMA_AutoInitRead,
47
   DMA_AutoInitWrite
48
   };
49
50
char *DMA_ErrorString
51
   (
52
   int ErrorNumber
53
   );
54
55
int DMA_VerifyChannel
56
   (
57
   int channel
58
   );
59
60
int DMA_SetupTransfer
61
   (
62
   int  channel,
63
   char *address,
64
   int  length,
65
   int  mode
66
   );
67
68
int DMA_EndTransfer
69
   (
70
   int channel
71
   );
72
73
char *DMA_GetCurrentPos
74
   (
75
   int channel
76
   );
77
78
int DMA_GetTransferCount
79
   (
80
   int channel
81
   );
82
83
#endif
(-)jfduke3d_src_20051009.orig/source/jaudiolib/dpmi.h (+43 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
*/
20
/**********************************************************************
21
   module: DPMI.H
22
23
   author: James R. Dose
24
   date:   March 31, 1994
25
26
   Inline functions for performing DPMI calls.
27
28
   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
29
**********************************************************************/
30
31
#ifndef __DPMI_H
32
#define __DPMI_H
33
34
enum DPMI_Errors
35
   {
36
   DPMI_Warning = -2,
37
   DPMI_Error   = -1,
38
   DPMI_Ok      = 0
39
   };
40
41
int  DPMI_GetDOSMemory( void **ptr, int *descriptor, unsigned length );
42
int  DPMI_FreeDOSMemory( int descriptor );
43
#endif
(-)jfduke3d_src_20051009.orig/source/jaudiolib/dsl.c (+257 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
20
Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
21
22
*/
23
#include <stdlib.h>
24
#include <string.h>
25
26
#include "dsl.h"
27
#include "util.h"
28
29
#include "SDL.h"
30
#include "SDL_mixer.h"
31
32
extern volatile int MV_MixPage;
33
34
static int DSL_ErrorCode = DSL_Ok;
35
36
static int mixer_initialized;
37
38
static void ( *_CallBackFunc )( void );
39
static volatile char *_BufferStart;
40
static int _BufferSize;
41
static int _NumDivisions;
42
static int _SampleRate;
43
static int _remainder;
44
45
static Mix_Chunk *blank;
46
static unsigned char *blank_buf;
47
48
/*
49
possible todo ideas: cache sdl/sdl mixer error messages.
50
*/
51
52
char *DSL_ErrorString( int ErrorNumber )
53
{
54
   char *ErrorString;
55
   
56
   switch (ErrorNumber) {
57
       case DSL_Warning:
58
       case DSL_Error:
59
           ErrorString = DSL_ErrorString(DSL_ErrorCode);
60
           break;
61
       
62
       case DSL_Ok:
63
           ErrorString = "SDL Driver ok.";
64
           break;
65
       
66
       case DSL_SDLInitFailure:
67
           ErrorString = "SDL Audio initialization failed.";
68
           break;
69
       
70
       case DSL_MixerActive:
71
           ErrorString = "SDL Mixer already initialized.";
72
           break;  
73
   
74
       case DSL_MixerInitFailure:
75
           ErrorString = "SDL Mixer initialization failed.";
76
           break;
77
           
78
       default:
79
           ErrorString = "Unknown SDL Driver error.";
80
           break;
81
   }
82
   
83
   return ErrorString;
84
}
85
86
static void DSL_SetErrorCode(int ErrorCode)
87
{
88
   DSL_ErrorCode = ErrorCode;
89
}
90
91
int DSL_Init( void )
92
{
93
   DSL_SetErrorCode(DSL_Ok);
94
   
95
   if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
96
       DSL_SetErrorCode(DSL_SDLInitFailure);
97
       
98
       return DSL_Error;
99
   }
100
   
101
   return DSL_Ok;
102
}
103
104
void DSL_Shutdown( void )
105
{
106
   DSL_StopPlayback();
107
}
108
109
static void mixer_callback(int chan, void *stream, int len, void *udata)
110
{
111
   Uint8 *stptr;
112
   Uint8 *fxptr;
113
   int copysize;
114
   
115
   /* len should equal _BufferSize, else this is screwed up */
116
117
   stptr = (Uint8 *)stream;
118
   
119
   if (_remainder > 0) {
120
       copysize = min(len, _remainder);
121
       
122
       fxptr = (Uint8 *)(&_BufferStart[MV_MixPage * 
123
           _BufferSize]);
124
       
125
       memcpy(stptr, fxptr+(_BufferSize-_remainder), copysize);
126
       
127
       len -= copysize;
128
       _remainder -= copysize;
129
       
130
       stptr += copysize;
131
   }
132
   
133
   while (len > 0) {
134
       /* new buffer */
135
       
136
       _CallBackFunc();
137
       
138
       fxptr = (Uint8 *)(&_BufferStart[MV_MixPage * 
139
           _BufferSize]);
140
141
       copysize = min(len, _BufferSize);
142
       
143
       memcpy(stptr, fxptr, copysize);
144
       
145
       len -= copysize;
146
       
147
       stptr += copysize;
148
   }
149
   
150
   _remainder = len;
151
}
152
153
int   DSL_BeginBufferedPlayback( char *BufferStart,
154
      int BufferSize, int NumDivisions, unsigned SampleRate,
155
      int MixMode, void ( *CallBackFunc )( void ) )
156
{
157
   Uint16 format;
158
   Uint8 *tmp;
159
   int channels;
160
   int chunksize;
161
       
162
   if (mixer_initialized) {
163
       DSL_SetErrorCode(DSL_MixerActive);
164
       
165
       return DSL_Error;
166
   }
167
   
168
   _CallBackFunc = CallBackFunc;
169
   _BufferStart = BufferStart;
170
   _BufferSize = (BufferSize / NumDivisions);
171
   _NumDivisions = NumDivisions;
172
   _SampleRate = SampleRate;
173
174
   _remainder = 0;
175
   
176
   format = (MixMode & SIXTEEN_BIT) ? AUDIO_S16SYS : AUDIO_U8;
177
   channels = (MixMode & STEREO) ? 2 : 1;
178
179
/*
180
   23ms is typically ideal (11025,22050,44100)
181
   46ms isn't bad
182
*/
183
   
184
   chunksize = 512;
185
   
186
   if (SampleRate >= 16000) chunksize *= 2;
187
   if (SampleRate >= 32000) chunksize *= 2;
188
   
189
/* 
190
// SDL mixer does this already
191
   if (MixMode & SIXTEEN_BIT) chunksize *= 2;
192
   if (MixMode & STEREO) chunksize *= 2;
193
*/
194
   
195
   if (Mix_OpenAudio(SampleRate, format, channels, chunksize) < 0) {
196
       DSL_SetErrorCode(DSL_MixerInitFailure);
197
       
198
       return DSL_Error;
199
   }
200
201
/*
202
   Mix_SetPostMix(mixer_callback, NULL);
203
*/
204
   /* have to use a channel because postmix will overwrite the music... */
205
   Mix_RegisterEffect(0, mixer_callback, NULL, NULL);
206
   
207
   /* create a dummy sample just to allocate that channel */
208
   blank_buf = (Uint8 *)malloc(4096);
209
   memset(blank_buf, 0, 4096);
210
   
211
   blank = Mix_QuickLoad_RAW(blank_buf, 4096);
212
       
213
   Mix_PlayChannel(0, blank, -1);
214
   
215
   mixer_initialized = 1;
216
   
217
   return DSL_Ok;
218
}
219
220
void DSL_StopPlayback( void )
221
{
222
   if (mixer_initialized) {
223
       Mix_HaltChannel(0);
224
   }
225
   
226
   if (blank != NULL) {
227
       Mix_FreeChunk(blank);
228
   }
229
   
230
   blank = NULL;
231
   
232
   if (blank_buf  != NULL) {
233
       free(blank_buf);
234
   }
235
   
236
   blank_buf = NULL;
237
   
238
   if (mixer_initialized) {
239
       Mix_CloseAudio();
240
   }
241
   
242
   mixer_initialized = 0;
243
}
244
245
unsigned DSL_GetPlaybackRate( void )
246
{
247
   return _SampleRate;
248
}
249
250
unsigned long DisableInterrupts( void )
251
{
252
   return 0;
253
}
254
255
void RestoreInterrupts( unsigned long flags )
256
{
257
}
(-)jfduke3d_src_20051009.orig/source/jaudiolib/dsl.h (+50 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
20
Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
21
22
*/
23
#ifndef AUDIOLIB__DSL_H
24
#define AUDIOLIB__DSL_H
25
26
#define MONO_8BIT    0
27
#define STEREO      1
28
#define SIXTEEN_BIT 2
29
#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
30
31
enum DSL_ERRORS
32
   {
33
   DSL_Warning = -2,
34
   DSL_Error = -1,
35
   DSL_Ok = 0,
36
   DSL_SDLInitFailure,
37
   DSL_MixerActive,
38
   DSL_MixerInitFailure
39
   };
40
41
char *DSL_ErrorString( int ErrorNumber );
42
int   DSL_Init( void );
43
void  DSL_StopPlayback( void );
44
unsigned DSL_GetPlaybackRate( void );
45
int   DSL_BeginBufferedPlayback( char *BufferStart,
46
      int BufferSize, int NumDivisions, unsigned SampleRate,
47
      int MixMode, void ( *CallBackFunc )( void ) );
48
void  DSL_Shutdown( void );
49
50
#endif
(-)jfduke3d_src_20051009.orig/source/jaudiolib/interrup.h (+50 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
*/
20
/**********************************************************************
21
   module: INTERRUP.H
22
23
   author: James R. Dose
24
   date:   March 31, 1994
25
26
   Inline functions for disabling and restoring the interrupt flag.
27
28
   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
29
**********************************************************************/
30
31
#ifndef __INTERRUPT_H
32
#define __INTERRUPT_H
33
34
unsigned long DisableInterrupts( void );
35
void          RestoreInterrupts( unsigned long flags );
36
37
#ifdef PLAT_DOS
38
#pragma aux DisableInterrupts = \
39
   "pushfd",                    \
40
   "pop    eax",                \
41
   "cli"                        \
42
   modify [ eax ];
43
44
#pragma aux RestoreInterrupts = \
45
   "push   eax",                \
46
   "popfd"                      \
47
   parm [ eax ];
48
#endif
49
50
#endif
(-)jfduke3d_src_20051009.orig/source/jaudiolib/_multivc.h (-1 / +4 lines)
Lines 67-74 Link Here
67
#define SILENCE_8BIT      0x80808080
67
#define SILENCE_8BIT      0x80808080
68
//#define SILENCE_16BIT_PAS 0
68
//#define SILENCE_16BIT_PAS 0
69
69
70
//#define MixBufferSize     256
70
#ifdef WINDOWS
71
#define MixBufferSize     (MV_GetBufferSize(MV_RequestedMixRate))
71
#define MixBufferSize     (MV_GetBufferSize(MV_RequestedMixRate))
72
#else
73
#define MixBufferSize     256
74
#endif
72
75
73
#define NumberOfBuffers   16
76
#define NumberOfBuffers   16
74
#define TotalBufferSize   ( MixBufferSize * NumberOfBuffers )
77
#define TotalBufferSize   ( MixBufferSize * NumberOfBuffers )
(-)jfduke3d_src_20051009.orig/source/jaudiolib/nodpmi.c (+50 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
*/
20
/**********************************************************************
21
   module: NODPMI.C
22
23
   Functions for faking DPMI calls.
24
25
**********************************************************************/
26
27
#include <stdlib.h>
28
#include <string.h>
29
#include "dpmi.h"
30
31
#define TRUE  ( 1 == 1 )
32
#define FALSE ( !TRUE )
33
34
int DPMI_GetDOSMemory( void **ptr, int *descriptor, unsigned length )
35
{
36
   /* Lovely... */
37
   
38
   *ptr = (void *)malloc(length);
39
   
40
   *descriptor = (int) *ptr;
41
   
42
   return (descriptor == 0) ? DPMI_Error : DPMI_Ok;
43
}
44
45
int DPMI_FreeDOSMemory( int descriptor )
46
{
47
   free((void *)descriptor);
48
   
49
   return (descriptor == 0) ? DPMI_Error : DPMI_Ok;
50
}
(-)jfduke3d_src_20051009.orig/source/jaudiolib/platform.h (+61 lines)
Line 0 Link Here
1
#ifndef _INCLUDE_PLATFORM_H_
2
#define _INCLUDE_PLATFORM_H_
3
4
#if (!defined __EXPORT__)
5
#define __EXPORT__
6
#endif
7
8
#if (defined __WATCOMC__)
9
#define snprintf _snprintf
10
#endif
11
12
static __inline unsigned short _swap16(unsigned short D)
13
{
14
#if PLATFORM_MACOSX
15
    register unsigned short returnValue;
16
    __asm__ volatile("lhbrx %0,0,%1"
17
        : "=r" (returnValue)
18
        : "r" (&D)
19
    );
20
    return returnValue;
21
#else
22
    return((D<<8)|(D>>8));
23
#endif
24
}
25
26
static __inline unsigned int _swap32(unsigned int D)
27
{
28
#if PLATFORM_MACOSX
29
    register unsigned int returnValue;
30
    __asm__ volatile("lwbrx %0,0,%1"
31
        : "=r" (returnValue)
32
        : "r" (&D)
33
    );
34
    return returnValue;
35
#else
36
    return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24));
37
#endif
38
}
39
40
#if PLATFORM_MACOSX
41
#define PLATFORM_BIGENDIAN 1
42
#define BUILDSWAP_INTEL16(x) _swap16(x)
43
#define BUILDSWAP_INTEL32(x) _swap32(x)
44
#else
45
#if __BYTE_ORDER == __LITTLE_ENDIAN
46
#define PLATFORM_LITTLEENDIAN 1
47
#define BUILDSWAP_INTEL16(x) (x)
48
#define BUILDSWAP_INTEL32(x) (x)
49
#else
50
#define PLATFORM_BIGENDIAN 1
51
#define BUILDSWAP_INTEL16(x) _swap16(x)
52
#define BUILDSWAP_INTEL32(x) _swap32(x)
53
#endif
54
#endif
55
56
extern int has_altivec;  /* PowerPC-specific. */
57
58
#endif  /* !defined _INCLUDE_PLATFORM_H_ */
59
60
/* end of platform.h ... */
61
(-)jfduke3d_src_20051009.orig/source/jaudiolib/sdlmusic.c (+478 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
20
Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
21
22
*/
23
/*
24
 * A reimplementation of Jim Dose's FX_MAN routines, using  SDL_mixer 1.2.
25
 *   Whee. FX_MAN is also known as the "Apogee Sound System", or "ASS" for
26
 *   short. How strangely appropriate that seems.
27
 */
28
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <stdarg.h>
32
#include <string.h>
33
#include <assert.h>
34
35
#include "duke3d.h"
36
#include "cache1d.h"
37
38
#ifndef MAX_PATH
39
#define MAX_PATH 256
40
#endif
41
42
#if (defined __WATCOMC__)
43
// This is probably out of date.  --ryan.
44
#include "dukesnd_watcom.h"
45
#endif
46
47
#if (!defined __WATCOMC__)
48
#define cdecl
49
#endif
50
51
#include "SDL.h"
52
#include "SDL_mixer.h"
53
#include "music.h"
54
55
#define __FX_TRUE  (1 == 1)
56
#define __FX_FALSE (!__FX_TRUE)
57
58
#define DUKESND_DEBUG       "DUKESND_DEBUG"
59
60
#ifndef min
61
#define min(a, b)  (((a) < (b)) ? (a) : (b))
62
#endif
63
64
#ifndef max
65
#define max(a, b)  (((a) > (b)) ? (a) : (b))
66
#endif
67
68
void GetUnixPathFromEnvironment( char *fullname, int32 length, const char *filename );
69
70
int MUSIC_ErrorCode = MUSIC_Ok;
71
72
static char warningMessage[80];
73
static char errorMessage[80];
74
static int fx_initialized = 0;
75
static int numChannels = MIX_CHANNELS;
76
static void (*callback)(unsigned long);
77
static int reverseStereo = 0;
78
static int reverbDelay = 256;
79
static int reverbLevel = 0;
80
static int fastReverb = 0;
81
static FILE *debug_file = NULL;
82
static int initialized_debugging = 0;
83
static int mixerIsStereo = 1;
84
85
// This gets called all over the place for information and debugging messages.
86
//  If the user set the DUKESND_DEBUG environment variable, the messages
87
//  go to the file that is specified in that variable. Otherwise, they
88
//  are ignored for the expense of the function call. If DUKESND_DEBUG is
89
//  set to "-" (without the quotes), then the output goes to stdout.
90
static void musdebug(const char *fmt, ...)
91
{
92
    va_list ap;
93
94
    if (debug_file)
95
    {
96
        fprintf(debug_file, "DUKEMUS: ");
97
        va_start(ap, fmt);
98
        vfprintf(debug_file, fmt, ap);
99
        va_end(ap);
100
        fprintf(debug_file, "\n");
101
        fflush(debug_file);
102
    } // if
103
} // musdebug
104
105
static void init_debugging(void)
106
{
107
    const char *envr;
108
109
    if (initialized_debugging)
110
        return;
111
112
    envr = getenv(DUKESND_DEBUG);
113
    if (envr != NULL)
114
    {
115
        if (strcmp(envr, "-") == 0)
116
            debug_file = stdout;
117
        else
118
            debug_file = fopen(envr, "w");
119
120
        if (debug_file == NULL)
121
            fprintf(stderr, "DUKESND: -WARNING- Could not open debug file!\n");
122
        else
123
            setbuf(debug_file, NULL);
124
    } // if
125
126
    initialized_debugging = 1;
127
} // init_debugging
128
129
static void setWarningMessage(const char *msg)
130
{
131
    strncpy(warningMessage, msg, sizeof (warningMessage));
132
    // strncpy() doesn't add the null char if there isn't room...
133
    warningMessage[sizeof (warningMessage) - 1] = '\0';
134
    musdebug("Warning message set to [%s].", warningMessage);
135
} // setErrorMessage
136
137
138
static void setErrorMessage(const char *msg)
139
{
140
    strncpy(errorMessage, msg, sizeof (errorMessage));
141
    // strncpy() doesn't add the null char if there isn't room...
142
    errorMessage[sizeof (errorMessage) - 1] = '\0';
143
    musdebug("Error message set to [%s].", errorMessage);
144
} // setErrorMessage
145
146
// The music functions...
147
148
char *MUSIC_ErrorString(int ErrorNumber)
149
{
150
    switch (ErrorNumber)
151
    {
152
        case MUSIC_Warning:
153
            return(warningMessage);
154
155
        case MUSIC_Error:
156
            return(errorMessage);
157
158
        case MUSIC_Ok:
159
            return("OK; no error.");
160
161
        case MUSIC_ASSVersion:
162
            return("Incorrect sound library version.");
163
164
        case MUSIC_SoundCardError:
165
            return("General sound card error.");
166
167
        case MUSIC_InvalidCard:
168
            return("Invalid sound card.");
169
170
        case MUSIC_MidiError:
171
            return("MIDI error.");
172
173
        case MUSIC_MPU401Error:
174
            return("MPU401 error.");
175
176
        case MUSIC_TaskManError:
177
            return("Task Manager error.");
178
179
        //case MUSIC_FMNotDetected:
180
        //    return("FM not detected error.");
181
182
        case MUSIC_DPMI_Error:
183
            return("DPMI error.");
184
185
        default:
186
            return("Unknown error.");
187
    } // switch
188
189
    assert(0);    // shouldn't hit this point.
190
    return(NULL);
191
} // MUSIC_ErrorString
192
193
194
static int music_initialized = 0;
195
static int music_context = 0;
196
static int music_loopflag = MUSIC_PlayOnce;
197
static char *music_songdata = NULL;
198
static Mix_Music *music_musicchunk = NULL;
199
200
int MUSIC_Init(int SoundCard, int Address)
201
{
202
    init_debugging();
203
204
    musdebug("INIT! card=>%d, address=>%d...", SoundCard, Address);
205
206
    if (music_initialized)
207
    {
208
        setErrorMessage("Music system is already initialized.");
209
        return(MUSIC_Error);
210
    } // if
211
    
212
    SoundCard = 1;
213
214
    music_initialized = 1;
215
    return(MUSIC_Ok);
216
} // MUSIC_Init
217
218
219
int MUSIC_Shutdown(void)
220
{
221
    musdebug("shutting down sound subsystem.");
222
223
    MUSIC_StopSong();
224
    music_context = 0;
225
    music_initialized = 0;
226
    music_loopflag = MUSIC_PlayOnce;
227
    return(MUSIC_Ok);
228
} // MUSIC_Shutdown
229
230
231
void MUSIC_SetMaxFMMidiChannel(int channel)
232
{
233
    musdebug("STUB ... MUSIC_SetMaxFMMidiChannel(%d).\n", channel);
234
} // MUSIC_SetMaxFMMidiChannel
235
236
237
void MUSIC_SetVolume(int volume)
238
{
239
    volume = max( 0, volume );
240
    volume = min( volume, 255 );
241
242
    Mix_VolumeMusic(volume >> 1);  // convert 0-255 to 0-128.
243
} // MUSIC_SetVolume
244
245
246
void MUSIC_SetMidiChannelVolume(int channel, int volume)
247
{
248
    musdebug("STUB ... MUSIC_SetMidiChannelVolume(%d, %d).\n", channel, volume);
249
} // MUSIC_SetMidiChannelVolume
250
251
252
void MUSIC_ResetMidiChannelVolumes(void)
253
{
254
    musdebug("STUB ... MUSIC_ResetMidiChannelVolumes().\n");
255
} // MUSIC_ResetMidiChannelVolumes
256
257
258
int MUSIC_GetVolume(void)
259
{
260
    return(Mix_VolumeMusic(-1) << 1);  // convert 0-128 to 0-255.
261
} // MUSIC_GetVolume
262
263
264
void MUSIC_SetLoopFlag(int loopflag)
265
{
266
    music_loopflag = loopflag;
267
} // MUSIC_SetLoopFlag
268
269
270
int MUSIC_SongPlaying(void)
271
{
272
    return((Mix_PlayingMusic()) ? __FX_TRUE : __FX_FALSE);
273
} // MUSIC_SongPlaying
274
275
276
void MUSIC_Continue(void)
277
{
278
    if (Mix_PausedMusic())
279
        Mix_ResumeMusic();
280
    else if (music_songdata)
281
        MUSIC_PlaySong(music_songdata, MUSIC_PlayOnce);
282
} // MUSIC_Continue
283
284
285
void MUSIC_Pause(void)
286
{
287
    Mix_PauseMusic();
288
} // MUSIC_Pause
289
290
291
int MUSIC_StopSong(void)
292
{
293
    //if (!fx_initialized)
294
    if (!Mix_QuerySpec(NULL, NULL, NULL))
295
    {
296
        setErrorMessage("Need FX system initialized, too. Sorry.");
297
        return(MUSIC_Error);
298
    } // if
299
300
    if ( (Mix_PlayingMusic()) || (Mix_PausedMusic()) )
301
        Mix_HaltMusic();
302
303
    if (music_musicchunk)
304
        Mix_FreeMusic(music_musicchunk);
305
306
    music_songdata = NULL;
307
    music_musicchunk = NULL;
308
    return(MUSIC_Ok);
309
} // MUSIC_StopSong
310
311
312
int MUSIC_PlaySong(unsigned char *song, int loopflag)
313
{
314
    //SDL_RWops *rw;
315
316
    MUSIC_StopSong();
317
318
    music_songdata = song;
319
320
    // !!! FIXME: This could be a problem...SDL/SDL_mixer wants a RWops, which
321
    // !!! FIXME:  is an i/o abstraction. Since we already have the MIDI data
322
    // !!! FIXME:  in memory, we fake it with a memory-based RWops. None of
323
    // !!! FIXME:  this is a problem, except the RWops wants to know how big
324
    // !!! FIXME:  its memory block is (so it can do things like seek on an
325
    // !!! FIXME:  offset from the end of the block), and since we don't have
326
    // !!! FIXME:  this information, we have to give it SOMETHING.
327
328
    /* !!! ARGH! There's no LoadMUS_RW  ?!
329
    rw = SDL_RWFromMem((void *) song, (10 * 1024) * 1024);  // yikes.
330
    music_musicchunk = Mix_LoadMUS_RW(rw);
331
    Mix_PlayMusic(music_musicchunk, (loopflag == MUSIC_PlayOnce) ? 0 : -1);
332
    */
333
334
    return(MUSIC_Ok);
335
} // MUSIC_PlaySong
336
337
338
extern char ApogeePath[256] = "./";
339
340
// Duke3D-specific.  --ryan.
341
void PlayMusic(char *_filename)
342
{
343
    //char filename[MAX_PATH];
344
    //strcpy(filename, _filename);
345
    //FixFilePath(filename);
346
347
    char filename[MAX_PATH];
348
    long handle;
349
    long size;
350
    void *song;
351
    long rc;
352
353
    MUSIC_StopSong();
354
355
    // Read from a groupfile, write it to disk so SDL_mixer can read it.
356
    //   Lame.  --ryan.
357
    handle = kopen4load(_filename, 0);
358
    if (handle == -1)
359
        return;
360
361
    size = kfilelength(handle);
362
    if (size == -1)
363
    {
364
        kclose(handle);
365
        return;
366
    } // if
367
368
    song = malloc(size);
369
    if (song == NULL)
370
    {
371
        kclose(handle);
372
        return;
373
    } // if
374
375
    rc = kread(handle, song, size);
376
    kclose(handle);
377
    if (rc != size)
378
    {
379
        free(song);
380
        return;
381
    } // if
382
383
    // save the file somewhere, so SDL_mixer can load it
384
    GetUnixPathFromEnvironment(filename, MAX_PATH, "tmpsong.mid");
385
    handle = SafeOpenWrite(filename, filetype_binary);
386
    
387
    SafeWrite(handle, song, size);
388
    close(handle);
389
    free(song);
390
    
391
    //music_songdata = song;
392
393
    music_musicchunk = Mix_LoadMUS(filename);
394
    if (music_musicchunk != NULL)
395
    {
396
        // !!! FIXME: I set the music to loop. Hope that's okay. --ryan.
397
        Mix_PlayMusic(music_musicchunk, -1);
398
    } // if
399
}
400
401
402
void MUSIC_SetContext(int context)
403
{
404
    musdebug("STUB ... MUSIC_SetContext().\n");
405
    music_context = context;
406
} // MUSIC_SetContext
407
408
409
int MUSIC_GetContext(void)
410
{
411
    return(music_context);
412
} // MUSIC_GetContext
413
414
415
void MUSIC_SetSongTick(unsigned long PositionInTicks)
416
{
417
    musdebug("STUB ... MUSIC_SetSongTick().\n");
418
} // MUSIC_SetSongTick
419
420
421
void MUSIC_SetSongTime(unsigned long milliseconds)
422
{
423
    musdebug("STUB ... MUSIC_SetSongTime().\n");
424
}// MUSIC_SetSongTime
425
426
427
void MUSIC_SetSongPosition(int measure, int beat, int tick)
428
{
429
    musdebug("STUB ... MUSIC_SetSongPosition().\n");
430
} // MUSIC_SetSongPosition
431
432
433
void MUSIC_GetSongPosition(songposition *pos)
434
{
435
    musdebug("STUB ... MUSIC_GetSongPosition().\n");
436
} // MUSIC_GetSongPosition
437
438
439
void MUSIC_GetSongLength(songposition *pos)
440
{
441
    musdebug("STUB ... MUSIC_GetSongLength().\n");
442
} // MUSIC_GetSongLength
443
444
445
int MUSIC_FadeVolume(int tovolume, int milliseconds)
446
{
447
    Mix_FadeOutMusic(milliseconds);
448
    return(MUSIC_Ok);
449
} // MUSIC_FadeVolume
450
451
452
int MUSIC_FadeActive(void)
453
{
454
    return((Mix_FadingMusic() == MIX_FADING_OUT) ? __FX_TRUE : __FX_FALSE);
455
} // MUSIC_FadeActive
456
457
458
void MUSIC_StopFade(void)
459
{
460
    musdebug("STUB ... MUSIC_StopFade().\n");
461
} // MUSIC_StopFade
462
463
464
void MUSIC_RerouteMidiChannel(int channel, int cdecl (*function)( int event, int c1, int c2 ))
465
{
466
    musdebug("STUB ... MUSIC_RerouteMidiChannel().\n");
467
} // MUSIC_RerouteMidiChannel
468
469
470
void MUSIC_RegisterTimbreBank(unsigned char *timbres)
471
{
472
    musdebug("STUB ... MUSIC_RegisterTimbreBank().\n");
473
} // MUSIC_RegisterTimbreBank
474
475
476
void MUSIC_Update(void)
477
{
478
}
(-)jfduke3d_src_20051009.orig/source/jaudiolib/unixglob.c (+149 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
20
Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
21
22
*/
23
24
static char ApogeePath[256] = "./";
25
26
#define PATH_SEP_CHAR '/'
27
#define PATH_SEP_STR  "/"
28
#define ROOTDIR       "/"
29
#define CURDIR        "./"
30
31
#include "duke3d.h"
32
#include <dirent.h>
33
#include <errno.h>
34
35
#ifndef MAX_PATH
36
#define MAX_PATH 256
37
#endif
38
39
void FixFilePath(char *filename)
40
{
41
    char *ptr;
42
    char *lastsep = filename;
43
44
    if ((!filename) || (*filename == '\0'))
45
        return;
46
47
    if (access(filename, F_OK) == 0)  /* File exists; we're good to go. */
48
        return;
49
50
    for (ptr = filename; 1; ptr++)
51
    {
52
        if (*ptr == '\\')
53
            *ptr = PATH_SEP_CHAR;
54
55
        if ((*ptr == PATH_SEP_CHAR) || (*ptr == '\0'))
56
        {
57
            char pch = *ptr;
58
            struct dirent *dent = NULL;
59
            DIR *dir;
60
61
            if ((pch == PATH_SEP_CHAR) && (*(ptr + 1) == '\0'))
62
                return; /* eos is pathsep; we're done. */
63
64
            if (lastsep == ptr)
65
                continue;  /* absolute path; skip to next one. */
66
67
            *ptr = '\0';
68
            if (lastsep == filename) {
69
                dir = opendir((*lastsep == PATH_SEP_CHAR) ? ROOTDIR : CURDIR);
70
                
71
                if (*lastsep == PATH_SEP_CHAR) {
72
                    lastsep++;
73
                }
74
            } 
75
            else
76
            {
77
                *lastsep = '\0';
78
                dir = opendir(filename);
79
                *lastsep = PATH_SEP_CHAR;
80
                lastsep++;
81
            }
82
83
            if (dir == NULL)
84
            {
85
                *ptr = PATH_SEP_CHAR;
86
                return;  /* maybe dir doesn't exist? give up. */
87
            }
88
89
            while ((dent = readdir(dir)) != NULL)
90
            {
91
                if (strcasecmp(dent->d_name, lastsep) == 0)
92
                {
93
                    /* found match; replace it. */
94
                    strcpy(lastsep, dent->d_name);
95
                    break;
96
                }
97
            }
98
99
            closedir(dir);
100
            *ptr = pch;
101
            lastsep = ptr;
102
103
            if (dent == NULL)
104
                return;  /* no match. oh well. */
105
106
            if (pch == '\0')  /* eos? */
107
                return;
108
        }
109
    }
110
}
111
112
int32 SafeOpenWrite (const char *_filename, int32 filetype)
113
{
114
   int handle;
115
    char filename[MAX_PATH];
116
    strncpy(filename, _filename, sizeof (filename));
117
    filename[sizeof (filename) - 1] = '\0';
118
    FixFilePath(filename);
119
120
   handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_TRUNC
121
   , S_IREAD | S_IWRITE);
122
123
   if (handle == -1)
124
       Error ("Error opening %s: %s",filename,strerror(errno));
125
126
   return handle;
127
}
128
129
130
void SafeWrite (int32 handle, void *buffer, int32 count)
131
{
132
   unsigned    iocount;
133
134
   while (count)
135
   {
136
       iocount = count > 0x8000 ? 0x8000 : count;
137
       if (write (handle,buffer,iocount) != (int)iocount)
138
           Error ("File write failure writing %ld bytes",count);
139
       buffer = (void *)( (byte *)buffer + iocount );
140
       count -= iocount;
141
   }
142
}
143
144
145
146
void GetUnixPathFromEnvironment( char *fullname, int32 length, const char *filename )
147
{
148
   snprintf(fullname, length-1, "%s%s", ApogeePath, filename);
149
}
(-)jfduke3d_src_20051009.orig/source/jaudiolib/unixpitch.c (+212 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
*/
20
/**********************************************************************
21
   module: PITCH.C
22
23
   author: James R. Dose
24
   date:   June 14, 1993
25
26
   Routines for pitch scaling.
27
28
   (c) Copyright 1993 James R. Dose.  All Rights Reserved.
29
**********************************************************************/
30
31
#include <stdlib.h>
32
//#include <math.h>
33
#include "dpmi.h"
34
#include "standard.h"
35
#include "pitch.h"
36
37
#define MAXDETUNE 25
38
39
static unsigned long PitchTable[ 12 ][ MAXDETUNE ] =
40
   {
41
      { 0x10000, 0x10097, 0x1012f, 0x101c7, 0x10260, 0x102f9, 0x10392, 0x1042c,
42
      0x104c6, 0x10561, 0x105fb, 0x10696, 0x10732, 0x107ce, 0x1086a, 0x10907,
43
      0x109a4, 0x10a41, 0x10adf, 0x10b7d, 0x10c1b, 0x10cba, 0x10d59, 0x10df8,
44
      0x10e98 },
45
      { 0x10f38, 0x10fd9, 0x1107a, 0x1111b, 0x111bd, 0x1125f, 0x11302, 0x113a5,
46
      0x11448, 0x114eb, 0x1158f, 0x11634, 0x116d8, 0x1177e, 0x11823, 0x118c9,
47
      0x1196f, 0x11a16, 0x11abd, 0x11b64, 0x11c0c, 0x11cb4, 0x11d5d, 0x11e06,
48
      0x11eaf },
49
      { 0x11f59, 0x12003, 0x120ae, 0x12159, 0x12204, 0x122b0, 0x1235c, 0x12409,
50
      0x124b6, 0x12563, 0x12611, 0x126bf, 0x1276d, 0x1281c, 0x128cc, 0x1297b,
51
      0x12a2b, 0x12adc, 0x12b8d, 0x12c3e, 0x12cf0, 0x12da2, 0x12e55, 0x12f08,
52
      0x12fbc },
53
      { 0x1306f, 0x13124, 0x131d8, 0x1328d, 0x13343, 0x133f9, 0x134af, 0x13566,
54
      0x1361d, 0x136d5, 0x1378d, 0x13846, 0x138fe, 0x139b8, 0x13a72, 0x13b2c,
55
      0x13be6, 0x13ca1, 0x13d5d, 0x13e19, 0x13ed5, 0x13f92, 0x1404f, 0x1410d,
56
      0x141cb },
57
      { 0x1428a, 0x14349, 0x14408, 0x144c8, 0x14588, 0x14649, 0x1470a, 0x147cc,
58
      0x1488e, 0x14951, 0x14a14, 0x14ad7, 0x14b9b, 0x14c5f, 0x14d24, 0x14dea,
59
      0x14eaf, 0x14f75, 0x1503c, 0x15103, 0x151cb, 0x15293, 0x1535b, 0x15424,
60
      0x154ee },
61
      { 0x155b8, 0x15682, 0x1574d, 0x15818, 0x158e4, 0x159b0, 0x15a7d, 0x15b4a,
62
      0x15c18, 0x15ce6, 0x15db4, 0x15e83, 0x15f53, 0x16023, 0x160f4, 0x161c5,
63
      0x16296, 0x16368, 0x1643a, 0x1650d, 0x165e1, 0x166b5, 0x16789, 0x1685e,
64
      0x16934 },
65
      { 0x16a09, 0x16ae0, 0x16bb7, 0x16c8e, 0x16d66, 0x16e3e, 0x16f17, 0x16ff1,
66
      0x170ca, 0x171a5, 0x17280, 0x1735b, 0x17437, 0x17513, 0x175f0, 0x176ce,
67
      0x177ac, 0x1788a, 0x17969, 0x17a49, 0x17b29, 0x17c09, 0x17cea, 0x17dcc,
68
      0x17eae },
69
      { 0x17f91, 0x18074, 0x18157, 0x1823c, 0x18320, 0x18406, 0x184eb, 0x185d2,
70
      0x186b8, 0x187a0, 0x18888, 0x18970, 0x18a59, 0x18b43, 0x18c2d, 0x18d17,
71
      0x18e02, 0x18eee, 0x18fda, 0x190c7, 0x191b5, 0x192a2, 0x19391, 0x19480,
72
      0x1956f },
73
      { 0x1965f, 0x19750, 0x19841, 0x19933, 0x19a25, 0x19b18, 0x19c0c, 0x19d00,
74
      0x19df4, 0x19ee9, 0x19fdf, 0x1a0d5, 0x1a1cc, 0x1a2c4, 0x1a3bc, 0x1a4b4,
75
      0x1a5ad, 0x1a6a7, 0x1a7a1, 0x1a89c, 0x1a998, 0x1aa94, 0x1ab90, 0x1ac8d,
76
      0x1ad8b },
77
      { 0x1ae89, 0x1af88, 0x1b088, 0x1b188, 0x1b289, 0x1b38a, 0x1b48c, 0x1b58f,
78
      0x1b692, 0x1b795, 0x1b89a, 0x1b99f, 0x1baa4, 0x1bbaa, 0x1bcb1, 0x1bdb8,
79
      0x1bec0, 0x1bfc9, 0x1c0d2, 0x1c1dc, 0x1c2e6, 0x1c3f1, 0x1c4fd, 0x1c609,
80
      0x1c716 },
81
      { 0x1c823, 0x1c931, 0x1ca40, 0x1cb50, 0x1cc60, 0x1cd70, 0x1ce81, 0x1cf93,
82
      0x1d0a6, 0x1d1b9, 0x1d2cd, 0x1d3e1, 0x1d4f6, 0x1d60c, 0x1d722, 0x1d839,
83
      0x1d951, 0x1da69, 0x1db82, 0x1dc9c, 0x1ddb6, 0x1ded1, 0x1dfec, 0x1e109,
84
      0x1e225 },
85
      { 0x1e343, 0x1e461, 0x1e580, 0x1e6a0, 0x1e7c0, 0x1e8e0, 0x1ea02, 0x1eb24,
86
      0x1ec47, 0x1ed6b, 0x1ee8f, 0x1efb4, 0x1f0d9, 0x1f1ff, 0x1f326, 0x1f44e,
87
      0x1f576, 0x1f69f, 0x1f7c9, 0x1f8f3, 0x1fa1e, 0x1fb4a, 0x1fc76, 0x1fda3,
88
      0x1fed1 }
89
   };
90
91
92
//static int PITCH_Installed = FALSE;
93
94
95
/*---------------------------------------------------------------------
96
   Function: PITCH_Init
97
98
   Initializes pitch table.
99
---------------------------------------------------------------------*/
100
/*
101
void PITCH_Init
102
   (
103
   void
104
   )
105
106
   {
107
   int note;
108
   int detune;
109
110
   if ( !PITCH_Installed )
111
      {
112
      for( note = 0; note < 12; note++ )
113
         {
114
         for( detune = 0; detune < MAXDETUNE; detune++ )
115
            {
116
            PitchTable[ note ][ detune ] = 0x10000 *
117
               pow( 2, ( note * MAXDETUNE + detune ) / ( 12.0 * MAXDETUNE ) );
118
            }
119
         }
120
121
      PITCH_Installed = TRUE;
122
      }
123
   }
124
*/
125
126
/**********************************************************************
127
128
   Memory locked functions:
129
130
**********************************************************************/
131
132
133
#define PITCH_LockStart PITCH_GetScale
134
135
136
/*---------------------------------------------------------------------
137
   Function: PITCH_GetScale
138
139
   Returns a fixed-point value to scale number the specified amount.
140
---------------------------------------------------------------------*/
141
142
unsigned long PITCH_GetScale
143
   (
144
   int pitchoffset
145
   )
146
147
   {
148
   unsigned long scale;
149
   int octaveshift;
150
   int noteshift;
151
   int note;
152
   int detune;
153
154
//   if ( !PITCH_Installed )
155
//      {
156
//      PITCH_Init();
157
//      }
158
159
   if ( pitchoffset == 0 )
160
      {
161
      return( PitchTable[ 0 ][ 0 ] );
162
      }
163
164
   noteshift = pitchoffset % 1200;
165
   if ( noteshift < 0 )
166
      {
167
      noteshift += 1200;
168
      }
169
170
   note   = noteshift / 100;
171
   detune = ( noteshift % 100 ) / ( 100 / MAXDETUNE );
172
   octaveshift = ( pitchoffset - noteshift ) / 1200;
173
174
   if ( detune < 0 )
175
      {
176
      detune += ( 100 / MAXDETUNE );
177
      note--;
178
      if ( note < 0 )
179
         {
180
         note += 12;
181
         octaveshift--;
182
         }
183
      }
184
185
   scale = PitchTable[ note ][ detune ];
186
187
   if ( octaveshift < 0 )
188
      {
189
      scale >>= -octaveshift;
190
      }
191
   else
192
      {
193
      scale <<= octaveshift;
194
      }
195
196
   return( scale );
197
   }
198
199
200
/*---------------------------------------------------------------------
201
   Function: PITCH_LockEnd
202
203
   Used for determining the length of the functions to lock in memory.
204
---------------------------------------------------------------------*/
205
206
static void PITCH_LockEnd
207
   (
208
   void
209
   )
210
211
   {
212
   }
(-)jfduke3d_src_20051009.orig/source/jaudiolib/unixvoc.c (+2877 lines)
Line 0 Link Here
1
/*
2
Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13
See the GNU General Public License for more details.
14
15
ou should have received a copy of the GNU General Public License
16
long with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19
*/
20
/**********************************************************************
21
   module: MULTIVOC.C
22
23
   author: James R. Dose
24
   date:   December 20, 1993
25
26
   Routines to provide multichannel digitized sound playback for
27
   Sound Blaster compatible sound cards.
28
29
   (c) Copyright 1993 James R. Dose.  All Rights Reserved.
30
**********************************************************************/
31
32
#include <stdio.h>
33
#include <stdlib.h>
34
#include <string.h>
35
#include <time.h>
36
37
#include "util.h"
38
#include "dpmi.h"
39
#include "usrhooks.h"
40
#include "interrup.h"
41
#include "dma.h"
42
#include "linklist.h"
43
#include "dsl.h"
44
45
#include "pitch.h"
46
#include "multivoc.h"
47
#include "_multivc.h"
48
#include "debugio.h"
49
50
// platform.h is from the build engine, but I need the byteswapping macros... --ryan.
51
#include "platform.h"
52
53
#define RoundFixed( fixedval, bits )            \
54
        (                                       \
55
          (                                     \
56
            (fixedval) + ( 1 << ( (bits) - 1 ) )\
57
          ) >> (bits)                           \
58
        )
59
60
#define IS_QUIET( ptr )  ( ( void * )( ptr ) == ( void * )&MV_VolumeTable[ 0 ] )
61
62
static int       MV_ReverbLevel;
63
static int       MV_ReverbDelay;
64
static VOLUME16 *MV_ReverbTable = NULL;
65
66
//static signed short MV_VolumeTable[ MV_MaxVolume + 1 ][ 256 ];
67
static signed short MV_VolumeTable[ 63 + 1 ][ 256 ];
68
69
//static Pan MV_PanTable[ MV_NumPanPositions ][ MV_MaxVolume + 1 ];
70
static Pan MV_PanTable[ MV_NumPanPositions ][ 63 + 1 ];
71
72
static int MV_Installed   = FALSE;
73
static int MV_SoundCard   = 1;
74
static int MV_TotalVolume = MV_MaxTotalVolume;
75
static int MV_MaxVoices   = 1;
76
static int MV_Recording;
77
78
static int MV_BufferSize = MixBufferSize;
79
static int MV_BufferLength;
80
81
static int MV_NumberOfBuffers = NumberOfBuffers;
82
83
static int MV_MixMode    = MONO_8BIT;
84
static int MV_Channels   = 1;
85
static int MV_Bits       = 8;
86
87
static int MV_Silence    = SILENCE_8BIT;
88
static int MV_SwapLeftRight = FALSE;
89
90
static int MV_RequestedMixRate;
91
static int MV_MixRate;
92
93
static int MV_DMAChannel = -1;
94
static int MV_BuffShift;
95
96
static int MV_TotalMemory;
97
98
static int   MV_BufferDescriptor;
99
static int   MV_BufferEmpty[ NumberOfBuffers ];
100
char *MV_MixBuffer[ NumberOfBuffers + 1 ];
101
102
static VoiceNode *MV_Voices = NULL;
103
104
static volatile VoiceNode VoiceList;
105
static volatile VoiceNode VoicePool;
106
107
/*static*/ int MV_MixPage      = 0;
108
static int MV_VoiceHandle  = MV_MinVoiceHandle;
109
110
static void ( *MV_CallBackFunc )( unsigned long ) = NULL;
111
static void ( *MV_RecordFunc )( char *ptr, int length ) = NULL;
112
static void ( *MV_MixFunction )( VoiceNode *voice, int buffer );
113
114
static int MV_MaxVolume = 63;
115
116
char  *MV_HarshClipTable;
117
char  *MV_MixDestination;
118
short *MV_LeftVolume;
119
short *MV_RightVolume;
120
int    MV_SampleSize = 1;
121
int    MV_RightChannelOffset;
122
123
unsigned long MV_MixPosition;
124
125
int MV_ErrorCode = MV_Ok;
126
127
#define MV_SetErrorCode( status ) \
128
   MV_ErrorCode   = ( status );
129
130
131
/*---------------------------------------------------------------------
132
   Function: MV_ErrorString
133
134
   Returns a pointer to the error message associated with an error
135
   number.  A -1 returns a pointer the current error.
136
---------------------------------------------------------------------*/
137
138
char *MV_ErrorString
139
   (
140
   int ErrorNumber
141
   )
142
143
   {
144
   char *ErrorString;
145
146
   switch( ErrorNumber )
147
      {
148
      case MV_Warning :
149
      case MV_Error :
150
         ErrorString = MV_ErrorString( MV_ErrorCode );
151
         break;
152
153
      case MV_Ok :
154
         ErrorString = "Multivoc ok.";
155
         break;
156
157
      case MV_UnsupportedCard :
158
         ErrorString = "Selected sound card is not supported by Multivoc.";
159
         break;
160
161
      case MV_NotInstalled :
162
         ErrorString = "Multivoc not installed.";
163
         break;
164
165
      case MV_NoVoices :
166
         ErrorString = "No free voices available to Multivoc.";
167
         break;
168
169
      case MV_NoMem :
170
         ErrorString = "Out of memory in Multivoc.";
171
         break;
172
173
      case MV_VoiceNotFound :
174
         ErrorString = "No voice with matching handle found.";
175
         break;
176
177
      case MV_DPMI_Error :
178
         ErrorString = "DPMI Error in Multivoc.";
179
         break;
180
181
      case MV_InvalidVOCFile :
182
         ErrorString = "Invalid VOC file passed in to Multivoc.";
183
         break;
184
185
      case MV_InvalidWAVFile :
186
         ErrorString = "Invalid WAV file passed in to Multivoc.";
187
         break;
188
189
      case MV_InvalidMixMode :
190
         ErrorString = "Invalid mix mode request in Multivoc.";
191
         break;
192
193
      case MV_IrqFailure :
194
         ErrorString = "Playback failed, possibly due to an invalid or conflicting IRQ.";
195
         break;
196
197
      case MV_DMAFailure :
198
         ErrorString = "Playback failed, possibly due to an invalid or conflicting DMA channel.";
199
         break;
200
201
      case MV_DMA16Failure :
202
         ErrorString = "Playback failed, possibly due to an invalid or conflicting DMA channel.  \n"
203
                       "Make sure the 16-bit DMA channel is correct.";
204
         break;
205
206
      case MV_NullRecordFunction :
207
         ErrorString = "Null record function passed to MV_StartRecording.";
208
         break;
209
210
      default :
211
         ErrorString = "Unknown Multivoc error code.";
212
         break;
213
      }
214
215
   return( ErrorString );
216
   }
217
218
219
/**********************************************************************
220
221
   Memory locked functions:
222
223
**********************************************************************/
224
225
226
#define MV_LockStart MV_Mix
227
228
229
/*---------------------------------------------------------------------
230
   Function: MV_Mix
231
232
   Mixes the sound into the buffer.
233
---------------------------------------------------------------------*/
234
235
static void MV_Mix
236
   (
237
   VoiceNode *voice,
238
   int        buffer
239
   )
240
241
   {
242
   char          *start;
243
   int            length;
244
   long           voclength;
245
   unsigned long  position;
246
   unsigned long  rate;
247
   unsigned long  FixedPointBufferSize;
248
249
   if ( ( voice->length == 0 ) &&
250
        ( voice->GetSound != NULL ) &&
251
        ( voice->GetSound( voice ) != KeepPlaying ) )
252
      {
253
      return;
254
      }
255
256
   length               = MixBufferSize;
257
   FixedPointBufferSize = voice->FixedPointBufferSize;
258
259
   MV_MixDestination    = MV_MixBuffer[ buffer ];
260
   MV_LeftVolume        = voice->LeftVolume;
261
   MV_RightVolume       = voice->RightVolume;
262
263
   if ( ( MV_Channels == 2 ) && ( IS_QUIET( MV_LeftVolume ) ) )
264
      {
265
      MV_LeftVolume      = MV_RightVolume;
266
      MV_MixDestination += MV_RightChannelOffset;
267
      }
268
269
   // Add this voice to the mix
270
   while( length > 0 )
271
      {
272
      start    = voice->sound;
273
      rate     = voice->RateScale;
274
      position = voice->position;
275
276
      // Check if the last sample in this buffer would be
277
      // beyond the length of the sample block
278
      if ( ( position + FixedPointBufferSize ) >= voice->length )
279
         {
280
         if ( position < voice->length )
281
            {
282
            voclength = ( voice->length - position + rate - 1 ) / rate;
283
            }
284
         else
285
            {
286
            voice->GetSound( voice );
287
            return;
288
            }
289
         }
290
      else
291
         {
292
         voclength = length;
293
         }
294
295
      voice->mix( position, rate, start, voclength );
296
297
      if ( voclength & 1 )
298
         {
299
         MV_MixPosition += rate;
300
         voclength -= 1;
301
         }
302
      voice->position = MV_MixPosition;
303
304
      length -= voclength;
305
306
      if ( voice->position >= voice->length )
307
         {
308
         // Get the next block of sound
309
         if ( voice->GetSound( voice ) != KeepPlaying )
310
            {
311
            return;
312
            }
313
314
         if ( length > 0 )
315
            {
316
            // Get the position of the last sample in the buffer
317
            FixedPointBufferSize = voice->RateScale * ( length - 1 );
318
            }
319
         }
320
      }
321
   }
322
323
324
/*---------------------------------------------------------------------
325
   Function: MV_PlayVoice
326
327
   Adds a voice to the play list.
328
---------------------------------------------------------------------*/
329
330
void MV_PlayVoice
331
   (
332
   VoiceNode *voice
333
   )
334
335
   {
336
   unsigned flags;
337
338
   flags = DisableInterrupts();
339
   LL_SortedInsertion( &VoiceList, voice, prev, next, VoiceNode, priority );
340
341
   RestoreInterrupts( flags );
342
   }
343
344
345
/*---------------------------------------------------------------------
346
   Function: MV_StopVoice
347
348
   Removes the voice from the play list and adds it to the free list.
349
---------------------------------------------------------------------*/
350
351
void MV_StopVoice
352
   (
353
   VoiceNode *voice
354
   )
355
356
   {
357
   unsigned  flags;
358
359
   flags = DisableInterrupts();
360
361
   // move the voice from the play list to the free list
362
   LL_Remove( voice, next, prev );
363
   LL_Add( (VoiceNode *)&VoicePool, voice, next, prev );
364
365
   RestoreInterrupts( flags );
366
   }
367
368
369
/*---------------------------------------------------------------------
370
   Function: MV_ServiceVoc
371
372
   Starts playback of the waiting buffer and mixes the next one.
373
---------------------------------------------------------------------*/
374
375
// static int backcolor = 1;
376
377
static int MV_ServiceVoc(int dummy_arg)
378
   {
379
   VoiceNode *voice;
380
   VoiceNode *next;
381
   char      *buffer;
382
383
   // Toggle which buffer we'll mix next
384
   MV_MixPage++;
385
   if ( MV_MixPage >= MV_NumberOfBuffers )
386
      {
387
      MV_MixPage -= MV_NumberOfBuffers;
388
      }
389
390
   if ( MV_ReverbLevel == 0 )
391
      {
392
      // Initialize buffer
393
      //Commented out so that the buffer is always cleared.
394
      //This is so the guys at Echo Speech can mix into the
395
      //buffer even when no sounds are playing.
396
      //if ( !MV_BufferEmpty[ MV_MixPage ] )
397
         {
398
         ClearBuffer_DW( MV_MixBuffer[ MV_MixPage ], MV_Silence, MV_BufferSize >> 2 );
399
         MV_BufferEmpty[ MV_MixPage ] = TRUE;
400
         }
401
      }
402
   else
403
      {
404
      char *end;
405
      char *source;
406
      char *dest;
407
      int   count;
408
      int   length;
409
410
      end = MV_MixBuffer[ 0 ] + MV_BufferLength;;
411
      dest = MV_MixBuffer[ MV_MixPage ];
412
      source = MV_MixBuffer[ MV_MixPage ] - MV_ReverbDelay;
413
      if ( source < MV_MixBuffer[ 0 ] )
414
         {
415
         source += MV_BufferLength;
416
         }
417
418
      length = MV_BufferSize;
419
      while( length > 0 )
420
         {
421
         count = length;
422
         if ( source + count > end )
423
            {
424
            count = end - source;
425
            }
426
427
         if ( MV_Bits == 16 )
428
            {
429
            if ( MV_ReverbTable != NULL )
430
                MV_16BitReverb( source, dest, (const VOLUME16 *)MV_ReverbTable, count / 2 );
431
            else
432
                MV_16BitReverbFast( source, dest, count / 2, MV_ReverbLevel );
433
            }
434
         else
435
            {
436
            if ( MV_ReverbTable != NULL )
437
                MV_8BitReverb( source, dest, (const VOLUME16 *)MV_ReverbTable, count );
438
            else
439
                MV_8BitReverbFast( source, dest, count, MV_ReverbLevel );
440
            }
441
442
         // if we go through the loop again, it means that we've wrapped around the buffer
443
         source  = MV_MixBuffer[ 0 ];
444
         dest   += count;
445
         length -= count;
446
         }
447
      }
448
449
   // Play any waiting voices
450
   for( voice = VoiceList.next; voice != &VoiceList; voice = next )
451
      {
452
//      if ( ( voice < &MV_Voices[ 0 ] ) || ( voice > &MV_Voices[ 8 ] ) )
453
//         {
454
//         SetBorderColor(backcolor++);
455
//         break;
456
//         }
457
458
      MV_BufferEmpty[ MV_MixPage ] = FALSE;
459
460
      if (MV_MixFunction != NULL)
461
        MV_MixFunction( voice, MV_MixPage );
462
463
      next = voice->next;
464
465
      // Is this voice done?
466
      if ( !voice->Playing )
467
         {
468
         MV_StopVoice( voice );
469
470
         if ( MV_CallBackFunc )
471
            {
472
            MV_CallBackFunc( voice->callbackval );
473
            }
474
         }
475
      }
476
   }
477
478
479
int leftpage  = -1;
480
int rightpage = -1;
481
482
void MV_ServiceGus( char **ptr, unsigned long *length )
483
   {
484
   if ( leftpage == MV_MixPage )
485
      {
486
      MV_ServiceVoc(0);
487
      }
488
489
   leftpage = MV_MixPage;
490
491
   *ptr = MV_MixBuffer[ MV_MixPage ];
492
   *length = MV_BufferSize;
493
   }
494
495
void MV_ServiceRightGus( char **ptr, unsigned long *length )
496
   {
497
   if ( rightpage == MV_MixPage )
498
      {
499
      MV_ServiceVoc(0);
500
      }
501
502
   rightpage = MV_MixPage;
503
504
   *ptr = MV_MixBuffer[ MV_MixPage ] + MV_RightChannelOffset;
505
   *length = MV_BufferSize;
506
   }
507
508
/*---------------------------------------------------------------------
509
   Function: MV_GetNextVOCBlock
510
511
   Interperate the information of a VOC format sound file.
512
---------------------------------------------------------------------*/
513
static __inline unsigned int get_le32(void *p0)
514
{
515
   //unsigned char *p = p0;
516
   //return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
517
   unsigned int val = *((unsigned int *) p0);
518
   return(BUILDSWAP_INTEL32(val));
519
}
520
521
static __inline unsigned int get_le16(void *p0)
522
{
523
   //unsigned char *p = p0;
524
   //return p[0] | (p[1]<<8);
525
   unsigned short val = *((unsigned short *) p0);
526
   return( (unsigned int) (BUILDSWAP_INTEL16(val)) );
527
}
528
529
playbackstatus MV_GetNextVOCBlock
530
   (
531
   VoiceNode *voice
532
   )
533
534
   {
535
   unsigned char *ptr;
536
   int            blocktype=0;
537
   int            lastblocktype=0;
538
   unsigned long  blocklength=0l;
539
   unsigned long  samplespeed=0l;
540
   unsigned int   tc=0;
541
   int            packtype=0;
542
   int            voicemode=0;
543
   int            done=0;
544
   unsigned       BitsPerSample;
545
   unsigned       Channels;
546
   unsigned       Format;
547
548
   if ( voice->BlockLength > 0 )
549
      {
550
      voice->position    -= voice->length;
551
      voice->sound       += voice->length >> 16;
552
      if ( voice->bits == 16 )
553
         {
554
         voice->sound += voice->length >> 16;
555
         }
556
      voice->length       = min( voice->BlockLength, 0x8000 );
557
      voice->BlockLength -= voice->length;
558
      voice->length     <<= 16;
559
      return( KeepPlaying );
560
      }
561
562
   if ( ( voice->length > 0 ) && ( voice->LoopEnd != NULL ) &&
563
      ( voice->LoopStart != NULL ) )
564
      {
565
      voice->BlockLength  = voice->LoopSize;
566
      voice->sound        = voice->LoopStart;
567
      voice->position     = 0;
568
      voice->length       = min( voice->BlockLength, 0x8000 );
569
      voice->BlockLength -= voice->length;
570
      voice->length     <<= 16;
571
      return( KeepPlaying );
572
      }
573
574
   ptr = ( unsigned char * )voice->NextBlock;
575
576
   voice->Playing = TRUE;
577
578
   voicemode = 0;
579
   lastblocktype = 0;
580
   packtype = 0;
581
582
   done = FALSE;
583
   while( !done )
584
      {
585
      // Stop playing if we get a NULL pointer
586
      if ( ptr == NULL )
587
         {
588
         voice->Playing = FALSE;
589
         done = TRUE;
590
         break;
591
         }
592
593
      {
594
      unsigned tmp = get_le32(ptr);
595
      blocktype = tmp&255;
596
      blocklength = tmp>>8;
597
      }
598
      ptr += 4;
599
600
      switch( blocktype )
601
         {
602
         case 0 :
603
            // End of data
604
            if ( ( voice->LoopStart == NULL ) ||
605
               ( (unsigned char *)voice->LoopStart >= ( ptr - 4 ) ) )
606
               {
607
               voice->Playing = FALSE;
608
               done = TRUE;
609
               }
610
            else
611
               {
612
               voice->BlockLength  = ( ptr - 4 ) - (unsigned char *)voice->LoopStart;
613
               voice->sound        = voice->LoopStart;
614
               voice->position     = 0;
615
               voice->length       = min( voice->BlockLength, 0x8000 );
616
               voice->BlockLength -= voice->length;
617
               voice->length     <<= 16;
618
               return( KeepPlaying );
619
               }
620
            break;
621
622
         case 1 :
623
            // Sound data block
624
            voice->bits  = 8;
625
            if ( lastblocktype != 8 )
626
               {
627
               tc = ( unsigned int )*ptr << 8;
628
               packtype = *( ptr + 1 );
629
               }
630
631
            ptr += 2;
632
            blocklength -= 2;
633
634
            samplespeed = 256000000L / ( 65536 - tc );
635
636
            // Skip packed or stereo data
637
            if ( ( packtype != 0 ) || ( voicemode != 0 ) )
638
               {
639
               ptr += blocklength;
640
               }
641
            else
642
               {
643
               done = TRUE;
644
               }
645
            voicemode = 0;
646
            break;
647
648
         case 2 :
649
            // Sound continuation block
650
            samplespeed = voice->SamplingRate;
651
            done = TRUE;
652
            break;
653
654
         case 3 :
655
            // Silence
656
            // Not implimented.
657
            ptr += blocklength;
658
            break;
659
660
         case 4 :
661
            // Marker
662
            // Not implimented.
663
            ptr += blocklength;
664
            break;
665
666
         case 5 :
667
            // ASCII string
668
            // Not implimented.
669
            ptr += blocklength;
670
            break;
671
672
         case 6 :
673
            // Repeat begin
674
            if ( voice->LoopEnd == NULL )
675
               {
676
               voice->LoopCount = get_le16(ptr);
677
               voice->LoopStart = ptr + blocklength;
678
               }
679
            ptr += blocklength;
680
            break;
681
682
         case 7 :
683
            // Repeat end
684
            ptr += blocklength;
685
            if ( lastblocktype == 6 )
686
               {
687
               voice->LoopCount = 0;
688
               }
689
            else
690
               {
691
               if ( ( voice->LoopCount > 0 ) && ( voice->LoopStart != NULL ) )
692
                  {
693
                  ptr = voice->LoopStart;
694
                  if ( voice->LoopCount < 0xffff )
695
                     {
696
                     voice->LoopCount--;
697
                     if ( voice->LoopCount == 0 )
698
                        {
699
                        voice->LoopStart = NULL;
700
                        }
701
                     }
702
                  }
703
               }
704
            break;
705
706
         case 8 :
707
            // Extended block
708
            voice->bits  = 8;
709
            tc = get_le16(ptr);
710
            packtype = *( ptr + 2 );
711
            voicemode = *( ptr + 3 );
712
            ptr += blocklength;
713
            break;
714
715
         case 9 :
716
            // New sound data block
717
            samplespeed = get_le32(ptr);
718
            BitsPerSample = ptr[4];
719
            Channels = ptr[5];
720
            Format = get_le16(ptr+6);
721
722
            if ( ( BitsPerSample == 8 ) && ( Channels == 1 ) &&
723
               ( Format == VOC_8BIT ) )
724
               {
725
               ptr         += 12;
726
               blocklength -= 12;
727
               voice->bits  = 8;
728
               done         = TRUE;
729
               }
730
            else if ( ( BitsPerSample == 16 ) && ( Channels == 1 ) &&
731
               ( Format == VOC_16BIT ) )
732
               {
733
               ptr         += 12;
734
               blocklength -= 12;
735
               voice->bits  = 16;
736
               done         = TRUE;
737
               }
738
            else
739
               {
740
               ptr += blocklength;
741
               }
742
            break;
743
744
         default :
745
            // Unknown data.  Probably not a VOC file.
746
            voice->Playing = FALSE;
747
            done = TRUE;
748
            break;
749
         }
750
751
      lastblocktype = blocktype;
752
      }
753
754
   if ( voice->Playing )
755
      {
756
      voice->NextBlock    = ptr + blocklength;
757
      voice->sound        = ptr;
758
759
      voice->SamplingRate = samplespeed;
760
      voice->RateScale    = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate;
761
762
      // Multiply by MixBufferSize - 1
763
      voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) -
764
         voice->RateScale;
765
766
      if ( voice->LoopEnd != NULL )
767
         {
768
         if ( blocklength > ( unsigned long )voice->LoopEnd )
769
            {
770
            blocklength = ( unsigned long )voice->LoopEnd;
771
            }
772
         else
773
            {
774
            voice->LoopEnd = ( char * )blocklength;
775
            }
776
777
         voice->LoopStart = voice->sound + ( unsigned long )voice->LoopStart;
778
         voice->LoopEnd   = voice->sound + ( unsigned long )voice->LoopEnd;
779
         voice->LoopSize  = voice->LoopEnd - voice->LoopStart;
780
         }
781
782
      if ( voice->bits == 16 )
783
         {
784
         blocklength /= 2;
785
         }
786
787
      voice->position     = 0;
788
      voice->length       = min( blocklength, 0x8000 );
789
      voice->BlockLength  = blocklength - voice->length;
790
      voice->length     <<= 16;
791
792
      MV_SetVoiceMixMode( voice );
793
794
      return( KeepPlaying );
795
      }
796
797
   return( NoMoreData );
798
   }
799
800
801
/*---------------------------------------------------------------------
802
   Function: MV_GetNextDemandFeedBlock
803
804
   Controls playback of demand fed data.
805
---------------------------------------------------------------------*/
806
807
playbackstatus MV_GetNextDemandFeedBlock
808
   (
809
   VoiceNode *voice
810
   )
811
812
   {
813
   if ( voice->BlockLength > 0 )
814
      {
815
      voice->position    -= voice->length;
816
      voice->sound       += voice->length >> 16;
817
      voice->length       = min( voice->BlockLength, 0x8000 );
818
      voice->BlockLength -= voice->length;
819
      voice->length     <<= 16;
820
821
      return( KeepPlaying );
822
      }
823
824
   if ( voice->DemandFeed == NULL )
825
      {
826
      return( NoMoreData );
827
      }
828
829
   voice->position     = 0;
830
   ( voice->DemandFeed )( &voice->sound, &voice->BlockLength );
831
   voice->length       = min( voice->BlockLength, 0x8000 );
832
   voice->BlockLength -= voice->length;
833
   voice->length     <<= 16;
834
835
   if ( ( voice->length > 0 ) && ( voice->sound != NULL ) )
836
      {
837
      return( KeepPlaying );
838
      }
839
   return( NoMoreData );
840
   }
841
842
843
/*---------------------------------------------------------------------
844
   Function: MV_GetNextRawBlock
845
846
   Controls playback of demand fed data.
847
---------------------------------------------------------------------*/
848
849
playbackstatus MV_GetNextRawBlock
850
   (
851
   VoiceNode *voice
852
   )
853
854
   {
855
   if ( voice->BlockLength <= 0 )
856
      {
857
      if ( voice->LoopStart == NULL )
858
         {
859
         voice->Playing = FALSE;
860
         return( NoMoreData );
861
         }
862
863
      voice->BlockLength = voice->LoopSize;
864
      voice->NextBlock   = voice->LoopStart;
865
      voice->length = 0;
866
      voice->position = 0;
867
      }
868
869
   voice->sound        = voice->NextBlock;
870
   voice->position    -= voice->length;
871
   voice->length       = min( voice->BlockLength, 0x8000 );
872
   voice->NextBlock   += voice->length;
873
   if ( voice->bits == 16 )
874
      {
875
      voice->NextBlock += voice->length;
876
      }
877
   voice->BlockLength -= voice->length;
878
   voice->length     <<= 16;
879
880
   return( KeepPlaying );
881
   }
882
883
884
/*---------------------------------------------------------------------
885
   Function: MV_GetNextWAVBlock
886
887
   Controls playback of demand fed data.
888
---------------------------------------------------------------------*/
889
890
playbackstatus MV_GetNextWAVBlock
891
   (
892
   VoiceNode *voice
893
   )
894
895
   {
896
   if ( voice->BlockLength <= 0 )
897
      {
898
      if ( voice->LoopStart == NULL )
899
         {
900
         voice->Playing = FALSE;
901
         return( NoMoreData );
902
         }
903
904
      voice->BlockLength = voice->LoopSize;
905
      voice->NextBlock   = voice->LoopStart;
906
      voice->length      = 0;
907
      voice->position    = 0;
908
      }
909
910
   voice->sound        = voice->NextBlock;
911
   voice->position    -= voice->length;
912
   voice->length       = min( voice->BlockLength, 0x8000 );
913
   voice->NextBlock   += voice->length;
914
   if ( voice->bits == 16 )
915
      {
916
      voice->NextBlock += voice->length;
917
      }
918
   voice->BlockLength -= voice->length;
919
   voice->length     <<= 16;
920
921
   return( KeepPlaying );
922
   }
923
924
925
/*---------------------------------------------------------------------
926
   Function: MV_ServiceRecord
927
928
   Starts recording of the waiting buffer.
929
---------------------------------------------------------------------*/
930
931
static void MV_ServiceRecord
932
   (
933
   void
934
   )
935
936
   {
937
   if ( MV_RecordFunc )
938
      {
939
      MV_RecordFunc( MV_MixBuffer[ 0 ] + MV_MixPage * MixBufferSize,
940
         MixBufferSize );
941
      }
942
943
   // Toggle which buffer we'll mix next
944
   MV_MixPage++;
945
   if ( MV_MixPage >= NumberOfBuffers )
946
      {
947
      MV_MixPage = 0;
948
      }
949
   }
950
951
952
/*---------------------------------------------------------------------
953
   Function: MV_GetVoice
954
955
   Locates the voice with the specified handle.
956
---------------------------------------------------------------------*/
957
958
VoiceNode *MV_GetVoice
959
   (
960
   int handle
961
   )
962
963
   {
964
   VoiceNode *voice;
965
   unsigned  flags;
966
967
   flags = DisableInterrupts();
968
969
   for( voice = VoiceList.next; voice != &VoiceList; voice = voice->next )
970
      {
971
      if ( handle == voice->handle )
972
         {
973
         break;
974
         }
975
      }
976
977
   RestoreInterrupts( flags );
978
979
   if ( voice == &VoiceList )
980
      {
981
      MV_SetErrorCode( MV_VoiceNotFound );
982
      
983
      // SBF - should this return null?
984
      return NULL;
985
      }
986
987
   return( voice );
988
   }
989
990
991
/*---------------------------------------------------------------------
992
   Function: MV_VoicePlaying
993
994
   Checks if the voice associated with the specified handle is
995
   playing.
996
---------------------------------------------------------------------*/
997
998
int MV_VoicePlaying
999
   (
1000
   int handle
1001
   )
1002
1003
   {
1004
   VoiceNode *voice;
1005
1006
   if ( !MV_Installed )
1007
      {
1008
      MV_SetErrorCode( MV_NotInstalled );
1009
      return( FALSE );
1010
      }
1011
1012
   voice = MV_GetVoice( handle );
1013
1014
   if ( voice == NULL )
1015
      {
1016
      return( FALSE );
1017
      }
1018
1019
   return( TRUE );
1020
   }
1021
1022
1023
/*---------------------------------------------------------------------
1024
   Function: MV_KillAllVoices
1025
1026
   Stops output of all currently active voices.
1027
---------------------------------------------------------------------*/
1028
1029
int MV_KillAllVoices
1030
   (
1031
   void
1032
   )
1033
1034
   {
1035
   if ( !MV_Installed )
1036
      {
1037
      MV_SetErrorCode( MV_NotInstalled );
1038
      return( MV_Error );
1039
      }
1040
1041
   // Remove all the voices from the list
1042
   while( VoiceList.next != &VoiceList )
1043
      {
1044
      MV_Kill( VoiceList.next->handle );
1045
      }
1046
1047
   return( MV_Ok );
1048
   }
1049
1050
1051
/*---------------------------------------------------------------------
1052
   Function: MV_Kill
1053
1054
   Stops output of the voice associated with the specified handle.
1055
---------------------------------------------------------------------*/
1056
1057
int MV_Kill
1058
   (
1059
   int handle
1060
   )
1061
1062
   {
1063
   VoiceNode *voice;
1064
   unsigned  flags;
1065
   unsigned  long callbackval;
1066
1067
   if ( !MV_Installed )
1068
      {
1069
      MV_SetErrorCode( MV_NotInstalled );
1070
      return( MV_Error );
1071
      }
1072
1073
   flags = DisableInterrupts();
1074
1075
   voice = MV_GetVoice( handle );
1076
   if ( voice == NULL )
1077
      {
1078
      RestoreInterrupts( flags );
1079
      MV_SetErrorCode( MV_VoiceNotFound );
1080
      return( MV_Error );
1081
      }
1082
1083
   callbackval = voice->callbackval;
1084
1085
   MV_StopVoice( voice );
1086
1087
   RestoreInterrupts( flags );
1088
1089
   if ( MV_CallBackFunc )
1090
      {
1091
      MV_CallBackFunc( callbackval );
1092
      }
1093
1094
   return( MV_Ok );
1095
   }
1096
1097
1098
/*---------------------------------------------------------------------
1099
   Function: MV_VoicesPlaying
1100
1101
   Determines the number of currently active voices.
1102
---------------------------------------------------------------------*/
1103
1104
int MV_VoicesPlaying
1105
   (
1106
   void
1107
   )
1108
1109
   {
1110
   VoiceNode   *voice;
1111
   int         NumVoices = 0;
1112
   unsigned    flags;
1113
1114
   if ( !MV_Installed )
1115
      {
1116
      MV_SetErrorCode( MV_NotInstalled );
1117
      return( 0 );
1118
      }
1119
1120
   flags = DisableInterrupts();
1121
1122
   for( voice = VoiceList.next; voice != &VoiceList; voice = voice->next )
1123
      {
1124
      NumVoices++;
1125
      }
1126
1127
   RestoreInterrupts( flags );
1128
1129
   return( NumVoices );
1130
   }
1131
1132
1133
/*---------------------------------------------------------------------
1134
   Function: MV_AllocVoice
1135
1136
   Retrieve an inactive or lower priority voice for output.
1137
---------------------------------------------------------------------*/
1138
1139
VoiceNode *MV_AllocVoice
1140
   (
1141
   int priority
1142
   )
1143
1144
   {
1145
   VoiceNode   *voice;
1146
   VoiceNode   *node;
1147
   unsigned    flags;
1148
1149
//return( NULL );
1150
   if ( MV_Recording )
1151
      {
1152
      return( NULL );
1153
      }
1154
1155
   flags = DisableInterrupts();
1156
1157
   // Check if we have any free voices
1158
   if ( LL_Empty( &VoicePool, next, prev ) )
1159
      {
1160
      // check if we have a higher priority than a voice that is playing.
1161
      voice = VoiceList.next;
1162
      for( node = voice->next; node != &VoiceList; node = node->next )
1163
         {
1164
         if ( node->priority < voice->priority )
1165
            {
1166
            voice = node;
1167
            }
1168
         }
1169
1170
      if ( priority >= voice->priority )
1171
         {
1172
         MV_Kill( voice->handle );
1173
         }
1174
      }
1175
1176
   // Check if any voices are in the voice pool
1177
   if ( LL_Empty( &VoicePool, next, prev ) )
1178
      {
1179
      // No free voices
1180
      RestoreInterrupts( flags );
1181
      return( NULL );
1182
      }
1183
1184
   voice = VoicePool.next;
1185
   LL_Remove( voice, next, prev );
1186
   RestoreInterrupts( flags );
1187
1188
   // Find a free voice handle
1189
   do
1190
      {
1191
      MV_VoiceHandle++;
1192
      if ( MV_VoiceHandle < MV_MinVoiceHandle )
1193
         {
1194
         MV_VoiceHandle = MV_MinVoiceHandle;
1195
         }
1196
      }
1197
   while( MV_VoicePlaying( MV_VoiceHandle ) );
1198
1199
   voice->handle = MV_VoiceHandle;
1200
1201
   return( voice );
1202
   }
1203
1204
1205
/*---------------------------------------------------------------------
1206
   Function: MV_VoiceAvailable
1207
1208
   Checks if a voice can be play at the specified priority.
1209
---------------------------------------------------------------------*/
1210
1211
int MV_VoiceAvailable
1212
   (
1213
   int priority
1214
   )
1215
1216
   {
1217
   VoiceNode   *voice;
1218
   VoiceNode   *node;
1219
   unsigned    flags;
1220
1221
   // Check if we have any free voices
1222
   if ( !LL_Empty( &VoicePool, next, prev ) )
1223
      {
1224
      return( TRUE );
1225
      }
1226
1227
   flags = DisableInterrupts();
1228
1229
   // check if we have a higher priority than a voice that is playing.
1230
   voice = VoiceList.next;
1231
   for( node = VoiceList.next; node != &VoiceList; node = node->next )
1232
      {
1233
      if ( node->priority < voice->priority )
1234
         {
1235
         voice = node;
1236
         }
1237
      }
1238
1239
   RestoreInterrupts( flags );
1240
1241
   if ( ( voice != &VoiceList ) && ( priority >= voice->priority ) )
1242
      {
1243
      return( TRUE );
1244
      }
1245
1246
   return( FALSE );
1247
   }
1248
1249
1250
/*---------------------------------------------------------------------
1251
   Function: MV_SetVoicePitch
1252
1253
   Sets the pitch for the specified voice.
1254
---------------------------------------------------------------------*/
1255
1256
void MV_SetVoicePitch
1257
   (
1258
   VoiceNode *voice,
1259
   unsigned long rate,
1260
   int pitchoffset
1261
   )
1262
1263
   {
1264
   voice->SamplingRate = rate;
1265
   voice->PitchScale   = PITCH_GetScale( pitchoffset );
1266
   voice->RateScale    = ( rate * voice->PitchScale ) / MV_MixRate;
1267
1268
   // Multiply by MixBufferSize - 1
1269
   voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) -
1270
      voice->RateScale;
1271
   }
1272
1273
1274
/*---------------------------------------------------------------------
1275
   Function: MV_SetPitch
1276
1277
   Sets the pitch for the voice associated with the specified handle.
1278
---------------------------------------------------------------------*/
1279
1280
int MV_SetPitch
1281
   (
1282
   int handle,
1283
   int pitchoffset
1284
   )
1285
1286
   {
1287
   VoiceNode *voice;
1288
1289
   if ( !MV_Installed )
1290
      {
1291
      MV_SetErrorCode( MV_NotInstalled );
1292
      return( MV_Error );
1293
      }
1294
1295
   voice = MV_GetVoice( handle );
1296
   if ( voice == NULL )
1297
      {
1298
      MV_SetErrorCode( MV_VoiceNotFound );
1299
      return( MV_Error );
1300
      }
1301
1302
   MV_SetVoicePitch( voice, voice->SamplingRate, pitchoffset );
1303
1304
   return( MV_Ok );
1305
   }
1306
1307
1308
/*---------------------------------------------------------------------
1309
   Function: MV_SetFrequency
1310
1311
   Sets the frequency for the voice associated with the specified handle.
1312
---------------------------------------------------------------------*/
1313
1314
int MV_SetFrequency
1315
   (
1316
   int handle,
1317
   int frequency
1318
   )
1319
1320
   {
1321
   VoiceNode *voice;
1322
1323
   if ( !MV_Installed )
1324
      {
1325
      MV_SetErrorCode( MV_NotInstalled );
1326
      return( MV_Error );
1327
      }
1328
1329
   voice = MV_GetVoice( handle );
1330
   if ( voice == NULL )
1331
      {
1332
      MV_SetErrorCode( MV_VoiceNotFound );
1333
      return( MV_Error );
1334
      }
1335
1336
   MV_SetVoicePitch( voice, frequency, 0 );
1337
1338
   return( MV_Ok );
1339
   }
1340
1341
1342
/*---------------------------------------------------------------------
1343
   Function: MV_GetVolumeTable
1344
1345
   Returns a pointer to the volume table associated with the specified
1346
   volume.
1347
---------------------------------------------------------------------*/
1348
1349
static short *MV_GetVolumeTable
1350
   (
1351
   int vol
1352
   )
1353
1354
   {
1355
   int volume;
1356
   short *table;
1357
1358
   volume = MIX_VOLUME( vol );
1359
1360
   table = (short *)&MV_VolumeTable[ volume ];
1361
1362
   return( table );
1363
   }
1364
1365
1366
/*---------------------------------------------------------------------
1367
   Function: MV_SetVoiceMixMode
1368
1369
   Selects which method should be used to mix the voice.
1370
---------------------------------------------------------------------*/
1371
1372
static void MV_SetVoiceMixMode
1373
   (
1374
   VoiceNode *voice
1375
   )
1376
1377
   {
1378
   unsigned flags;
1379
   int test;
1380
1381
   flags = DisableInterrupts();
1382
1383
   test = T_DEFAULT;
1384
   if ( MV_Bits == 8 )
1385
      {
1386
      test |= T_8BITS;
1387
      }
1388
1389
   if ( voice->bits == 16 )
1390
      {
1391
      test |= T_16BITSOURCE;
1392
      }
1393
1394
   if ( MV_Channels == 1 )
1395
      {
1396
      test |= T_MONO;
1397
      }
1398
   else
1399
      {
1400
      if ( IS_QUIET( voice->RightVolume ) )
1401
         {
1402
         test |= T_RIGHTQUIET;
1403
         }
1404
      else if ( IS_QUIET( voice->LeftVolume ) )
1405
         {
1406
         test |= T_LEFTQUIET;
1407
         }
1408
      }
1409
1410
   // Default case
1411
   voice->mix = MV_Mix8BitMono;
1412
1413
   switch( test )
1414
      {
1415
      case T_8BITS | T_MONO | T_16BITSOURCE :
1416
         voice->mix = MV_Mix8BitMono16;
1417
         break;
1418
1419
      case T_8BITS | T_MONO :
1420
         voice->mix = MV_Mix8BitMono;
1421
         break;
1422
1423
      case T_8BITS | T_16BITSOURCE | T_LEFTQUIET :
1424
         MV_LeftVolume = MV_RightVolume;
1425
         voice->mix = MV_Mix8BitMono16;
1426
         break;
1427
1428
      case T_8BITS | T_LEFTQUIET :
1429
         MV_LeftVolume = MV_RightVolume;
1430
         voice->mix = MV_Mix8BitMono;
1431
         break;
1432
1433
      case T_8BITS | T_16BITSOURCE | T_RIGHTQUIET :
1434
         voice->mix = MV_Mix8BitMono16;
1435
         break;
1436
1437
      case T_8BITS | T_RIGHTQUIET :
1438
         voice->mix = MV_Mix8BitMono;
1439
         break;
1440
1441
      case T_8BITS | T_16BITSOURCE :
1442
         voice->mix = MV_Mix8BitStereo16;
1443
         break;
1444
1445
      case T_8BITS :
1446
         voice->mix = MV_Mix8BitStereo;
1447
         break;
1448
1449
      case T_MONO | T_16BITSOURCE :
1450
         voice->mix = MV_Mix16BitMono16;
1451
         break;
1452
1453
      case T_MONO :
1454
         voice->mix = MV_Mix16BitMono;
1455
         break;
1456
1457
      case T_16BITSOURCE | T_LEFTQUIET :
1458
         MV_LeftVolume = MV_RightVolume;
1459
         voice->mix = MV_Mix16BitMono16;
1460
         break;
1461
1462
      case T_LEFTQUIET :
1463
         MV_LeftVolume = MV_RightVolume;
1464
         voice->mix = MV_Mix16BitMono;
1465
         break;
1466
1467
      case T_16BITSOURCE | T_RIGHTQUIET :
1468
         voice->mix = MV_Mix16BitMono16;
1469
         break;
1470
1471
      case T_RIGHTQUIET :
1472
         voice->mix = MV_Mix16BitMono;
1473
         break;
1474
1475
      case T_16BITSOURCE :
1476
         voice->mix = MV_Mix16BitStereo16;
1477
         break;
1478
1479
      case T_SIXTEENBIT_STEREO :
1480
         voice->mix = MV_Mix16BitStereo;
1481
         break;
1482
1483
      default :
1484
         voice->mix = MV_Mix8BitMono;
1485
      }
1486
1487
   RestoreInterrupts( flags );
1488
   }
1489
1490
1491
/*---------------------------------------------------------------------
1492
   Function: MV_SetVoiceVolume
1493
1494
   Sets the stereo and mono volume level of the voice associated
1495
   with the specified handle.
1496
---------------------------------------------------------------------*/
1497
1498
void MV_SetVoiceVolume
1499
   (
1500
   VoiceNode *voice,
1501
   int vol,
1502
   int left,
1503
   int right
1504
   )
1505
1506
   {
1507
   if ( MV_Channels == 1 )
1508
      {
1509
      left  = vol;
1510
      right = vol;
1511
      }
1512
1513
   if ( MV_SwapLeftRight )
1514
      {
1515
      // SBPro uses reversed panning
1516
      voice->LeftVolume  = MV_GetVolumeTable( right );
1517
      voice->RightVolume = MV_GetVolumeTable( left );
1518
      }
1519
   else
1520
      {
1521
      voice->LeftVolume  = MV_GetVolumeTable( left );
1522
      voice->RightVolume = MV_GetVolumeTable( right );
1523
      }
1524
1525
   MV_SetVoiceMixMode( voice );
1526
   }
1527
1528
1529
/*---------------------------------------------------------------------
1530
   Function: MV_EndLooping
1531
1532
   Stops the voice associated with the specified handle from looping
1533
   without stoping the sound.
1534
---------------------------------------------------------------------*/
1535
1536
int MV_EndLooping
1537
   (
1538
   int handle
1539
   )
1540
1541
   {
1542
   VoiceNode *voice;
1543
   unsigned flags;
1544
1545
   if ( !MV_Installed )
1546
      {
1547
      MV_SetErrorCode( MV_NotInstalled );
1548
      return( MV_Error );
1549
      }
1550
1551
   flags = DisableInterrupts();
1552
1553
   voice = MV_GetVoice( handle );
1554
   if ( voice == NULL )
1555
      {
1556
      RestoreInterrupts( flags );
1557
      MV_SetErrorCode( MV_VoiceNotFound );
1558
      return( MV_Warning );
1559
      }
1560
1561
   voice->LoopCount = 0;
1562
   voice->LoopStart = NULL;
1563
   voice->LoopEnd   = NULL;
1564
1565
   RestoreInterrupts( flags );
1566
1567
   return( MV_Ok );
1568
   }
1569
1570
1571
/*---------------------------------------------------------------------
1572
   Function: MV_SetPan
1573
1574
   Sets the stereo and mono volume level of the voice associated
1575
   with the specified handle.
1576
---------------------------------------------------------------------*/
1577
1578
int MV_SetPan
1579
   (
1580
   int handle,
1581
   int vol,
1582
   int left,
1583
   int right
1584
   )
1585
1586
   {
1587
   VoiceNode *voice;
1588
1589
   if ( !MV_Installed )
1590
      {
1591
      MV_SetErrorCode( MV_NotInstalled );
1592
      return( MV_Error );
1593
      }
1594
1595
   voice = MV_GetVoice( handle );
1596
   if ( voice == NULL )
1597
      {
1598
      MV_SetErrorCode( MV_VoiceNotFound );
1599
      return( MV_Warning );
1600
      }
1601
1602
   MV_SetVoiceVolume( voice, vol, left, right );
1603
1604
   return( MV_Ok );
1605
   }
1606
1607
1608
/*---------------------------------------------------------------------
1609
   Function: MV_Pan3D
1610
1611
   Set the angle and distance from the listener of the voice associated
1612
   with the specified handle.
1613
---------------------------------------------------------------------*/
1614
1615
int MV_Pan3D
1616
   (
1617
   int handle,
1618
   int angle,
1619
   int distance
1620
   )
1621
1622
   {
1623
   int left;
1624
   int right;
1625
   int mid;
1626
   int volume;
1627
   int status;
1628
1629
   if ( distance < 0 )
1630
      {
1631
      distance  = -distance;
1632
      angle    += MV_NumPanPositions / 2;
1633
      }
1634
1635
   volume = MIX_VOLUME( distance );
1636
1637
   // Ensure angle is within 0 - 31
1638
   angle &= MV_MaxPanPosition;
1639
1640
   left  = MV_PanTable[ angle ][ volume ].left;
1641
   right = MV_PanTable[ angle ][ volume ].right;
1642
   mid   = max( 0, 255 - distance );
1643
1644
   status = MV_SetPan( handle, mid, left, right );
1645
1646
   return( status );
1647
   }
1648
1649
1650
/*---------------------------------------------------------------------
1651
   Function: MV_SetReverb
1652
1653
   Sets the level of reverb to add to mix.
1654
---------------------------------------------------------------------*/
1655
1656
void MV_SetReverb
1657
   (
1658
   int reverb
1659
   )
1660
1661
   {
1662
   MV_ReverbLevel = MIX_VOLUME( reverb );
1663
   MV_ReverbTable = &MV_VolumeTable[ MV_ReverbLevel ];
1664
   }
1665
1666
1667
/*---------------------------------------------------------------------
1668
   Function: MV_SetFastReverb
1669
1670
   Sets the level of reverb to add to mix.
1671
---------------------------------------------------------------------*/
1672
1673
void MV_SetFastReverb
1674
   (
1675
   int reverb
1676
   )
1677
1678
   {
1679
   MV_ReverbLevel = max( 0, min( 16, reverb ) );
1680
   MV_ReverbTable = NULL;
1681
   }
1682
1683
1684
/*---------------------------------------------------------------------
1685
   Function: MV_GetMaxReverbDelay
1686
1687
   Returns the maximum delay time for reverb.
1688
---------------------------------------------------------------------*/
1689
1690
int MV_GetMaxReverbDelay
1691
   (
1692
   void
1693
   )
1694
1695
   {
1696
   int maxdelay;
1697
1698
   maxdelay = MixBufferSize * MV_NumberOfBuffers;
1699
1700
   return maxdelay;
1701
   }
1702
1703
1704
/*---------------------------------------------------------------------
1705
   Function: MV_GetReverbDelay
1706
1707
   Returns the current delay time for reverb.
1708
---------------------------------------------------------------------*/
1709
1710
int MV_GetReverbDelay
1711
   (
1712
   void
1713
   )
1714
1715
   {
1716
   return MV_ReverbDelay / MV_SampleSize;
1717
   }
1718
1719
1720
/*---------------------------------------------------------------------
1721
   Function: MV_SetReverbDelay
1722
1723
   Sets the delay level of reverb to add to mix.
1724
---------------------------------------------------------------------*/
1725
1726
void MV_SetReverbDelay
1727
   (
1728
   int delay
1729
   )
1730
1731
   {
1732
   int maxdelay;
1733
1734
   maxdelay = MV_GetMaxReverbDelay();
1735
   MV_ReverbDelay = max( MixBufferSize, min( delay, maxdelay ) );
1736
   MV_ReverbDelay *= MV_SampleSize;
1737
   }
1738
1739
1740
/*---------------------------------------------------------------------
1741
   Function: MV_SetMixMode
1742
1743
   Prepares Multivoc to play stereo of mono digitized sounds.
1744
---------------------------------------------------------------------*/
1745
1746
int MV_SetMixMode
1747
   (
1748
   int numchannels,
1749
   int samplebits
1750
   )
1751
1752
   {
1753
   int mode;
1754
1755
   if ( !MV_Installed )
1756
      {
1757
      MV_SetErrorCode( MV_NotInstalled );
1758
      return( MV_Error );
1759
      }
1760
1761
   mode = 0;
1762
   if ( numchannels == 2 )
1763
      {
1764
      mode |= STEREO;
1765
      }
1766
   if ( samplebits == 16 )
1767
      {
1768
      mode |= SIXTEEN_BIT;
1769
      }
1770
1771
   MV_MixMode = mode;
1772
1773
   MV_Channels = 1;
1774
   if ( MV_MixMode & STEREO )
1775
      {
1776
      MV_Channels = 2;
1777
      }
1778
1779
   MV_Bits = 8;
1780
   if ( MV_MixMode & SIXTEEN_BIT )
1781
      {
1782
      MV_Bits = 16;
1783
      }
1784
1785
   MV_BuffShift  = 7 + MV_Channels;
1786
   MV_SampleSize = sizeof( MONO8 ) * MV_Channels;
1787
1788
   if ( MV_Bits == 8 )
1789
      {
1790
      MV_Silence = SILENCE_8BIT;
1791
      }
1792
   else
1793
      {
1794
      MV_Silence     = SILENCE_16BIT;
1795
      MV_BuffShift  += 1;
1796
      MV_SampleSize *= 2;
1797
      }
1798
1799
   MV_BufferSize = MixBufferSize * MV_SampleSize;
1800
   MV_NumberOfBuffers = TotalBufferSize / MV_BufferSize;
1801
   MV_BufferLength = TotalBufferSize;
1802
1803
   MV_RightChannelOffset = MV_SampleSize / 2;
1804
1805
   return( MV_Ok );
1806
   }
1807
1808
1809
/*---------------------------------------------------------------------
1810
   Function: MV_StartPlayback
1811
1812
   Starts the sound playback engine.
1813
---------------------------------------------------------------------*/
1814
1815
int MV_StartPlayback
1816
   (
1817
   void
1818
   )
1819
1820
   {
1821
   int status;
1822
   int buffer;
1823
1824
   // Initialize the buffers
1825
   ClearBuffer_DW( MV_MixBuffer[ 0 ], MV_Silence, TotalBufferSize >> 2 );
1826
   for( buffer = 0; buffer < MV_NumberOfBuffers; buffer++ )
1827
      {
1828
      MV_BufferEmpty[ buffer ] = TRUE;
1829
      }
1830
1831
   // Set the mix buffer variables
1832
   MV_MixPage = 1;
1833
1834
   MV_MixFunction = MV_Mix;
1835
1836
    status = DSL_BeginBufferedPlayback( MV_MixBuffer[ 0 ],
1837
            TotalBufferSize, MV_NumberOfBuffers,
1838
            MV_RequestedMixRate, MV_MixMode, MV_ServiceVoc );
1839
1840
    if ( status != DSL_Ok )
1841
       {
1842
       MV_SetErrorCode( MV_BlasterError );
1843
       return( MV_Error );
1844
       }
1845
1846
    MV_MixRate = DSL_GetPlaybackRate();
1847
1848
   return( MV_Ok );
1849
   }
1850
1851
1852
/*---------------------------------------------------------------------
1853
   Function: MV_StopPlayback
1854
1855
   Stops the sound playback engine.
1856
---------------------------------------------------------------------*/
1857
1858
void MV_StopPlayback
1859
   (
1860
   void
1861
   )
1862
1863
   {
1864
   VoiceNode   *voice;
1865
   VoiceNode   *next;
1866
   unsigned    flags;
1867
1868
   DSL_StopPlayback();
1869
1870
   // Make sure all callbacks are done.
1871
   flags = DisableInterrupts();
1872
1873
   for( voice = VoiceList.next; voice != &VoiceList; voice = next )
1874
      {
1875
      next = voice->next;
1876
1877
      MV_StopVoice( voice );
1878
1879
      if ( MV_CallBackFunc )
1880
         {
1881
         MV_CallBackFunc( voice->callbackval );
1882
         }
1883
      }
1884
1885
   RestoreInterrupts( flags );
1886
   }
1887
1888
1889
/*---------------------------------------------------------------------
1890
   Function: MV_StartRecording
1891
1892
   Starts the sound recording engine.
1893
---------------------------------------------------------------------*/
1894
1895
int MV_StartRecording
1896
   (
1897
   int MixRate,
1898
   void ( *function )( char *ptr, int length )
1899
   )
1900
1901
   {
1902
   MV_SetErrorCode( MV_UnsupportedCard );
1903
   return( MV_Error );
1904
   }
1905
1906
1907
/*---------------------------------------------------------------------
1908
   Function: MV_StopRecord
1909
1910
   Stops the sound record engine.
1911
---------------------------------------------------------------------*/
1912
1913
void MV_StopRecord
1914
   (
1915
   void
1916
   )
1917
1918
   {
1919
   }
1920
1921
1922
/*---------------------------------------------------------------------
1923
   Function: MV_StartDemandFeedPlayback
1924
1925
   Plays a digitized sound from a user controlled buffering system.
1926
---------------------------------------------------------------------*/
1927
1928
int MV_StartDemandFeedPlayback
1929
   (
1930
   void ( *function )( char **ptr, unsigned long *length ),
1931
   int rate,
1932
   int pitchoffset,
1933
   int vol,
1934
   int left,
1935
   int right,
1936
   int priority,
1937
   unsigned long callbackval
1938
   )
1939
1940
   {
1941
   VoiceNode *voice;
1942
1943
   if ( !MV_Installed )
1944
      {
1945
      MV_SetErrorCode( MV_NotInstalled );
1946
      return( MV_Error );
1947
      }
1948
1949
   // Request a voice from the voice pool
1950
   voice = MV_AllocVoice( priority );
1951
   if ( voice == NULL )
1952
      {
1953
      MV_SetErrorCode( MV_NoVoices );
1954
      return( MV_Error );
1955
      }
1956
1957
   voice->wavetype    = DemandFeed;
1958
   voice->bits        = 8;
1959
   voice->GetSound    = MV_GetNextDemandFeedBlock;
1960
   voice->NextBlock   = NULL;
1961
   voice->DemandFeed  = function;
1962
   voice->LoopStart   = NULL;
1963
   voice->LoopCount   = 0;
1964
   voice->BlockLength = 0;
1965
   voice->position    = 0;
1966
   voice->sound       = NULL;
1967
   voice->length      = 0;
1968
   voice->BlockLength = 0;
1969
   voice->Playing     = TRUE;
1970
   voice->next        = NULL;
1971
   voice->prev        = NULL;
1972
   voice->priority    = priority;
1973
   voice->callbackval = callbackval;
1974
1975
   MV_SetVoicePitch( voice, rate, pitchoffset );
1976
   MV_SetVoiceVolume( voice, vol, left, right );
1977
   MV_PlayVoice( voice );
1978
1979
   return( voice->handle );
1980
   }
1981
1982
1983
/*---------------------------------------------------------------------
1984
   Function: MV_PlayRaw
1985
1986
   Begin playback of sound data with the given sound levels and
1987
   priority.
1988
---------------------------------------------------------------------*/
1989
1990
int MV_PlayRaw
1991
   (
1992
   char *ptr,
1993
   unsigned long length,
1994
   unsigned rate,
1995
   int   pitchoffset,
1996
   int   vol,
1997
   int   left,
1998
   int   right,
1999
   int   priority,
2000
   unsigned long callbackval
2001
   )
2002
2003
   {
2004
   int status;
2005
2006
   status = MV_PlayLoopedRaw( ptr, length, NULL, NULL, rate, pitchoffset,
2007
      vol, left, right, priority, callbackval );
2008
2009
   return( status );
2010
   }
2011
2012
2013
/*---------------------------------------------------------------------
2014
   Function: MV_PlayLoopedRaw
2015
2016
   Begin playback of sound data with the given sound levels and
2017
   priority.
2018
---------------------------------------------------------------------*/
2019
2020
int MV_PlayLoopedRaw
2021
   (
2022
   char *ptr,
2023
   long length,
2024
   char *loopstart,
2025
   char *loopend,
2026
   unsigned rate,
2027
   int   pitchoffset,
2028
   int   vol,
2029
   int   left,
2030
   int   right,
2031
   int   priority,
2032
   unsigned long callbackval
2033
   )
2034
2035
   {
2036
   VoiceNode *voice;
2037
2038
   if ( !MV_Installed )
2039
      {
2040
      MV_SetErrorCode( MV_NotInstalled );
2041
      return( MV_Error );
2042
      }
2043
2044
   // Request a voice from the voice pool
2045
   voice = MV_AllocVoice( priority );
2046
   if ( voice == NULL )
2047
      {
2048
      MV_SetErrorCode( MV_NoVoices );
2049
      return( MV_Error );
2050
      }
2051
2052
   voice->wavetype    = Raw;
2053
   voice->bits        = 8;
2054
   voice->GetSound    = MV_GetNextRawBlock;
2055
   voice->Playing     = TRUE;
2056
   voice->NextBlock   = ptr;
2057
   voice->position    = 0;
2058
   voice->BlockLength = length;
2059
   voice->length      = 0;
2060
   voice->next        = NULL;
2061
   voice->prev        = NULL;
2062
   voice->priority    = priority;
2063
   voice->callbackval = callbackval;
2064
   voice->LoopStart   = loopstart;
2065
   voice->LoopEnd     = loopend;
2066
   voice->LoopSize    = ( voice->LoopEnd - voice->LoopStart ) + 1;
2067
2068
   MV_SetVoicePitch( voice, rate, pitchoffset );
2069
   MV_SetVoiceVolume( voice, vol, left, right );
2070
   MV_PlayVoice( voice );
2071
2072
   return( voice->handle );
2073
   }
2074
2075
2076
/*---------------------------------------------------------------------
2077
   Function: MV_PlayWAV
2078
2079
   Begin playback of sound data with the given sound levels and
2080
   priority.
2081
---------------------------------------------------------------------*/
2082
2083
int MV_PlayWAV
2084
   (
2085
   char *ptr,
2086
   int   pitchoffset,
2087
   int   vol,
2088
   int   left,
2089
   int   right,
2090
   int   priority,
2091
   unsigned long callbackval
2092
   )
2093
2094
   {
2095
   int status;
2096
2097
   status = MV_PlayLoopedWAV( ptr, -1, -1, pitchoffset, vol, left, right,
2098
      priority, callbackval );
2099
2100
   return( status );
2101
   }
2102
2103
2104
/*---------------------------------------------------------------------
2105
   Function: MV_PlayWAV3D
2106
2107
   Begin playback of sound data at specified angle and distance
2108
   from listener.
2109
---------------------------------------------------------------------*/
2110
2111
int MV_PlayWAV3D
2112
   (
2113
   char *ptr,
2114
   int  pitchoffset,
2115
   int  angle,
2116
   int  distance,
2117
   int  priority,
2118
   unsigned long callbackval
2119
   )
2120
2121
   {
2122
   int left;
2123
   int right;
2124
   int mid;
2125
   int volume;
2126
   int status;
2127
2128
   if ( !MV_Installed )
2129
      {
2130
      MV_SetErrorCode( MV_NotInstalled );
2131
      return( MV_Error );
2132
      }
2133
2134
   if ( distance < 0 )
2135
      {
2136
      distance  = -distance;
2137
      angle    += MV_NumPanPositions / 2;
2138
      }
2139
2140
   volume = MIX_VOLUME( distance );
2141
2142
   // Ensure angle is within 0 - 31
2143
   angle &= MV_MaxPanPosition;
2144
2145
   left  = MV_PanTable[ angle ][ volume ].left;
2146
   right = MV_PanTable[ angle ][ volume ].right;
2147
   mid   = max( 0, 255 - distance );
2148
2149
   status = MV_PlayWAV( ptr, pitchoffset, mid, left, right, priority,
2150
      callbackval );
2151
2152
   return( status );
2153
   }
2154
2155
2156
/*---------------------------------------------------------------------
2157
   Function: MV_PlayLoopedWAV
2158
2159
   Begin playback of sound data with the given sound levels and
2160
   priority.
2161
---------------------------------------------------------------------*/
2162
2163
int MV_PlayLoopedWAV
2164
   (
2165
   char *ptr,
2166
   long  loopstart,
2167
   long  loopend,
2168
   int   pitchoffset,
2169
   int   vol,
2170
   int   left,
2171
   int   right,
2172
   int   priority,
2173
   unsigned long callbackval
2174
   )
2175
2176
   {
2177
   riff_header   *riff;
2178
   format_header *format;
2179
   data_header   *data;
2180
   VoiceNode     *voice;
2181
   int length;
2182
   int absloopend;
2183
   int absloopstart;
2184
2185
   if ( !MV_Installed )
2186
      {
2187
      MV_SetErrorCode( MV_NotInstalled );
2188
      return( MV_Error );
2189
      }
2190
2191
   riff = ( riff_header * )ptr;
2192
2193
   if ( ( strncmp( riff->RIFF, "RIFF", 4 ) != 0 ) ||
2194
      ( strncmp( riff->WAVE, "WAVE", 4 ) != 0 ) ||
2195
      ( strncmp( riff->fmt, "fmt ", 4) != 0 ) )
2196
      {
2197
      MV_SetErrorCode( MV_InvalidWAVFile );
2198
      return( MV_Error );
2199
      }
2200
2201
   format = ( format_header * )( riff + 1 );
2202
   data   = ( data_header * )( ( ( char * )format ) + riff->format_size );
2203
2204
   // Check if it's PCM data.
2205
   if ( format->wFormatTag != 1 )
2206
      {
2207
      MV_SetErrorCode( MV_InvalidWAVFile );
2208
      return( MV_Error );
2209
      }
2210
2211
   if ( format->nChannels != 1 )
2212
      {
2213
      MV_SetErrorCode( MV_InvalidWAVFile );
2214
      return( MV_Error );
2215
      }
2216
2217
   if ( ( format->nBitsPerSample != 8 ) &&
2218
      ( format->nBitsPerSample != 16 ) )
2219
      {
2220
      MV_SetErrorCode( MV_InvalidWAVFile );
2221
      return( MV_Error );
2222
      }
2223
2224
   if ( strncmp( data->DATA, "data", 4 ) != 0 )
2225
      {
2226
      MV_SetErrorCode( MV_InvalidWAVFile );
2227
      return( MV_Error );
2228
      }
2229
2230
   // Request a voice from the voice pool
2231
   voice = MV_AllocVoice( priority );
2232
   if ( voice == NULL )
2233
      {
2234
      MV_SetErrorCode( MV_NoVoices );
2235
      return( MV_Error );
2236
      }
2237
2238
   voice->wavetype    = WAV;
2239
   voice->bits        = format->nBitsPerSample;
2240
   voice->GetSound    = MV_GetNextWAVBlock;
2241
2242
   length = data->size;
2243
   absloopstart = loopstart;
2244
   absloopend   = loopend;
2245
   if ( voice->bits == 16 )
2246
      {
2247
      loopstart  *= 2;
2248
      data->size &= ~1;
2249
      loopend    *= 2;
2250
      length     /= 2;
2251
      }
2252
2253
   loopend    = min( loopend, (long)data->size );
2254
   absloopend = min( absloopend, length );
2255
2256
   voice->Playing     = TRUE;
2257
   voice->DemandFeed  = NULL;
2258
   voice->LoopStart   = NULL;
2259
   voice->LoopCount   = 0;
2260
   voice->position    = 0;
2261
   voice->length      = 0;
2262
   voice->BlockLength = absloopend;
2263
   voice->NextBlock   = ( char * )( data + 1 );
2264
   voice->next        = NULL;
2265
   voice->prev        = NULL;
2266
   voice->priority    = priority;
2267
   voice->callbackval = callbackval;
2268
   voice->LoopStart   = voice->NextBlock + loopstart;
2269
   voice->LoopEnd     = voice->NextBlock + loopend;
2270
   voice->LoopSize    = absloopend - absloopstart;
2271
2272
   if ( ( loopstart >= (long)data->size ) || ( loopstart < 0 ) )
2273
      {
2274
      voice->LoopStart = NULL;
2275
      voice->LoopEnd   = NULL;
2276
      voice->BlockLength = length;
2277
      }
2278
2279
   MV_SetVoicePitch( voice, format->nSamplesPerSec, pitchoffset );
2280
   MV_SetVoiceVolume( voice, vol, left, right );
2281
   MV_PlayVoice( voice );
2282
2283
   return( voice->handle );
2284
   }
2285
2286
2287
/*---------------------------------------------------------------------
2288
   Function: MV_PlayVOC3D
2289
2290
   Begin playback of sound data at specified angle and distance
2291
   from listener.
2292
---------------------------------------------------------------------*/
2293
2294
int MV_PlayVOC3D
2295
   (
2296
   char *ptr,
2297
   int  pitchoffset,
2298
   int  angle,
2299
   int  distance,
2300
   int  priority,
2301
   unsigned long callbackval
2302
   )
2303
2304
   {
2305
   int left;
2306
   int right;
2307
   int mid;
2308
   int volume;
2309
   int status;
2310
2311
   if ( !MV_Installed )
2312
      {
2313
      MV_SetErrorCode( MV_NotInstalled );
2314
      return( MV_Error );
2315
      }
2316
2317
   if ( distance < 0 )
2318
      {
2319
      distance  = -distance;
2320
      angle    += MV_NumPanPositions / 2;
2321
      }
2322
2323
   volume = MIX_VOLUME( distance );
2324
2325
   // Ensure angle is within 0 - 31
2326
   angle &= MV_MaxPanPosition;
2327
2328
   left  = MV_PanTable[ angle ][ volume ].left;
2329
   right = MV_PanTable[ angle ][ volume ].right;
2330
   mid   = max( 0, 255 - distance );
2331
2332
   status = MV_PlayVOC( ptr, pitchoffset, mid, left, right, priority,
2333
      callbackval );
2334
2335
   return( status );
2336
   }
2337
2338
2339
/*---------------------------------------------------------------------
2340
   Function: MV_PlayVOC
2341
2342
   Begin playback of sound data with the given sound levels and
2343
   priority.
2344
---------------------------------------------------------------------*/
2345
2346
int MV_PlayVOC
2347
   (
2348
   char *ptr,
2349
   int   pitchoffset,
2350
   int   vol,
2351
   int   left,
2352
   int   right,
2353
   int   priority,
2354
   unsigned long callbackval
2355
   )
2356
2357
   {
2358
   int status;
2359
2360
   status = MV_PlayLoopedVOC( ptr, -1, -1, pitchoffset, vol, left, right,
2361
      priority, callbackval );
2362
2363
   return( status );
2364
   }
2365
2366
2367
/*---------------------------------------------------------------------
2368
   Function: MV_PlayLoopedVOC
2369
2370
   Begin playback of sound data with the given sound levels and
2371
   priority.
2372
---------------------------------------------------------------------*/
2373
2374
int MV_PlayLoopedVOC
2375
   (
2376
   char *ptr,
2377
   long  loopstart,
2378
   long  loopend,
2379
   int   pitchoffset,
2380
   int   vol,
2381
   int   left,
2382
   int   right,
2383
   int   priority,
2384
   unsigned long callbackval
2385
   )
2386
2387
   {
2388
   VoiceNode   *voice;
2389
   int          status;
2390
   unsigned short nextpos;
2391
2392
   if ( !MV_Installed )
2393
      {
2394
      MV_SetErrorCode( MV_NotInstalled );
2395
      return( MV_Error );
2396
      }
2397
2398
   // Make sure it's a valid VOC file.
2399
   status = strncmp( ptr, "Creative Voice File", 19 );
2400
   if ( status != 0 )
2401
      {
2402
      MV_SetErrorCode( MV_InvalidVOCFile );
2403
      return( MV_Error );
2404
      }
2405
2406
   // Request a voice from the voice pool
2407
   voice = MV_AllocVoice( priority );
2408
   if ( voice == NULL )
2409
      {
2410
      MV_SetErrorCode( MV_NoVoices );
2411
      return( MV_Error );
2412
      }
2413
2414
   voice->wavetype    = VOC;
2415
   voice->bits        = 8;
2416
   voice->GetSound    = MV_GetNextVOCBlock;
2417
2418
   nextpos = *( unsigned short * )( ptr + 0x14 );
2419
   voice->NextBlock   = ptr + BUILDSWAP_INTEL16(nextpos);
2420
2421
   voice->DemandFeed  = NULL;
2422
   voice->LoopStart   = NULL;
2423
   voice->LoopCount   = 0;
2424
   voice->BlockLength = 0;
2425
   voice->PitchScale  = PITCH_GetScale( pitchoffset );
2426
   voice->length      = 0;
2427
   voice->next        = NULL;
2428
   voice->prev        = NULL;
2429
   voice->priority    = priority;
2430
   voice->callbackval = callbackval;
2431
   voice->LoopStart   = ( char * )loopstart;
2432
   voice->LoopEnd     = ( char * )loopend;
2433
   voice->LoopSize    = loopend - loopstart + 1;
2434
2435
   if ( loopstart < 0 )
2436
      {
2437
      voice->LoopStart = NULL;
2438
      voice->LoopEnd   = NULL;
2439
      }
2440
2441
   MV_SetVoiceVolume( voice, vol, left, right );
2442
   MV_PlayVoice( voice );
2443
2444
   return( voice->handle );
2445
   }
2446
2447
2448
/*---------------------------------------------------------------------
2449
   Function: MV_LockEnd
2450
2451
   Used for determining the length of the functions to lock in memory.
2452
---------------------------------------------------------------------*/
2453
2454
static void MV_LockEnd
2455
   (
2456
   void
2457
   )
2458
2459
   {
2460
   }
2461
2462
2463
/*---------------------------------------------------------------------
2464
   Function: MV_CreateVolumeTable
2465
2466
   Create the table used to convert sound data to a specific volume
2467
   level.
2468
---------------------------------------------------------------------*/
2469
2470
void MV_CreateVolumeTable
2471
   (
2472
   int index,
2473
   int volume,
2474
   int MaxVolume
2475
   )
2476
2477
   {
2478
   int val;
2479
   int level;
2480
   int i;
2481
2482
   level = ( volume * MaxVolume ) / MV_MaxTotalVolume;
2483
   if ( MV_Bits == 16 )
2484
      {
2485
      for( i = 0; i < 65536; i += 256 )
2486
         {
2487
         val   = i - 0x8000;
2488
         val  *= level;
2489
         val  /= MV_MaxVolume;
2490
         MV_VolumeTable[ index ][ i / 256 ] = val;
2491
         }
2492
      }
2493
   else
2494
      {
2495
      for( i = 0; i < 256; i++ )
2496
         {
2497
         val   = i - 0x80;
2498
         val  *= level;
2499
         val  /= MV_MaxVolume;
2500
         MV_VolumeTable[ volume ][ i ] = val;
2501
         }
2502
      }
2503
   }
2504
2505
2506
/*---------------------------------------------------------------------
2507
   Function: MV_CalcVolume
2508
2509
   Create the table used to convert sound data to a specific volume
2510
   level.
2511
---------------------------------------------------------------------*/
2512
2513
void MV_CalcVolume
2514
   (
2515
   int MaxVolume
2516
   )
2517
2518
   {
2519
   int volume;
2520
2521
   for( volume = 0; volume < 128; volume++ )
2522
      {
2523
      MV_HarshClipTable[ volume ] = 0;
2524
      MV_HarshClipTable[ volume + 384 ] = 255;
2525
      }
2526
   for( volume = 0; volume < 256; volume++ )
2527
      {
2528
      MV_HarshClipTable[ volume + 128 ] = volume;
2529
      }
2530
2531
   // For each volume level, create a translation table with the
2532
   // appropriate volume calculated.
2533
   for( volume = 0; volume <= MV_MaxVolume; volume++ )
2534
      {
2535
      MV_CreateVolumeTable( volume, volume, MaxVolume );
2536
      }
2537
   }
2538
2539
2540
/*---------------------------------------------------------------------
2541
   Function: MV_CalcPanTable
2542
2543
   Create the table used to determine the stereo volume level of
2544
   a sound located at a specific angle and distance from the listener.
2545
---------------------------------------------------------------------*/
2546
2547
void MV_CalcPanTable
2548
   (
2549
   void
2550
   )
2551
2552
   {
2553
   int   level;
2554
   int   angle;
2555
   int   distance;
2556
   int   HalfAngle;
2557
   int   ramp;
2558
2559
   HalfAngle = ( MV_NumPanPositions / 2 );
2560
2561
   for( distance = 0; distance <= MV_MaxVolume; distance++ )
2562
      {
2563
      level = ( 255 * ( MV_MaxVolume - distance ) ) / MV_MaxVolume;
2564
      for( angle = 0; angle <= HalfAngle / 2; angle++ )
2565
         {
2566
         ramp = level - ( ( level * angle ) /
2567
            ( MV_NumPanPositions / 4 ) );
2568
2569
         MV_PanTable[ angle ][ distance ].left = ramp;
2570
         MV_PanTable[ HalfAngle - angle ][ distance ].left = ramp;
2571
         MV_PanTable[ HalfAngle + angle ][ distance ].left = level;
2572
         MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].left = level;
2573
2574
         MV_PanTable[ angle ][ distance ].right = level;
2575
         MV_PanTable[ HalfAngle - angle ][ distance ].right = level;
2576
         MV_PanTable[ HalfAngle + angle ][ distance ].right = ramp;
2577
         MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].right = ramp;
2578
         }
2579
      }
2580
   }
2581
2582
2583
/*---------------------------------------------------------------------
2584
   Function: MV_SetVolume
2585
2586
   Sets the volume of digitized sound playback.
2587
---------------------------------------------------------------------*/
2588
2589
void MV_SetVolume
2590
   (
2591
   int volume
2592
   )
2593
2594
   {
2595
   volume = max( 0, volume );
2596
   volume = min( volume, MV_MaxTotalVolume );
2597
2598
   MV_TotalVolume = volume;
2599
2600
   // Calculate volume table
2601
   MV_CalcVolume( volume );
2602
   }
2603
2604
2605
/*---------------------------------------------------------------------
2606
   Function: MV_GetVolume
2607
2608
   Returns the volume of digitized sound playback.
2609
---------------------------------------------------------------------*/
2610
2611
int MV_GetVolume
2612
   (
2613
   void
2614
   )
2615
2616
   {
2617
   return( MV_TotalVolume );
2618
   }
2619
2620
2621
/*---------------------------------------------------------------------
2622
   Function: MV_SetCallBack
2623
2624
   Set the function to call when a voice stops.
2625
---------------------------------------------------------------------*/
2626
2627
void MV_SetCallBack
2628
   (
2629
   void ( *function )( unsigned long )
2630
   )
2631
2632
   {
2633
   MV_CallBackFunc = function;
2634
   }
2635
2636
2637
/*---------------------------------------------------------------------
2638
   Function: MV_SetReverseStereo
2639
2640
   Set the orientation of the left and right channels.
2641
---------------------------------------------------------------------*/
2642
2643
void MV_SetReverseStereo
2644
   (
2645
   int setting
2646
   )
2647
2648
   {
2649
   MV_SwapLeftRight = setting;
2650
   }
2651
2652
2653
/*---------------------------------------------------------------------
2654
   Function: MV_GetReverseStereo
2655
2656
   Returns the orientation of the left and right channels.
2657
---------------------------------------------------------------------*/
2658
2659
int MV_GetReverseStereo
2660
   (
2661
   void
2662
   )
2663
2664
   {
2665
   return( MV_SwapLeftRight );
2666
   }
2667
2668
2669
/*---------------------------------------------------------------------
2670
   Function: MV_TestPlayback
2671
2672
   Checks if playback has started.
2673
---------------------------------------------------------------------*/
2674
2675
int MV_TestPlayback(void)
2676
   {
2677
   return MV_Ok;
2678
   }
2679
2680
2681
/*---------------------------------------------------------------------
2682
   Function: MV_Init
2683
2684
   Perform the initialization of variables and memory used by
2685
   Multivoc.
2686
---------------------------------------------------------------------*/
2687
2688
int MV_Init
2689
   (
2690
   int soundcard,
2691
   int MixRate,
2692
   int Voices,
2693
   int numchannels,
2694
   int samplebits
2695
   )
2696
2697
   {
2698
   char *ptr;
2699
   int  status;
2700
   int  buffer;
2701
   int  index;
2702
2703
   if ( MV_Installed )
2704
      {
2705
      MV_Shutdown();
2706
      }
2707
2708
   MV_SetErrorCode( MV_Ok );
2709
2710
   MV_TotalMemory = Voices * sizeof( VoiceNode ) + sizeof( HARSH_CLIP_TABLE_8 );
2711
   status = USRHOOKS_GetMem( ( void ** )&ptr, MV_TotalMemory );
2712
   if ( status != USRHOOKS_Ok )
2713
      {
2714
      MV_SetErrorCode( MV_NoMem );
2715
      return( MV_Error );
2716
      }
2717
2718
   MV_Voices = ( VoiceNode * )ptr;
2719
   MV_HarshClipTable = ptr + ( MV_TotalMemory - sizeof( HARSH_CLIP_TABLE_8 ) );
2720
2721
   // Set number of voices before calculating volume table
2722
   MV_MaxVoices = Voices;
2723
2724
   LL_Reset( (VoiceNode *)&VoiceList, next, prev );
2725
   LL_Reset( (VoiceNode *)&VoicePool, next, prev );
2726
2727
   for( index = 0; index < Voices; index++ )
2728
      {
2729
      LL_Add( (VoiceNode *)&VoicePool, &MV_Voices[ index ], next, prev );
2730
      }
2731
2732
   // Allocate mix buffer within 1st megabyte
2733
   status = DPMI_GetDOSMemory( ( void ** )&ptr, &MV_BufferDescriptor,
2734
      2 * TotalBufferSize );
2735
2736
   if ( status )
2737
      {
2738
      USRHOOKS_FreeMem( MV_Voices );
2739
      MV_Voices      = NULL;
2740
      MV_TotalMemory = 0;
2741
2742
      MV_SetErrorCode( MV_NoMem );
2743
      return( MV_Error );
2744
      }
2745
2746
   MV_SetReverseStereo( FALSE );
2747
2748
   // Initialize the sound card
2749
   status = DSL_Init();
2750
   if ( status != DSL_Ok )
2751
      {
2752
      MV_SetErrorCode( MV_BlasterError );
2753
      }
2754
2755
   if ( MV_ErrorCode != MV_Ok )
2756
      {
2757
      status = MV_ErrorCode;
2758
2759
      USRHOOKS_FreeMem( MV_Voices );
2760
      MV_Voices      = NULL;
2761
      MV_TotalMemory = 0;
2762
2763
      DPMI_FreeDOSMemory( MV_BufferDescriptor );
2764
2765
      MV_SetErrorCode( status );
2766
      return( MV_Error );
2767
      }
2768
2769
   MV_SoundCard    = soundcard;
2770
   MV_Installed    = TRUE;
2771
   MV_CallBackFunc = NULL;
2772
   MV_RecordFunc   = NULL;
2773
   MV_Recording    = FALSE;
2774
   MV_ReverbLevel  = 0;
2775
   MV_ReverbTable  = NULL;
2776
2777
   // Set the sampling rate
2778
   MV_RequestedMixRate = MixRate;
2779
2780
   // Set Mixer to play stereo digitized sound
2781
   MV_SetMixMode( numchannels, samplebits );
2782
   MV_ReverbDelay = MV_BufferSize * 3;
2783
2784
   MV_MixBuffer[ MV_NumberOfBuffers ] = ptr;
2785
   for( buffer = 0; buffer < MV_NumberOfBuffers; buffer++ )
2786
      {
2787
      MV_MixBuffer[ buffer ] = ptr;
2788
      ptr += MV_BufferSize;
2789
      }
2790
2791
   // Calculate pan table
2792
   MV_CalcPanTable();
2793
2794
   MV_SetVolume( MV_MaxTotalVolume );
2795
2796
   // Start the playback engine
2797
   status = MV_StartPlayback();
2798
   if ( status != MV_Ok )
2799
      {
2800
      // Preserve error code while we shutdown.
2801
      status = MV_ErrorCode;
2802
      MV_Shutdown();
2803
      MV_SetErrorCode( status );
2804
      return( MV_Error );
2805
      }
2806
2807
   if ( MV_TestPlayback() != MV_Ok )
2808
      {
2809
      status = MV_ErrorCode;
2810
      MV_Shutdown();
2811
      MV_SetErrorCode( status );
2812
      return( MV_Error );
2813
      }
2814
2815
   return( MV_Ok );
2816
   }
2817
2818
2819
/*---------------------------------------------------------------------
2820
   Function: MV_Shutdown
2821
2822
   Restore any resources allocated by Multivoc back to the system.
2823
---------------------------------------------------------------------*/
2824
2825
int MV_Shutdown
2826
   (
2827
   void
2828
   )
2829
2830
   {
2831
   int      buffer;
2832
   unsigned flags;
2833
2834
   if ( !MV_Installed )
2835
      {
2836
      return( MV_Ok );
2837
      }
2838
2839
   flags = DisableInterrupts();
2840
2841
   MV_KillAllVoices();
2842
2843
   MV_Installed = FALSE;
2844
2845
   // Stop the sound recording engine
2846
   if ( MV_Recording )
2847
      {
2848
      MV_StopRecord();
2849
      }
2850
2851
   // Stop the sound playback engine
2852
   MV_StopPlayback();
2853
2854
   // Shutdown the sound card
2855
   DSL_Shutdown();
2856
2857
   RestoreInterrupts( flags );
2858
2859
   // Free any voices we allocated
2860
   USRHOOKS_FreeMem( MV_Voices );
2861
   MV_Voices      = NULL;
2862
   MV_TotalMemory = 0;
2863
2864
   LL_Reset( (VoiceNode *)&VoiceList, next, prev );
2865
   LL_Reset( (VoiceNode *)&VoicePool, next, prev );
2866
2867
   MV_MaxVoices = 1;
2868
2869
   // Release the descriptor from our mix buffer
2870
   DPMI_FreeDOSMemory( MV_BufferDescriptor );
2871
   for( buffer = 0; buffer < NumberOfBuffers; buffer++ )
2872
      {
2873
      MV_MixBuffer[ buffer ] = NULL;
2874
      }
2875
2876
   return( MV_Ok );
2877
   }
(-)jfduke3d_src_20051009.orig/source/jaudiolib/util.h (+12 lines)
Line 0 Link Here
1
#ifndef AUDIOLIB__UTIL_H
2
#define AUDIOLIB__UTIL_H
3
4
#ifndef min
5
#define min(a, b)  ((a) < (b) ? (a) : (b))
6
#endif
7
8
#ifndef max
9
#define max(a, b)  ((a) > (b) ? (a) : (b))
10
#endif
11
12
#endif
(-)jfduke3d_src_20051009.orig/source/player.c (-2 / +5 lines)
Lines 1974-1981 Link Here
1974
        info.dz = 0;
1974
        info.dz = 0;
1975
    }
1975
    }
1976
1976
1977
    svel -= info.dx;
1977
    if (!running) svel -= (info.dx / 8);
1978
    vel = -info.dz>>6;
1978
    else svel -= (info.dx / 4);
1979
    vel = -info.dz>>6;
1980
    if (!running) vel -= (info.dpitch / 8);
1981
    else vel -= (info.dpitch / 4);
1979
1982
1980
    if (running)
1983
    if (running)
1981
    {
1984
    {
(-)jfduke3d_src_20051009.orig/source/sounds.c (+10 lines)
Lines 209-214 Link Here
209
209
210
void playmusic(char *fn)
210
void playmusic(char *fn)
211
{
211
{
212
#ifdef WINDOWS
212
    short      fp;
213
    short      fp;
213
    long        l;
214
    long        l;
214
215
Lines 229-234 Link Here
229
    kread( fp, MusicPtr, l);
230
    kread( fp, MusicPtr, l);
230
    kclose( fp );
231
    kclose( fp );
231
    MUSIC_PlaySong( MusicPtr, MUSIC_LoopSong );
232
    MUSIC_PlaySong( MusicPtr, MUSIC_LoopSong );
233
#else
234
    void PlayMusic(char *_filename);
235
    if(MusicToggle == 0) return;
236
    if(MusicDevice < 0) return;
237
238
     // FIXME: I need this to get the music volume initialized (not sure why) -- Jim Bentler
239
    MUSIC_SetVolume( MusicVolume );
240
    PlayMusic(fn);
241
#endif
232
}
242
}
233
243
234
char loadsound(unsigned short num)
244
char loadsound(unsigned short num)

Return to bug 87685