~and471/ubuntu/maverick/frozen-bubble/fix-599809

« back to all changes in this revision

Viewing changes to SDL_mixer_patched/mikmod/virtch_common.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2004-07-08 17:22:16 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040708172216-4e9erxuhsq7djmnd
Tags: 1.0.0-6
c_stuff/lib/FBLE.pm: fix to deal with new SDL_perl (closes: #257749).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*      MikMod sound library
2
 
        (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for
3
 
        complete list.
4
 
 
5
 
        This library is free software; you can redistribute it and/or modify
6
 
        it under the terms of the GNU Library General Public License as
7
 
        published by the Free Software Foundation; either version 2 of
8
 
        the License, or (at your option) any later version.
9
 
 
10
 
        This program is distributed in the hope that it will be useful,
11
 
        but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
        GNU Library General Public License for more details.
14
 
 
15
 
        You should have received a copy of the GNU Library General Public
16
 
        License along with this library; if not, write to the Free Software
17
 
        Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18
 
        02111-1307, USA.
19
 
*/
20
 
 
21
 
/*==============================================================================
22
 
 
23
 
  $Id: virtch_common.c,v 1.2 2001/12/17 02:39:12 slouken Exp $
24
 
 
25
 
  Common source parts between the two software mixers.
26
 
  This file is probably the ugliest part of libmikmod...
27
 
 
28
 
==============================================================================*/
29
 
 
30
 
#ifndef _IN_VIRTCH_
31
 
 
32
 
#include "mikmod_internals.h"
33
 
 
34
 
extern BOOL  VC1_Init(void);
35
 
extern BOOL  VC2_Init(void);
36
 
static BOOL (*VC_Init_ptr)(void)=VC1_Init;
37
 
extern void  VC1_Exit(void);
38
 
extern void  VC2_Exit(void);
39
 
static void (*VC_Exit_ptr)(void)=VC1_Exit;
40
 
extern BOOL  VC1_SetNumVoices(void);
41
 
extern BOOL  VC2_SetNumVoices(void);
42
 
static BOOL (*VC_SetNumVoices_ptr)(void);
43
 
extern ULONG VC1_SampleSpace(int);
44
 
extern ULONG VC2_SampleSpace(int);
45
 
static ULONG (*VC_SampleSpace_ptr)(int);
46
 
extern ULONG VC1_SampleLength(int,SAMPLE*);
47
 
extern ULONG VC2_SampleLength(int,SAMPLE*);
48
 
static ULONG (*VC_SampleLength_ptr)(int,SAMPLE*);
49
 
 
50
 
extern BOOL  VC1_PlayStart(void);
51
 
extern BOOL  VC2_PlayStart(void);
52
 
static BOOL (*VC_PlayStart_ptr)(void);
53
 
extern void  VC1_PlayStop(void);
54
 
extern void  VC2_PlayStop(void);
55
 
static void (*VC_PlayStop_ptr)(void);
56
 
 
57
 
extern SWORD VC1_SampleLoad(struct SAMPLOAD*,int);
58
 
extern SWORD VC2_SampleLoad(struct SAMPLOAD*,int);
59
 
static SWORD (*VC_SampleLoad_ptr)(struct SAMPLOAD*,int);
60
 
extern void  VC1_SampleUnload(SWORD);
61
 
extern void  VC2_SampleUnload(SWORD);
62
 
static void (*VC_SampleUnload_ptr)(SWORD);
63
 
 
64
 
extern ULONG VC1_WriteBytes(SBYTE*,ULONG);
65
 
extern ULONG VC2_WriteBytes(SBYTE*,ULONG);
66
 
static ULONG (*VC_WriteBytes_ptr)(SBYTE*,ULONG);
67
 
extern ULONG VC1_SilenceBytes(SBYTE*,ULONG);
68
 
extern ULONG VC2_SilenceBytes(SBYTE*,ULONG);
69
 
static ULONG (*VC_SilenceBytes_ptr)(SBYTE*,ULONG);
70
 
 
71
 
extern void  VC1_VoiceSetVolume(UBYTE,UWORD);
72
 
extern void  VC2_VoiceSetVolume(UBYTE,UWORD);
73
 
static void (*VC_VoiceSetVolume_ptr)(UBYTE,UWORD);
74
 
extern UWORD VC1_VoiceGetVolume(UBYTE);
75
 
extern UWORD VC2_VoiceGetVolume(UBYTE);
76
 
static UWORD (*VC_VoiceGetVolume_ptr)(UBYTE);
77
 
extern void  VC1_VoiceSetFrequency(UBYTE,ULONG);
78
 
extern void  VC2_VoiceSetFrequency(UBYTE,ULONG);
79
 
static void (*VC_VoiceSetFrequency_ptr)(UBYTE,ULONG);
80
 
extern ULONG VC1_VoiceGetFrequency(UBYTE);
81
 
extern ULONG VC2_VoiceGetFrequency(UBYTE);
82
 
static ULONG (*VC_VoiceGetFrequency_ptr)(UBYTE);
83
 
extern void  VC1_VoiceSetPanning(UBYTE,ULONG);
84
 
extern void  VC2_VoiceSetPanning(UBYTE,ULONG);
85
 
static void (*VC_VoiceSetPanning_ptr)(UBYTE,ULONG);
86
 
extern ULONG VC1_VoiceGetPanning(UBYTE);
87
 
extern ULONG VC2_VoiceGetPanning(UBYTE);
88
 
static ULONG (*VC_VoiceGetPanning_ptr)(UBYTE);
89
 
extern void  VC1_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
90
 
extern void  VC2_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
91
 
static void (*VC_VoicePlay_ptr)(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD);
92
 
 
93
 
extern void  VC1_VoiceStop(UBYTE);
94
 
extern void  VC2_VoiceStop(UBYTE);
95
 
static void (*VC_VoiceStop_ptr)(UBYTE);
96
 
extern BOOL  VC1_VoiceStopped(UBYTE);
97
 
extern BOOL  VC2_VoiceStopped(UBYTE);
98
 
static BOOL (*VC_VoiceStopped_ptr)(UBYTE);
99
 
extern SLONG VC1_VoiceGetPosition(UBYTE);
100
 
extern SLONG VC2_VoiceGetPosition(UBYTE);
101
 
static SLONG (*VC_VoiceGetPosition_ptr)(UBYTE);
102
 
extern ULONG VC1_VoiceRealVolume(UBYTE);
103
 
extern ULONG VC2_VoiceRealVolume(UBYTE);
104
 
static ULONG (*VC_VoiceRealVolume_ptr)(UBYTE);
105
 
 
106
 
#ifdef __STDC__
107
 
#define VC_PROC0(suffix) \
108
 
void VC_##suffix (void) { VC_##suffix##_ptr(); }
109
 
 
110
 
#define VC_FUNC0(suffix,ret) \
111
 
ret VC_##suffix (void) { return VC_##suffix##_ptr(); }
112
 
 
113
 
#define VC_PROC1(suffix,typ1) \
114
 
void VC_##suffix (typ1 a) { VC_##suffix##_ptr(a); }
115
 
 
116
 
#define VC_FUNC1(suffix,ret,typ1) \
117
 
ret VC_##suffix (typ1 a) { return VC_##suffix##_ptr(a); }
118
 
 
119
 
#define VC_PROC2(suffix,typ1,typ2) \
120
 
void VC_##suffix (typ1 a,typ2 b) { VC_##suffix##_ptr(a,b); }
121
 
 
122
 
#define VC_FUNC2(suffix,ret,typ1,typ2) \
123
 
ret VC_##suffix (typ1 a,typ2 b) { return VC_##suffix##_ptr(a,b); }
124
 
#else
125
 
#define VC_PROC0(suffix) \
126
 
void VC_/**/suffix/**/(void) { VC_/**/suffix/**/_ptr(); }
127
 
 
128
 
#define VC_FUNC0(suffix,ret) \
129
 
ret VC_/**/suffix/**/(void) { return VC_/**/suffix/**/_ptr(); }
130
 
 
131
 
#define VC_PROC1(suffix,typ1) \
132
 
void VC_/**/suffix/**/(typ1 a) { VC_/**/suffix/**/_ptr(a); }
133
 
 
134
 
#define VC_FUNC1(suffix,ret,typ1) \
135
 
ret VC_/**/suffix/**/(typ1 a) { return VC_/**/suffix/**/_ptr(a); }
136
 
 
137
 
#define VC_PROC2(suffix,typ1,typ2) \
138
 
void VC_/**/suffix/**/(typ1 a,typ2 b) { VC_/**/suffix/**/_ptr(a,b); }
139
 
 
140
 
#define VC_FUNC2(suffix,ret,typ1,typ2) \
141
 
ret VC_/**/suffix/**/(typ1 a,typ2 b) { return VC_/**/suffix/**/_ptr(a,b); }
142
 
#endif
143
 
 
144
 
VC_FUNC0(Init,BOOL);
145
 
VC_PROC0(Exit)
146
 
VC_FUNC0(SetNumVoices,BOOL)
147
 
VC_FUNC1(SampleSpace,ULONG,int)
148
 
VC_FUNC2(SampleLength,ULONG,int,SAMPLE*)
149
 
VC_FUNC0(PlayStart,BOOL)
150
 
VC_PROC0(PlayStop)
151
 
VC_FUNC2(SampleLoad,SWORD,struct SAMPLOAD*,int)
152
 
VC_PROC1(SampleUnload,SWORD)
153
 
VC_FUNC2(WriteBytes,ULONG,SBYTE*,ULONG)
154
 
VC_FUNC2(SilenceBytes,ULONG,SBYTE*,ULONG)
155
 
VC_PROC2(VoiceSetVolume,UBYTE,UWORD)
156
 
VC_FUNC1(VoiceGetVolume,UWORD,UBYTE)
157
 
VC_PROC2(VoiceSetFrequency,UBYTE,ULONG)
158
 
VC_FUNC1(VoiceGetFrequency,ULONG,UBYTE)
159
 
VC_PROC2(VoiceSetPanning,UBYTE,ULONG)
160
 
VC_FUNC1(VoiceGetPanning,ULONG,UBYTE)
161
 
 
162
 
void  VC_VoicePlay(UBYTE a,SWORD b,ULONG c,ULONG d,ULONG e,ULONG f,UWORD g)
163
 
{ VC_VoicePlay_ptr(a,b,c,d,e,f,g); }
164
 
 
165
 
VC_PROC1(VoiceStop,UBYTE)
166
 
VC_FUNC1(VoiceStopped,BOOL,UBYTE)
167
 
VC_FUNC1(VoiceGetPosition,SLONG,UBYTE)
168
 
VC_FUNC1(VoiceRealVolume,ULONG,UBYTE)
169
 
 
170
 
void VC_SetupPointers(void)
171
 
{
172
 
        if (md_mode&DMODE_HQMIXER) {
173
 
                VC_Init_ptr=VC2_Init;
174
 
                VC_Exit_ptr=VC2_Exit;
175
 
                VC_SetNumVoices_ptr=VC2_SetNumVoices;
176
 
                VC_SampleSpace_ptr=VC2_SampleSpace;
177
 
                VC_SampleLength_ptr=VC2_SampleLength;
178
 
                VC_PlayStart_ptr=VC2_PlayStart;
179
 
                VC_PlayStop_ptr=VC2_PlayStop;
180
 
                VC_SampleLoad_ptr=VC2_SampleLoad;
181
 
                VC_SampleUnload_ptr=VC2_SampleUnload;
182
 
                VC_WriteBytes_ptr=VC2_WriteBytes;
183
 
                VC_SilenceBytes_ptr=VC2_SilenceBytes;
184
 
                VC_VoiceSetVolume_ptr=VC2_VoiceSetVolume;
185
 
                VC_VoiceGetVolume_ptr=VC2_VoiceGetVolume;
186
 
                VC_VoiceSetFrequency_ptr=VC2_VoiceSetFrequency;
187
 
                VC_VoiceGetFrequency_ptr=VC2_VoiceGetFrequency;
188
 
                VC_VoiceSetPanning_ptr=VC2_VoiceSetPanning;
189
 
                VC_VoiceGetPanning_ptr=VC2_VoiceGetPanning;
190
 
                VC_VoicePlay_ptr=VC2_VoicePlay;
191
 
                VC_VoiceStop_ptr=VC2_VoiceStop;
192
 
                VC_VoiceStopped_ptr=VC2_VoiceStopped;
193
 
                VC_VoiceGetPosition_ptr=VC2_VoiceGetPosition;
194
 
                VC_VoiceRealVolume_ptr=VC2_VoiceRealVolume;
195
 
        } else {
196
 
                VC_Init_ptr=VC1_Init;
197
 
                VC_Exit_ptr=VC1_Exit;
198
 
                VC_SetNumVoices_ptr=VC1_SetNumVoices;
199
 
                VC_SampleSpace_ptr=VC1_SampleSpace;
200
 
                VC_SampleLength_ptr=VC1_SampleLength;
201
 
                VC_PlayStart_ptr=VC1_PlayStart;
202
 
                VC_PlayStop_ptr=VC1_PlayStop;
203
 
                VC_SampleLoad_ptr=VC1_SampleLoad;
204
 
                VC_SampleUnload_ptr=VC1_SampleUnload;
205
 
                VC_WriteBytes_ptr=VC1_WriteBytes;
206
 
                VC_SilenceBytes_ptr=VC1_SilenceBytes;
207
 
                VC_VoiceSetVolume_ptr=VC1_VoiceSetVolume;
208
 
                VC_VoiceGetVolume_ptr=VC1_VoiceGetVolume;
209
 
                VC_VoiceSetFrequency_ptr=VC1_VoiceSetFrequency;
210
 
                VC_VoiceGetFrequency_ptr=VC1_VoiceGetFrequency;
211
 
                VC_VoiceSetPanning_ptr=VC1_VoiceSetPanning;
212
 
                VC_VoiceGetPanning_ptr=VC1_VoiceGetPanning;
213
 
                VC_VoicePlay_ptr=VC1_VoicePlay;
214
 
                VC_VoiceStop_ptr=VC1_VoiceStop;
215
 
                VC_VoiceStopped_ptr=VC1_VoiceStopped;
216
 
                VC_VoiceGetPosition_ptr=VC1_VoiceGetPosition;
217
 
                VC_VoiceRealVolume_ptr=VC1_VoiceRealVolume;
218
 
        }
219
 
}
220
 
 
221
 
#else
222
 
 
223
 
#ifndef _VIRTCH_COMMON_
224
 
#define _VIRTCH_COMMON_
225
 
 
226
 
static ULONG samples2bytes(ULONG samples)
227
 
{
228
 
        if(vc_mode & DMODE_16BITS) samples <<= 1;
229
 
        if(vc_mode & DMODE_STEREO) samples <<= 1;
230
 
        return samples;
231
 
}
232
 
 
233
 
static ULONG bytes2samples(ULONG bytes)
234
 
{
235
 
        if(vc_mode & DMODE_16BITS) bytes >>= 1;
236
 
        if(vc_mode & DMODE_STEREO) bytes >>= 1;
237
 
        return bytes;
238
 
}
239
 
 
240
 
/* Fill the buffer with 'todo' bytes of silence (it depends on the mixing mode
241
 
   how the buffer is filled) */
242
 
ULONG VC1_SilenceBytes(SBYTE* buf,ULONG todo)
243
 
{
244
 
        todo=samples2bytes(bytes2samples(todo));
245
 
 
246
 
        /* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */
247
 
        if(vc_mode & DMODE_16BITS)
248
 
                memset(buf,0,todo);
249
 
        else
250
 
                memset(buf,0x80,todo);
251
 
 
252
 
        return todo;
253
 
}
254
 
 
255
 
void VC1_WriteSamples(SBYTE*,ULONG);
256
 
 
257
 
/* Writes 'todo' mixed SBYTES (!!) to 'buf'. It returns the number of SBYTES
258
 
   actually written to 'buf' (which is rounded to number of samples that fit
259
 
   into 'todo' bytes). */
260
 
ULONG VC1_WriteBytes(SBYTE* buf,ULONG todo)
261
 
{
262
 
        if(!vc_softchn)
263
 
                return VC1_SilenceBytes(buf,todo);
264
 
 
265
 
        todo = bytes2samples(todo);
266
 
        VC1_WriteSamples(buf,todo);
267
 
 
268
 
        return samples2bytes(todo);
269
 
}
270
 
 
271
 
void VC1_Exit(void)
272
 
{
273
 
        if(vc_tickbuf) free(vc_tickbuf);
274
 
        if(vinf) free(vinf);
275
 
        if(Samples) free(Samples);
276
 
 
277
 
        vc_tickbuf = NULL;
278
 
        vinf = NULL;
279
 
        Samples = NULL;
280
 
 
281
 
        VC_SetupPointers();
282
 
}
283
 
 
284
 
UWORD VC1_VoiceGetVolume(UBYTE voice)
285
 
{
286
 
        return vinf[voice].vol;
287
 
}
288
 
 
289
 
ULONG VC1_VoiceGetPanning(UBYTE voice)
290
 
{
291
 
        return vinf[voice].pan;
292
 
}
293
 
 
294
 
void VC1_VoiceSetFrequency(UBYTE voice,ULONG frq)
295
 
{
296
 
        vinf[voice].frq=frq;
297
 
}
298
 
 
299
 
ULONG VC1_VoiceGetFrequency(UBYTE voice)
300
 
{
301
 
        return vinf[voice].frq;
302
 
}
303
 
 
304
 
void VC1_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags)
305
 
{
306
 
        vinf[voice].flags    = flags;
307
 
        vinf[voice].handle   = handle;
308
 
        vinf[voice].start    = start;
309
 
        vinf[voice].size     = size;
310
 
        vinf[voice].reppos   = reppos;
311
 
        vinf[voice].repend   = repend;
312
 
        vinf[voice].kick     = 1;
313
 
}
314
 
 
315
 
void VC1_VoiceStop(UBYTE voice)
316
 
{
317
 
        vinf[voice].active = 0;
318
 
}
319
 
 
320
 
BOOL VC1_VoiceStopped(UBYTE voice)
321
 
{
322
 
        return(vinf[voice].active==0);
323
 
}
324
 
 
325
 
SLONG VC1_VoiceGetPosition(UBYTE voice)
326
 
{
327
 
        return(vinf[voice].current>>FRACBITS);
328
 
}
329
 
 
330
 
void VC1_VoiceSetVolume(UBYTE voice,UWORD vol)
331
 
{
332
 
        /* protect against clicks if volume variation is too high */
333
 
        if(abs((int)vinf[voice].vol-(int)vol)>32)
334
 
                vinf[voice].rampvol=CLICK_BUFFER;
335
 
        vinf[voice].vol=vol;
336
 
}
337
 
 
338
 
void VC1_VoiceSetPanning(UBYTE voice,ULONG pan)
339
 
{
340
 
        /* protect against clicks if panning variation is too high */
341
 
        if(abs((int)vinf[voice].pan-(int)pan)>48)
342
 
                vinf[voice].rampvol=CLICK_BUFFER;
343
 
        vinf[voice].pan=pan;
344
 
}
345
 
 
346
 
/*========== External mixer interface */
347
 
 
348
 
void VC1_SampleUnload(SWORD handle)
349
 
{
350
 
        if (handle<MAXSAMPLEHANDLES) {
351
 
                if (Samples[handle])
352
 
                        free(Samples[handle]);
353
 
                Samples[handle]=NULL;
354
 
        }
355
 
}
356
 
 
357
 
SWORD VC1_SampleLoad(struct SAMPLOAD* sload,int type)
358
 
{
359
 
        SAMPLE *s = sload->sample;
360
 
        int handle;
361
 
        ULONG t, length,loopstart,loopend;
362
 
 
363
 
        if(type==MD_HARDWARE) return -1;
364
 
 
365
 
        /* Find empty slot to put sample address in */
366
 
        for(handle=0;handle<MAXSAMPLEHANDLES;handle++)
367
 
                if(!Samples[handle]) break;
368
 
 
369
 
        if(handle==MAXSAMPLEHANDLES) {
370
 
                _mm_errno = MMERR_OUT_OF_HANDLES;
371
 
                return -1;
372
 
        }
373
 
 
374
 
        length    = s->length;
375
 
        loopstart = s->loopstart;
376
 
        loopend   = s->loopend;
377
 
 
378
 
        SL_SampleSigned(sload);
379
 
        SL_Sample8to16(sload);
380
 
 
381
 
        if(!(Samples[handle]=(SWORD*)_mm_malloc((length+20)<<1))) {
382
 
                _mm_errno = MMERR_SAMPLE_TOO_BIG;
383
 
                return -1;
384
 
        }
385
 
 
386
 
        /* read sample into buffer */
387
 
        if (SL_Load(Samples[handle],sload,length))
388
 
                return -1;
389
 
 
390
 
        /* Unclick sample */
391
 
        if(s->flags & SF_LOOP) {
392
 
                if(s->flags & SF_BIDI)
393
 
                        for(t=0;t<16;t++)
394
 
                                Samples[handle][loopend+t]=Samples[handle][(loopend-t)-1];
395
 
                else
396
 
                        for(t=0;t<16;t++)
397
 
                                Samples[handle][loopend+t]=Samples[handle][t+loopstart];
398
 
        } else
399
 
                for(t=0;t<16;t++)
400
 
                        Samples[handle][t+length]=0;
401
 
 
402
 
        return handle;
403
 
}
404
 
 
405
 
ULONG VC1_SampleSpace(int type)
406
 
{
407
 
        return vc_memory;
408
 
}
409
 
 
410
 
ULONG VC1_SampleLength(int type,SAMPLE* s)
411
 
{
412
 
        if (!s) return 0;
413
 
 
414
 
        return (s->length*((s->flags&SF_16BITS)?2:1))+16;
415
 
}
416
 
 
417
 
ULONG VC1_VoiceRealVolume(UBYTE voice)
418
 
{
419
 
        ULONG i,s,size;
420
 
        int k,j;
421
 
        SWORD *smp;
422
 
        SLONG t;
423
 
 
424
 
        t = vinf[voice].current>>FRACBITS;
425
 
        if(!vinf[voice].active) return 0;
426
 
 
427
 
        s = vinf[voice].handle;
428
 
        size = vinf[voice].size;
429
 
 
430
 
        i=64; t-=64; k=0; j=0;
431
 
        if(i>size) i = size;
432
 
        if(t<0) t = 0;
433
 
        if(t+i > size) t = size-i;
434
 
 
435
 
        i &= ~1;  /* make sure it's EVEN. */
436
 
 
437
 
        smp = &Samples[s][t];
438
 
        for(;i;i--,smp++) {
439
 
                if(k<*smp) k = *smp;
440
 
                if(j>*smp) j = *smp;
441
 
        }
442
 
        return abs(k-j);
443
 
}
444
 
 
445
 
#endif
446
 
 
447
 
#endif
448
 
 
449
 
/* ex:set ts=4: */