comparison playercode/virtch2.c @ 4:5d614bcc4287

Initial entry of mikmod into the CVS tree.
author darius
date Fri, 23 Jan 1998 16:05:08 +0000
parents
children
comparison
equal deleted inserted replaced
3:71e20a32bd84 4:5d614bcc4287
1 /*
2
3 Name: VIRTCH2.C
4
5 Description:
6 All-c sample mixing routines, using a 32 bits mixing buffer, interpolation,
7 and sample smoothing [improves sound quality and removes clicks].
8
9 Future Additions:
10 Low-Pass filter to remove annoying staticy buzz.
11
12
13 C Mixer Portability:
14 All Systems -- All compilers.
15
16 Assembly Mixer Portability:
17
18 MSDOS: BC(?) Watcom(y) DJGPP(y)
19 Win95: ?
20 Os2: ?
21 Linux: y
22
23 (y) - yes
24 (n) - no (not possible or not useful)
25 (?) - may be possible, but not tested
26
27 */
28
29 #include <stddef.h>
30 #include <string.h>
31 #include "mikmod.h"
32
33
34 // REVERBERATION : Larger numbers result in shorter reverb duration.
35 // Longer reverb durations can cause unwanted static and make the
36 // reverb sound more like an echo.
37
38 #define REVERBERATION 28000l
39
40 // SAMPLING_SHIFT : Specified the shift multiplier which controls by how
41 // much the mixing rate is multiplied while mixing. Higher values
42 // can improve quality by smoothing the soudn and reducing pops and
43 // clicks. Note, this is a shift value, so a value of 2 becomes a
44 // mixing-rate multiplier of 4, and a value of 3 = 8, etc.
45
46 #define SAMPLING_SHIFT 2
47 #define SAMPLING_FACTOR (SLONG)(1<<SAMPLING_SHIFT)
48
49
50 // FRACBITS : the number of bits per integer devoted to the fractional
51 // part of the number. This value HAS to be changed if the compiler
52 // does not support 64 bit integers. If 32 bit integers are used,
53 // FRACBITS _must_ be 9 or smaller.
54
55 #define FRACBITS 28
56 #define FRACMASK ((1l<<FRACBITS)-1)
57
58 #define TICKLSIZE 4096
59 #define TICKWSIZE (TICKLSIZE*2)
60 #define TICKBSIZE (TICKWSIZE*2)
61
62 #ifndef MIN
63 #define MIN(a,b) (((a)<(b)) ? (a) : (b))
64 #endif
65
66 #ifndef MAX
67 #define MAX(a,b) (((a)>(b))?(a):(b))
68 #endif
69
70
71 typedef struct
72 { UBYTE kick; // =1 -> sample has to be restarted
73 UBYTE active; // =1 -> sample is playing
74 UWORD flags; // 16/8 bits looping/one-shot
75 SWORD handle; // identifies the sample
76 ULONG start; // start index
77 ULONG size; // samplesize
78 ULONG reppos; // loop start
79 ULONG repend; // loop end
80 ULONG frq; // current frequency
81 UWORD vol; // current volume
82 UWORD pan; // current panning position
83 SDOUBLE current; // current index in the sample
84 SDOUBLE increment; // fixed-point increment value
85 } VINFO;
86
87
88 static SWORD **Samples;
89
90 static VINFO *vinf = NULL;
91 static VINFO *vnf;
92 static ULONG samplesthatfit;
93 static int vc_memory, vc_softchn;
94 static SDOUBLE idxsize,idxlpos,idxlend;
95 static SLONG TICKLEFT;
96 static SLONG *VC2_TICKBUF = NULL;
97 static UWORD vc_mode;
98 static int bitshift; // Amplification shift (amount to decrease 32 bit mixing buffer by!)
99 static SLONG lvolsel, rvolsel; // Volume factor .. range 0-255
100
101
102 // Reverb control variables
103 // ========================
104
105 static int RVc1, RVc2, RVc3, RVc4, RVc5, RVc6, RVc7, RVc8;
106 static ULONG RVRindex;
107
108 // For Mono or Left Channel
109 static SLONG *RVbuf1 = NULL, *RVbuf2 = NULL, *RVbuf3 = NULL,
110 *RVbuf4 = NULL, *RVbuf5 = NULL, *RVbuf6 = NULL,
111 *RVbuf7 = NULL, *RVbuf8 = NULL;
112
113 // For Stereo only (Right Channel)
114 static SLONG *RVbuf9 = NULL, *RVbuf10 = NULL, *RVbuf11 = NULL,
115 *RVbuf12 = NULL, *RVbuf13 = NULL, *RVbuf14 = NULL,
116 *RVbuf15 = NULL, *RVbuf16 = NULL;
117
118
119 // ==============================================================
120 // 16 bit sample mixers!
121
122 static SDOUBLE MixStereoNormal(SWORD *srce, SLONG *dest, SDOUBLE index, SDOUBLE increment, ULONG todo)
123 {
124 SWORD sample;
125
126 for(; todo; todo--)
127 { sample = (index & FRACBITS) ?
128 (((srce[index >> FRACBITS] * (FRACBITS - (index & FRACBITS))) +
129 (srce[(index >> FRACBITS)+1] * (index & FRACBITS))) / FRACBITS)
130 : srce[index >> FRACBITS];
131 index += increment;
132
133 *dest++ += lvolsel * sample;
134 *dest++ += rvolsel * sample;
135 }
136
137 return index;
138 }
139
140
141 static SDOUBLE MixStereoSurround(SWORD *srce, SLONG *dest, SDOUBLE index, SDOUBLE increment, ULONG todo)
142 {
143 SWORD sample;
144
145 for(dest--; todo; todo--)
146 { sample = (index & FRACBITS) ?
147 (((srce[index >> FRACBITS] * (FRACBITS - (index & FRACBITS))) +
148 (srce[(index >> FRACBITS)+1] * (index & FRACBITS))) / FRACBITS)
149 : srce[index >> FRACBITS];
150 index += increment;
151
152 *dest++ += lvolsel * sample;
153 *dest++ -= lvolsel * sample;
154 }
155
156 return index;
157 }
158
159
160 static SDOUBLE MixMonoNormal(SWORD *srce, SLONG *dest, SDOUBLE index, SDOUBLE increment, SLONG todo)
161 {
162 SWORD sample;
163
164 for(; todo; todo--)
165 { sample = (index & FRACBITS) ?
166 (((srce[index >> FRACBITS] * (FRACBITS - (index & FRACBITS))) +
167 (srce[(index >> FRACBITS)+1] * (index & FRACBITS))) / FRACBITS)
168 : srce[index >> FRACBITS];
169 index += increment;
170
171 *dest++ += lvolsel * sample;
172 }
173
174 return index;
175 }
176
177
178 static void (*Mix32to16)(SWORD *dste, SLONG *srce, SLONG count);
179 static void (*Mix32to8)(SBYTE *dste, SLONG *srce, SLONG count);
180 static void (*MixReverb)(SLONG *srce, SLONG count);
181
182
183 static void MixReverb_Normal(SLONG *srce, SLONG count)
184 {
185 SLONG speedup;
186 int ReverbPct;
187 unsigned int loc1, loc2, loc3, loc4,
188 loc5, loc6, loc7, loc8;
189
190 ReverbPct = 63 + (md_reverb*4);
191
192 loc1 = RVRindex % RVc1;
193 loc2 = RVRindex % RVc2;
194 loc3 = RVRindex % RVc3;
195 loc4 = RVRindex % RVc4;
196 loc5 = RVRindex % RVc5;
197 loc6 = RVRindex % RVc6;
198 loc7 = RVRindex % RVc7;
199 loc8 = RVRindex % RVc8;
200
201 for(; count; count--)
202 {
203 // Compute the LEFT CHANNEL echo buffers!
204
205 speedup = *srce >> 3;
206
207 RVbuf1[loc1] = speedup + ((ReverbPct * RVbuf1[loc1]) / 128);
208 RVbuf2[loc2] = speedup + ((ReverbPct * RVbuf2[loc2]) / 128);
209 RVbuf3[loc3] = speedup + ((ReverbPct * RVbuf3[loc3]) / 128);
210 RVbuf4[loc4] = speedup + ((ReverbPct * RVbuf4[loc4]) / 128);
211 RVbuf5[loc5] = speedup + ((ReverbPct * RVbuf5[loc5]) / 128);
212 RVbuf6[loc6] = speedup + ((ReverbPct * RVbuf6[loc6]) / 128);
213 RVbuf7[loc7] = speedup + ((ReverbPct * RVbuf7[loc7]) / 128);
214 RVbuf8[loc8] = speedup + ((ReverbPct * RVbuf8[loc8]) / 128);
215
216 // Prepare to compute actual finalized data!
217
218 RVRindex++;
219 loc1 = RVRindex % RVc1;
220 loc2 = RVRindex % RVc2;
221 loc3 = RVRindex % RVc3;
222 loc4 = RVRindex % RVc4;
223 loc5 = RVRindex % RVc5;
224 loc6 = RVRindex % RVc6;
225 loc7 = RVRindex % RVc7;
226 loc8 = RVRindex % RVc8;
227
228 // Left Channel!
229
230 *srce++ += (RVbuf1[loc1] - RVbuf2[loc2] + RVbuf3[loc3] - RVbuf4[loc4] +
231 RVbuf5[loc5] - RVbuf6[loc6] + RVbuf7[loc7] - RVbuf8[loc8]);
232 }
233 }
234
235
236 static void MixReverb_Stereo(SLONG *srce, SLONG count)
237 {
238 SLONG speedup;
239 int ReverbPct;
240 unsigned int loc1, loc2, loc3, loc4,
241 loc5, loc6, loc7, loc8;
242
243 ReverbPct = 63 + (md_reverb*4);
244
245 loc1 = RVRindex % RVc1;
246 loc2 = RVRindex % RVc2;
247 loc3 = RVRindex % RVc3;
248 loc4 = RVRindex % RVc4;
249 loc5 = RVRindex % RVc5;
250 loc6 = RVRindex % RVc6;
251 loc7 = RVRindex % RVc7;
252 loc8 = RVRindex % RVc8;
253
254 for(; count; count--)
255 {
256 // Compute the LEFT CHANNEL echo buffers!
257
258 speedup = *srce >> 3;
259
260 RVbuf1[loc1] = speedup + ((ReverbPct * RVbuf1[loc1]) / 128);
261 RVbuf2[loc2] = speedup + ((ReverbPct * RVbuf2[loc2]) / 128);
262 RVbuf3[loc3] = speedup + ((ReverbPct * RVbuf3[loc3]) / 128);
263 RVbuf4[loc4] = speedup + ((ReverbPct * RVbuf4[loc4]) / 128);
264 RVbuf5[loc5] = speedup + ((ReverbPct * RVbuf5[loc5]) / 128);
265 RVbuf6[loc6] = speedup + ((ReverbPct * RVbuf6[loc6]) / 128);
266 RVbuf7[loc7] = speedup + ((ReverbPct * RVbuf7[loc7]) / 128);
267 RVbuf8[loc8] = speedup + ((ReverbPct * RVbuf8[loc8]) / 128);
268
269 // Compute the RIGHT CHANNEL echo buffers!
270
271 speedup = srce[1] >> 3;
272
273 RVbuf9[loc1] = speedup + ((ReverbPct * RVbuf9[loc1]) / 128);
274 RVbuf10[loc2] = speedup + ((ReverbPct * RVbuf11[loc2]) / 128);
275 RVbuf11[loc3] = speedup + ((ReverbPct * RVbuf12[loc3]) / 128);
276 RVbuf12[loc4] = speedup + ((ReverbPct * RVbuf12[loc4]) / 128);
277 RVbuf13[loc5] = speedup + ((ReverbPct * RVbuf13[loc5]) / 128);
278 RVbuf14[loc6] = speedup + ((ReverbPct * RVbuf14[loc6]) / 128);
279 RVbuf15[loc7] = speedup + ((ReverbPct * RVbuf15[loc7]) / 128);
280 RVbuf16[loc8] = speedup + ((ReverbPct * RVbuf16[loc8]) / 128);
281
282 // Prepare to compute actual finalized data!
283
284 RVRindex++;
285 loc1 = RVRindex % RVc1;
286 loc2 = RVRindex % RVc2;
287 loc3 = RVRindex % RVc3;
288 loc4 = RVRindex % RVc4;
289 loc5 = RVRindex % RVc5;
290 loc6 = RVRindex % RVc6;
291 loc7 = RVRindex % RVc7;
292 loc8 = RVRindex % RVc8;
293
294 // Left Channel!
295
296 *srce++ += (RVbuf1[loc1] - RVbuf2[loc2] + RVbuf3[loc3] - RVbuf4[loc4] +
297 RVbuf5[loc5] - RVbuf6[loc6] + RVbuf7[loc7] - RVbuf8[loc8]);
298
299 // Right Channel!
300
301 *srce++ += (RVbuf9[loc1] - RVbuf10[loc2] + RVbuf11[loc3] - RVbuf12[loc4] +
302 RVbuf13[loc5] - RVbuf14[loc6] + RVbuf15[loc7] - RVbuf16[loc8]);
303 }
304 }
305
306
307 static void Mix32To16_Normal(SWORD *dste, SLONG *srce, SLONG count)
308 {
309 SLONG x1, x2, tmpx;
310 int i;
311
312 for(count/=SAMPLING_FACTOR; count; count--)
313 { tmpx = 0;
314
315 for(i=SAMPLING_FACTOR/2; i; i--)
316 { x1 = *srce++ / bitshift;
317 x2 = *srce++ / bitshift;
318
319 x1 = (x1 > 32767) ? 32767 : (x1 < -32768) ? -32768 : x1;
320 x2 = (x2 > 32767) ? 32767 : (x2 < -32768) ? -32768 : x2;
321
322 tmpx += x1 + x2;
323 }
324
325 *dste++ = tmpx / SAMPLING_FACTOR;
326 }
327 }
328
329
330 static void Mix32To16_Stereo(SWORD *dste, SLONG *srce, SLONG count)
331 {
332 SLONG x1, x2, x3, x4, tmpx, tmpy;
333 int i;
334
335 for(count/=SAMPLING_FACTOR; count; count--)
336 { tmpx = tmpy = 0;
337
338 for(i=SAMPLING_FACTOR/2; i; i--)
339 { x1 = *srce++ / bitshift;
340 x2 = *srce++ / bitshift;
341 x3 = *srce++ / bitshift;
342 x4 = *srce++ / bitshift;
343
344 x1 = (x1 > 32767) ? 32767 : (x1 < -32768) ? -32768 : x1;
345 x2 = (x2 > 32767) ? 32767 : (x2 < -32768) ? -32768 : x2;
346 x3 = (x3 > 32767) ? 32767 : (x3 < -32768) ? -32768 : x3;
347 x4 = (x4 > 32767) ? 32767 : (x4 < -32768) ? -32768 : x4;
348
349 tmpx += x1 + x3;
350 tmpy += x2 + x4;
351 }
352
353 *dste++ = tmpx / SAMPLING_FACTOR;
354 *dste++ = tmpy / SAMPLING_FACTOR;
355 }
356 }
357
358
359 static void Mix32To8_Normal(SBYTE *dste, SLONG *srce, SLONG count)
360 {
361 int x1, x2;
362 int i, tmpx;
363
364 for(count/=SAMPLING_FACTOR; count; count--)
365 { tmpx = 0;
366
367 for(i=SAMPLING_FACTOR/2; i; i--)
368 { x1 = *srce++ / bitshift;
369 x2 = *srce++ / bitshift;
370
371 x1 = (x1 > 127) ? 127 : (x1 < -128) ? -128 : x1;
372 x2 = (x2 > 127) ? 127 : (x2 < -128) ? -128 : x2;
373
374 tmpx += x1 + x2;
375 }
376
377 *dste++ = (tmpx / SAMPLING_FACTOR) + 128;
378 }
379 }
380
381
382 static void Mix32To8_Stereo(SBYTE *dste, SLONG *srce, SLONG count)
383 {
384 int x1, x2, x3, x4;
385 int i, tmpx, tmpy;
386
387 for(count/=SAMPLING_FACTOR; count; count--)
388 { tmpx = tmpy = 0;
389
390 for(i=SAMPLING_FACTOR/2; i; i--)
391 { x1 = *srce++ / bitshift;
392 x2 = *srce++ / bitshift;
393 x3 = *srce++ / bitshift;
394 x4 = *srce++ / bitshift;
395
396 x1 = (x1 > 127) ? 127 : (x1 < -128) ? -128 : x1;
397 x2 = (x2 > 127) ? 127 : (x2 < -128) ? -128 : x2;
398 x3 = (x3 > 127) ? 127 : (x3 < -128) ? -128 : x3;
399 x4 = (x4 > 127) ? 127 : (x4 < -128) ? -128 : x4;
400
401 tmpx += x1 + x3;
402 tmpy += x2 + x4;
403 }
404
405 *dste++ = (tmpx / SAMPLING_FACTOR) + 128;
406 *dste++ = (tmpy / SAMPLING_FACTOR) + 128;
407 }
408 }
409
410
411 static ULONG samples2bytes(ULONG samples)
412 {
413 if(vc_mode & DMODE_16BITS) samples <<= 1;
414 if(vc_mode & DMODE_STEREO) samples <<= 1;
415
416 return samples;
417 }
418
419
420 static ULONG bytes2samples(ULONG bytes)
421 {
422 if(vc_mode & DMODE_16BITS) bytes >>= 1;
423 if(vc_mode & DMODE_STEREO) bytes >>= 1;
424
425 return bytes;
426 }
427
428
429 static void AddChannel(SLONG *ptr, SLONG todo)
430 {
431 SDOUBLE end;
432 SLONG done;
433 SWORD *s;
434
435 while(todo > 0)
436 { // update the 'current' index so the sample loops, or
437 // stops playing if it reached the end of the sample
438
439 if(vnf->flags & SF_REVERSE)
440 {
441 // The sample is playing in reverse
442
443 if((vnf->flags & SF_LOOP) && (vnf->current < idxlpos))
444 {
445 // the sample is looping, and it has
446 // reached the loopstart index
447
448 if(vnf->flags & SF_BIDI)
449 {
450 // sample is doing bidirectional loops, so 'bounce'
451 // the current index against the idxlpos
452
453 vnf->current = idxlpos + (idxlpos - vnf->current);
454 vnf->flags &= ~SF_REVERSE;
455 vnf->increment = -vnf->increment;
456 } else
457 // normal backwards looping, so set the
458 // current position to loopend index
459
460 vnf->current = idxlend - (idxlpos-vnf->current);
461 } else
462 {
463 // the sample is not looping, so check
464 // if it reached index 0
465
466 if(vnf->current < 0)
467 {
468 // playing index reached 0, so stop
469 // playing this sample
470
471 vnf->current = 0;
472 vnf->active = 0;
473 break;
474 }
475 }
476 } else
477 {
478 // The sample is playing forward
479
480 if((vnf->flags & SF_LOOP) && (vnf->current > idxlend))
481 {
482 // the sample is looping, so check if
483 // it reached the loopend index
484
485 if(vnf->flags & SF_BIDI)
486 {
487 // sample is doing bidirectional loops, so 'bounce'
488 // the current index against the idxlend
489
490 vnf->flags |= SF_REVERSE;
491 vnf->increment = -vnf->increment;
492 vnf->current = idxlend-(vnf->current-idxlend);
493 } else
494 // normal backwards looping, so set the
495 // current position to loopend index
496
497 vnf->current = idxlpos + (vnf->current-idxlend);
498 } else
499 {
500 // sample is not looping, so check
501 // if it reached the last position
502
503 if(vnf->current > idxsize)
504 {
505 // yes, so stop playing this sample
506
507 vnf->current = 0;
508 vnf->active = 0;
509 break;
510 }
511 }
512 }
513
514 if(!(s=Samples[vnf->handle]))
515 { vnf->current = 0;
516 vnf->active = 0;
517 break;
518 }
519
520 end = (vnf->flags & SF_REVERSE) ?
521 (vnf->flags & SF_LOOP) ? idxlpos : 0 :
522 (vnf->flags & SF_LOOP) ? idxlend : idxsize;
523
524 done = MIN((end - vnf->current) / vnf->increment + 1, todo);
525
526 if(!done)
527 { vnf->active = 0;
528 break;
529 }
530
531 if(vnf->vol)
532 { if(vc_mode & DMODE_STEREO)
533 if(vnf->pan == PAN_SURROUND && vc_mode&DMODE_SURROUND)
534 vnf->current = MixStereoSurround(s,ptr,vnf->current,vnf->increment,done);
535 else
536 vnf->current = MixStereoNormal(s,ptr,vnf->current,vnf->increment,done);
537 else
538 vnf->current = MixMonoNormal(s,ptr,vnf->current,vnf->increment,done);
539 }
540 todo -= done;
541 ptr += (vc_mode & DMODE_STEREO) ? (done<<1) : done;
542 }
543 }
544
545
546 void VC2_WriteSamples(SBYTE *buf, ULONG todo)
547 {
548 int left, portion = 0;
549 SBYTE *buffer;
550 int t;
551 int pan, vol;
552
553 todo *= SAMPLING_FACTOR;
554
555 while(todo)
556 { if(TICKLEFT==0)
557 { if(vc_mode & DMODE_SOFT_MUSIC) md_player();
558 TICKLEFT = (md_mixfreq*125l*SAMPLING_FACTOR) / (md_bpm*50l);
559 TICKLEFT &= ~(SAMPLING_FACTOR-1);
560 }
561
562 left = MIN(TICKLEFT, todo);
563
564 buffer = buf;
565 TICKLEFT -= left;
566 todo -= left;
567
568 buf += samples2bytes(left) / SAMPLING_FACTOR;
569
570 while(left)
571 { portion = MIN(left, samplesthatfit);
572 memset(VC2_TICKBUF, 0, portion << ((vc_mode & DMODE_STEREO) ? 3 : 2));
573
574 for(t=0; t<vc_softchn; t++)
575 { vnf = &vinf[t];
576
577 if(vnf->kick)
578 { vnf->current = (SDOUBLE)(vnf->start) << FRACBITS;
579 vnf->kick = 0;
580 vnf->active = 1;
581 }
582
583 if(vnf->frq == 0) vnf->active = 0;
584
585 if(vnf->active)
586 { vnf->increment = ((SDOUBLE)(vnf->frq) << (FRACBITS-SAMPLING_SHIFT)) / (SDOUBLE)md_mixfreq;
587 if(vnf->flags & SF_REVERSE) vnf->increment=-vnf->increment;
588
589 vol = vnf->vol; pan = vnf->pan;
590
591 if((vc_mode & DMODE_STEREO) && (pan!=PAN_SURROUND))
592 { lvolsel = (vol * (255-pan)) >> 8;
593 rvolsel = (vol * pan) >> 8;
594 } else
595 lvolsel = (vol*256l) / 480;
596
597 idxsize = (vnf->size) ? ((SDOUBLE)(vnf->size) << FRACBITS)-1 : 0;
598 idxlend = (vnf->repend) ? ((SDOUBLE)(vnf->repend) << FRACBITS)-1 : 0;
599 idxlpos = (SDOUBLE)(vnf->reppos) << FRACBITS;
600 AddChannel(VC2_TICKBUF, portion);
601 }
602 }
603
604 if(md_reverb) MixReverb(VC2_TICKBUF, portion);
605
606 if(vc_mode & DMODE_16BITS)
607 Mix32to16((SWORD *) buffer, VC2_TICKBUF, portion);
608 else
609 Mix32to8((SBYTE *) buffer, VC2_TICKBUF, portion);
610
611 buffer += samples2bytes(portion) / SAMPLING_FACTOR;
612 left -= portion;
613 }
614 }
615 }
616
617
618 void VC2_SilenceBytes(SBYTE *buf, ULONG todo)
619
620 // Fill the buffer with 'todo' bytes of silence (it depends on the mixing
621 // mode how the buffer is filled)
622
623 {
624 // clear the buffer to zero (16 bits
625 // signed ) or 0x80 (8 bits unsigned)
626
627 if(vc_mode & DMODE_16BITS)
628 memset(buf,0,todo);
629 else
630 memset(buf,0x80,todo);
631 }
632
633
634 ULONG VC2_WriteBytes(SBYTE *buf, ULONG todo)
635
636 // Writes 'todo' mixed SBYTES (!!) to 'buf'. It returns the number of
637 // SBYTES actually written to 'buf' (which is rounded to number of samples
638 // that fit into 'todo' bytes).
639
640 {
641 if(vc_softchn == 0)
642 { VC2_SilenceBytes(buf,todo);
643 return todo;
644 }
645
646 todo = bytes2samples(todo);
647 VC2_WriteSamples(buf,todo);
648
649 return samples2bytes(todo);
650 }
651
652
653 BOOL VC2_PlayStart(void)
654 {
655 if(vc_softchn > 0)
656 { bitshift = vc_softchn + 257;
657 if(!(vc_mode & DMODE_16BITS))
658 bitshift *= 256;
659 if(md_reverb) bitshift++;
660 }
661
662 samplesthatfit = TICKLSIZE;
663 if(vc_mode & DMODE_STEREO) samplesthatfit >>= 1;
664 TICKLEFT = 0;
665
666 /* Original Reverb Code!
667 The stuff I use avoids floating point (below).
668
669 RVc1 = (SLONG)(500 * md_mixfreq) / 11000;
670 RVc2 = (SLONG)(507.8125 * md_mixfreq) / 11000;
671 RVc3 = (SLONG)(531.25 * md_mixfreq) / 11000;
672 RVc4 = (SLONG)(570.3125 * md_mixfreq) / 11000;
673 RVc5 = (SLONG)(625 * md_mixfreq) / 11000;
674 RVc6 = (SLONG)(695.3125 * md_mixfreq) / 11000;
675 RVc7 = (SLONG)(781.25 * md_mixfreq) / 11000;
676 RVc8 = (SLONG)(882.8125 * md_mixfreq) / 11000;
677 ReverbPct = 99 - (md_reverb*2);
678 */
679
680 RVc1 = (5000L * md_mixfreq) / REVERBERATION;
681 RVc2 = (5078L * md_mixfreq) / REVERBERATION;
682 RVc3 = (5313L * md_mixfreq) / REVERBERATION;
683 RVc4 = (5703L * md_mixfreq) / REVERBERATION;
684 RVc5 = (6250L * md_mixfreq) / REVERBERATION;
685 RVc6 = (6953L * md_mixfreq) / REVERBERATION;
686 RVc7 = (7813L * md_mixfreq) / REVERBERATION;
687 RVc8 = (8828L * md_mixfreq) / REVERBERATION;
688
689 if((RVbuf1 = (SLONG *)_mm_calloc((RVc1+1),sizeof(SLONG))) == NULL) return 1;
690 if((RVbuf2 = (SLONG *)_mm_calloc((RVc2+1),sizeof(SLONG))) == NULL) return 1;
691 if((RVbuf3 = (SLONG *)_mm_calloc((RVc3+1),sizeof(SLONG))) == NULL) return 1;
692 if((RVbuf4 = (SLONG *)_mm_calloc((RVc4+1),sizeof(SLONG))) == NULL) return 1;
693 if((RVbuf5 = (SLONG *)_mm_calloc((RVc5+1),sizeof(SLONG))) == NULL) return 1;
694 if((RVbuf6 = (SLONG *)_mm_calloc((RVc6+1),sizeof(SLONG))) == NULL) return 1;
695 if((RVbuf7 = (SLONG *)_mm_calloc((RVc7+1),sizeof(SLONG))) == NULL) return 1;
696 if((RVbuf8 = (SLONG *)_mm_calloc((RVc8+1),sizeof(SLONG))) == NULL) return 1;
697
698 if(vc_mode & DMODE_STEREO)
699 { if((RVbuf9 = (SLONG *)_mm_calloc((RVc1+1),sizeof(SLONG))) == NULL) return 1;
700 if((RVbuf10 = (SLONG *)_mm_calloc((RVc2+1),sizeof(SLONG))) == NULL) return 1;
701 if((RVbuf11 = (SLONG *)_mm_calloc((RVc3+1),sizeof(SLONG))) == NULL) return 1;
702 if((RVbuf12 = (SLONG *)_mm_calloc((RVc4+1),sizeof(SLONG))) == NULL) return 1;
703 if((RVbuf13 = (SLONG *)_mm_calloc((RVc5+1),sizeof(SLONG))) == NULL) return 1;
704 if((RVbuf14 = (SLONG *)_mm_calloc((RVc6+1),sizeof(SLONG))) == NULL) return 1;
705 if((RVbuf15 = (SLONG *)_mm_calloc((RVc7+1),sizeof(SLONG))) == NULL) return 1;
706 if((RVbuf16 = (SLONG *)_mm_calloc((RVc8+1),sizeof(SLONG))) == NULL) return 1;
707 }
708
709 RVRindex = 0;
710 return 0;
711 }
712
713
714 void VC2_PlayStop(void)
715 {
716 if(RVbuf1 != NULL) free(RVbuf1);
717 if(RVbuf2 != NULL) free(RVbuf2);
718 if(RVbuf3 != NULL) free(RVbuf3);
719 if(RVbuf4 != NULL) free(RVbuf4);
720 if(RVbuf5 != NULL) free(RVbuf5);
721 if(RVbuf6 != NULL) free(RVbuf6);
722 if(RVbuf7 != NULL) free(RVbuf7);
723 if(RVbuf8 != NULL) free(RVbuf8);
724 if(RVbuf9 != NULL) free(RVbuf9);
725 if(RVbuf10 != NULL) free(RVbuf10);
726 if(RVbuf11 != NULL) free(RVbuf11);
727 if(RVbuf12 != NULL) free(RVbuf12);
728 if(RVbuf13 != NULL) free(RVbuf13);
729 if(RVbuf14 != NULL) free(RVbuf14);
730 if(RVbuf15 != NULL) free(RVbuf15);
731 if(RVbuf16 != NULL) free(RVbuf16);
732
733 RVbuf1 = NULL; RVbuf2 = NULL; RVbuf3 = NULL; RVbuf4 = NULL;
734 RVbuf5 = NULL; RVbuf6 = NULL; RVbuf7 = NULL; RVbuf8 = NULL;
735 RVbuf9 = NULL; RVbuf10 = NULL; RVbuf11 = NULL; RVbuf12 = NULL;
736 RVbuf13 = NULL; RVbuf14 = NULL; RVbuf15 = NULL; RVbuf16 = NULL;
737 }
738
739
740 BOOL VC2_Init(void)
741 {
742 _mm_errno = MMERR_INITIALIZING_MIXER;
743 if((Samples = (SWORD **)calloc(MAXSAMPLEHANDLES, sizeof(SWORD *))) == NULL) return 1;
744 if(VC2_TICKBUF==NULL) if((VC2_TICKBUF=(SLONG *)malloc((TICKLSIZE+32) * sizeof(SLONG))) == NULL) return 1;
745
746 if(md_mode & DMODE_STEREO)
747 { Mix32to16 = Mix32To16_Stereo;
748 Mix32to8 = Mix32To8_Stereo;
749 MixReverb = MixReverb_Stereo;
750 } else
751 { Mix32to16 = Mix32To16_Normal;
752 Mix32to8 = Mix32To8_Normal;
753 MixReverb = MixReverb_Normal;
754 }
755
756 vc_mode = md_mode;
757
758 _mm_errno = 0;
759 return 0;
760 }
761
762
763 void VC2_Exit(void)
764
765 // Yay, he joys and fruits of C and C++ -
766 // Deallocation of arrays!
767
768 {
769 //if(VC2_TICKBUF!=NULL) free(VC2_TICKBUF);
770 if(vinf!=NULL) free(vinf);
771 if(Samples!=NULL) free(Samples);
772
773 // VC2_TICKBUF = NULL;
774 vinf = NULL;
775 Samples = NULL;
776 }
777
778
779 BOOL VC2_SetNumVoices(void)
780 {
781 int t;
782
783 if((vc_softchn = md_softchn) == 0) return 0;
784
785 if(vinf!=NULL) free(vinf);
786 if((vinf = _mm_calloc(sizeof(VINFO),vc_softchn)) == NULL) return 1;
787
788 for(t=0; t<vc_softchn; t++)
789 { vinf[t].frq = 10000;
790 vinf[t].pan = (t & 1) ? 0 : 255;
791 }
792
793 return 0;
794 }
795
796
797 void VC2_VoiceSetVolume(UBYTE voice, UWORD vol)
798 {
799 vinf[voice].vol = vol;
800 }
801
802
803 void VC2_VoiceSetFrequency(UBYTE voice, ULONG frq)
804 {
805 vinf[voice].frq = frq;
806 }
807
808
809 void VC2_VoiceSetPanning(UBYTE voice, ULONG pan)
810 {
811 vinf[voice].pan = pan;
812 }
813
814
815 void VC2_VoicePlay(UBYTE voice, SWORD handle, ULONG start, ULONG size, ULONG reppos, ULONG repend, UWORD flags)
816 {
817 vinf[voice].flags = flags;
818 vinf[voice].handle = handle;
819 vinf[voice].start = start;
820 vinf[voice].size = size;
821 vinf[voice].reppos = reppos;
822 vinf[voice].repend = repend;
823 vinf[voice].kick = 1;
824 }
825
826
827 void VC2_VoiceStop(UBYTE voice)
828 {
829 vinf[voice].active = 0;
830 }
831
832
833 BOOL VC2_VoiceStopped(UBYTE voice)
834 {
835 return(vinf[voice].active==0);
836 }
837
838
839 void VC2_VoiceReleaseSustain(UBYTE voice)
840 {
841
842 }
843
844
845 SLONG VC2_VoiceGetPosition(UBYTE voice)
846 {
847 return(vinf[voice].current>>FRACBITS);
848 }
849
850
851 /**************************************************
852 ***************************************************
853 ***************************************************
854 **************************************************/
855
856
857 void VC2_SampleUnload(SWORD handle)
858 {
859 void *sampleadr = Samples[handle];
860
861 free(sampleadr);
862 Samples[handle] = NULL;
863 }
864
865
866 SWORD VC2_SampleLoad(SAMPLOAD *sload, int type, FILE *fp)
867 {
868 SAMPLE *s = sload->sample;
869 int handle;
870 ULONG t, length,loopstart,loopend;
871
872 if(type==MD_HARDWARE) return -1;
873
874 // Find empty slot to put sample address in
875 for(handle=0; handle<MAXSAMPLEHANDLES; handle++)
876 if(Samples[handle]==NULL) break;
877
878 if(handle==MAXSAMPLEHANDLES)
879 { _mm_errno = MMERR_OUT_OF_HANDLES;
880 return -1;
881 }
882
883 length = s->length;
884 loopstart = s->loopstart;
885 loopend = s->loopend;
886
887 SL_SampleSigned(sload);
888
889 SL_Sample8to16(sload);
890 if((Samples[handle]=(SWORD *)malloc((length+16)<<1))==NULL)
891 { _mm_errno = MMERR_SAMPLE_TOO_BIG;
892 return -1;
893 }
894 // read sample into buffer.
895 SL_Load(Samples[handle],sload,length);
896
897 // Unclick samples:
898
899 if(s->flags & SF_LOOP)
900 { if(s->flags & SF_BIDI)
901 for(t=0; t<16; t++) Samples[handle][loopend+t] = Samples[handle][(loopend-t)-1];
902 else
903 for(t=0; t<16; t++) Samples[handle][loopend+t] = Samples[handle][t+loopstart];
904 } else
905 for(t=0; t<16; t++) Samples[handle][t+length] = 0;
906
907 return handle;
908 }
909
910
911 ULONG VC2_SampleSpace(int type)
912 {
913 return vc_memory;
914 }
915
916
917 ULONG VC2_SampleLength(int type, SAMPLE *s)
918 {
919 return (s->length * ((s->flags & SF_16BITS) ? 2 : 1)) + 16;
920 }
921
922
923 /**************************************************
924 ***************************************************
925 ***************************************************
926 **************************************************/
927