3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
10 * By Shawn Hargreaves,
18 * See readme.txt for copyright information.
31 #include <sys/farptr.h>
38 typedef struct MIXER_VOICE
40 int playing; /* are we active? */
41 unsigned char *data8; /* data for 8 bit samples */
42 unsigned short *data16; /* data for 16 bit samples */
43 long pos; /* fixed point position in sample */
44 long diff; /* fixed point speed of play */
45 long len; /* fixed point sample length */
46 long loop_start; /* fixed point loop start position */
47 long loop_end; /* fixed point loop end position */
48 int lvol; /* left channel volume */
49 int rvol; /* right channel volume */
53 #define MIXER_VOLUME_LEVELS 32
54 #define MIXER_FIX_SHIFT 8
56 #define UPDATE_FREQ 16
59 /* the samples currently being played */
60 static MIXER_VOICE mixer_voice[MIXER_MAX_SFX];
62 /* temporary sample mixing buffer */
63 static unsigned short *mix_buffer = NULL;
65 /* lookup table for converting sample volumes */
66 typedef signed short MIXER_VOL_TABLE[256];
67 static MIXER_VOL_TABLE *mix_vol_table = NULL;
69 /* lookup table for amplifying and clipping samples */
70 static unsigned short *mix_clip_table = NULL;
75 /* flags for the mixing code */
76 static int mix_voices;
79 static int mix_stereo;
83 static void mixer_lock_mem();
88 * Initialises the sample mixing code, returning 0 on success. You should
89 * pass it the number of samples you want it to mix each time the refill
90 * buffer routine is called, the sample rate to mix at, and two flags
91 * indicating whether the mixing should be done in stereo or mono and with
92 * eight or sixteen bits. The bufsize parameter is the number of samples,
93 * not bytes. It should take into account whether you are working in stereo
94 * or not (eg. double it if in stereo), but it should not be affected by
95 * whether each sample is 8 or 16 bits.
97 int _mixer_init(int bufsize, int freq, int stereo, int is16bit, int *voices)
105 while ((mix_voices < MIXER_MAX_SFX) && (mix_voices < *voices))
108 *voices = mix_voices;
115 for (i=0; i<MIXER_MAX_SFX; i++) {
116 mixer_voice[i].playing = FALSE;
117 mixer_voice[i].data8 = NULL;
118 mixer_voice[i].data16 = NULL;
121 /* temporary buffer for sample mixing */
122 mix_buffer = malloc(mix_size*sizeof(short));
126 _go32_dpmi_lock_data(mix_buffer, mix_size*sizeof(short));
128 /* volume table for mixing samples into the temporary buffer */
129 mix_vol_table = malloc(sizeof(MIXER_VOL_TABLE) * MIXER_VOLUME_LEVELS);
130 if (!mix_vol_table) {
136 _go32_dpmi_lock_data(mix_vol_table, sizeof(MIXER_VOL_TABLE) * MIXER_VOLUME_LEVELS);
138 for (j=0; j<MIXER_VOLUME_LEVELS; j++)
139 for (i=0; i<256; i++)
140 mix_vol_table[j][i] = (i-128) * j * 256 / MIXER_VOLUME_LEVELS / mix_voices;
142 /* lookup table for amplifying and clipping sample buffers */
144 clip_size = 1 << MIX_RES_16;
145 clip_scale = 18 - MIX_RES_16;
149 clip_size = 1 << MIX_RES_8;
150 clip_scale = 10 - MIX_RES_8;
154 mix_clip_table = malloc(sizeof(short) * clip_size);
155 if (!mix_clip_table) {
159 mix_vol_table = NULL;
163 _go32_dpmi_lock_data(mix_clip_table, sizeof(short) * clip_size);
165 if (mix_voices >= 8) {
166 /* clip extremes of the sample range */
167 for (i=0; i<clip_size*3/8; i++) {
168 mix_clip_table[i] = 0;
169 mix_clip_table[clip_size-1-i] = clip_max;
172 for (i=0; i<clip_size/4; i++)
173 mix_clip_table[clip_size*3/8 + i] = i<<clip_scale;
176 /* simple linear amplification */
177 for (i=0; i<clip_size; i++)
178 mix_clip_table[i] = (i<<clip_scale)/4;
189 * Cleans up the sample mixer code when you are done with it.
197 mix_vol_table = NULL;
199 free(mix_clip_table);
200 mix_clip_table = NULL;
205 /* update_mixer_volume:
206 * Called whenever the voice volume or pan changes, to update the mixer
207 * amplification table indexes.
209 static inline void update_mixer_volume(MIXER_VOICE *mv, PHYS_VOICE *pv)
211 int vol = pv->vol >> 12;
212 int pan = pv->pan >> 12;
216 lvol = vol * (256-pan) * MIXER_VOLUME_LEVELS / 32768;
217 rvol = vol * pan * MIXER_VOLUME_LEVELS / 32768;
220 lvol = rvol = vol * MIXER_VOLUME_LEVELS / 256;
222 mv->lvol = MID(0, lvol, MIXER_VOLUME_LEVELS-1);
223 mv->rvol = MID(0, rvol, MIXER_VOLUME_LEVELS-1);
228 /* update_mixer_freq:
229 * Called whenever the voice frequency changes, to update the sample
232 static inline void update_mixer_freq(MIXER_VOICE *mv, PHYS_VOICE *pv)
234 mv->diff = (pv->freq >> (12 - MIXER_FIX_SHIFT)) / mix_freq;
236 if (pv->playmode & PLAYMODE_BACKWARD)
237 mv->diff = -mv->diff;
242 /* helper for constructing the body of a sample mixing routine */
245 if ((voice->playmode & PLAYMODE_LOOP) && \
246 (spl->loop_start < spl->loop_end)) { \
248 if (voice->playmode & PLAYMODE_BACKWARD) { \
249 /* mix a backward looping sample */ \
250 while (len-- > 0) { \
252 spl->pos += spl->diff; \
253 if (spl->pos < spl->loop_start) { \
254 if (voice->playmode & PLAYMODE_BIDIR) { \
255 spl->diff = -spl->diff; \
256 spl->pos += spl->diff * 2; \
257 voice->playmode ^= PLAYMODE_BACKWARD; \
261 spl->pos += (spl->loop_end - spl->loop_start); \
267 /* mix a forward looping sample */ \
268 while (len-- > 0) { \
270 spl->pos += spl->diff; \
271 if (spl->pos >= spl->loop_end) { \
272 if (voice->playmode & PLAYMODE_BIDIR) { \
273 spl->diff = -spl->diff; \
274 spl->pos += spl->diff * 2; \
275 voice->playmode ^= PLAYMODE_BACKWARD; \
279 spl->pos -= (spl->loop_end - spl->loop_start); \
286 /* mix a non-looping sample */ \
287 while (len-- > 0) { \
289 spl->pos += spl->diff; \
290 if ((unsigned long)spl->pos >= (unsigned long)spl->len) { \
291 /* note: we don't need a different version for reverse play, */ \
292 /* as this will wrap and automatically do the Right Thing */ \
293 spl->playing = FALSE; \
307 /* mix_mono_8_samples:
308 * Mixes from an eight bit sample into a mono buffer, until either len
309 * samples have been mixed or until the end of the sample is reached.
311 static void mix_mono_8_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, unsigned short *buf, int len)
313 signed short *vol = (short *)(mix_vol_table + spl->lvol);
316 *(buf++) += vol[spl->data8[spl->pos>>MIXER_FIX_SHIFT]];
323 static END_OF_FUNCTION(mix_mono_8_samples);
327 /* mix_stereo_8_samples:
328 * Mixes from an eight bit sample into a stereo buffer, until either len
329 * samples have been mixed or until the end of the sample is reached.
331 static void mix_stereo_8_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, unsigned short *buf, int len)
333 signed short *lvol = (short *)(mix_vol_table + spl->lvol);
334 signed short *rvol = (short *)(mix_vol_table + spl->rvol);
339 *(buf++) += lvol[spl->data8[spl->pos>>MIXER_FIX_SHIFT]]; \
340 *(buf++) += rvol[spl->data8[spl->pos>>MIXER_FIX_SHIFT]];
347 static END_OF_FUNCTION(mix_stereo_8_samples);
351 /* mix_mono_16_samples:
352 * Mixes from a 16 bit sample into a mono buffer, until either len samples
353 * have been mixed or until the end of the sample is reached.
355 static void mix_mono_16_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, unsigned short *buf, int len)
357 signed short *vol = (short *)(mix_vol_table + spl->lvol);
360 *(buf++) += vol[(spl->data16[spl->pos>>MIXER_FIX_SHIFT])>>8];
367 static END_OF_FUNCTION(mix_mono_16_samples);
371 /* mix_stereo_16_samples:
372 * Mixes from a 16 bit sample into a stereo buffer, until either len samples
373 * have been mixed or until the end of the sample is reached.
375 static void mix_stereo_16_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, unsigned short *buf, int len)
377 signed short *lvol = (short *)(mix_vol_table + spl->lvol);
378 signed short *rvol = (short *)(mix_vol_table + spl->rvol);
383 *(buf++) += lvol[(spl->data16[spl->pos>>MIXER_FIX_SHIFT])>>8]; \
384 *(buf++) += rvol[(spl->data16[spl->pos>>MIXER_FIX_SHIFT])>>8];
391 static END_OF_FUNCTION(mix_stereo_16_samples);
398 /* helper for updating the volume ramp and pitch/pan sweep status */
401 if ((len & (UPDATE_FREQ-1)) == 0) { \
402 /* update volume ramp */ \
404 voice->vol += voice->dvol; \
405 if (((voice->dvol > 0) && (voice->vol >= voice->target_vol)) || \
406 ((voice->dvol < 0) && (voice->vol <= voice->target_vol))) { \
407 voice->vol = voice->target_vol; \
412 /* update frequency sweep */ \
413 if (voice->dfreq) { \
414 voice->freq += voice->dfreq; \
415 if (((voice->dfreq > 0) && (voice->freq >= voice->target_freq)) || \
416 ((voice->dfreq < 0) && (voice->freq <= voice->target_freq))) { \
417 voice->freq = voice->target_freq; \
422 /* update pan sweep */ \
424 voice->pan += voice->dpan; \
425 if (((voice->dpan > 0) && (voice->pan >= voice->target_pan)) || \
426 ((voice->dpan < 0) && (voice->pan <= voice->target_pan))) { \
427 voice->pan = voice->target_pan; \
432 update_mixer_volume(spl, voice); \
433 update_mixer_freq(spl, voice); \
439 /* mix_mono_8_samples_slow:
440 * Mixes from an eight bit sample into a mono buffer, until either len
441 * samples have been mixed or until the end of the sample is reached,
442 * using the slow mixing code that supports volume ramps and frequency/pan
445 static void mix_mono_8_samples_slow(MIXER_VOICE *spl, PHYS_VOICE *voice, unsigned short *buf, int len)
447 signed short *vol = (short *)(mix_vol_table + spl->lvol);
450 *(buf++) += vol[spl->data8[spl->pos>>MIXER_FIX_SHIFT]];
457 static END_OF_FUNCTION(mix_mono_8_samples_slow);
461 /* mix_stereo_8_samples_slow:
462 * Mixes from an eight bit sample into a stereo buffer, until either len
463 * samples have been mixed or until the end of the sample is reached,
464 * using the slow mixing code that supports volume ramps and frequency/pan
467 static void mix_stereo_8_samples_slow(MIXER_VOICE *spl, PHYS_VOICE *voice, unsigned short *buf, int len)
469 signed short *lvol = (short *)(mix_vol_table + spl->lvol);
470 signed short *rvol = (short *)(mix_vol_table + spl->rvol);
475 *(buf++) += lvol[spl->data8[spl->pos>>MIXER_FIX_SHIFT]]; \
476 *(buf++) += rvol[spl->data8[spl->pos>>MIXER_FIX_SHIFT]];
483 static END_OF_FUNCTION(mix_stereo_8_samples_slow);
487 /* mix_mono_16_samples_slow:
488 * Mixes from a 16 bit sample into a mono buffer, until either len samples
489 * have been mixed or until the end of the sample is reached, using the
490 * slow mixing code that supports volume ramps and frequency/pan sweep
493 static void mix_mono_16_samples_slow(MIXER_VOICE *spl, PHYS_VOICE *voice, unsigned short *buf, int len)
495 signed short *vol = (short *)(mix_vol_table + spl->lvol);
498 *(buf++) += vol[(spl->data16[spl->pos>>MIXER_FIX_SHIFT])>>8];
505 static END_OF_FUNCTION(mix_mono_16_samples_slow);
509 /* mix_stereo_16_samples_slow:
510 * Mixes from a 16 bit sample into a stereo buffer, until either len samples
511 * have been mixed or until the end of the sample is reached, using the
512 * slow mixing code that supports volume ramps and frequency/pan sweep
515 static void mix_stereo_16_samples_slow(MIXER_VOICE *spl, PHYS_VOICE *voice, unsigned short *buf, int len)
517 signed short *lvol = (short *)(mix_vol_table + spl->lvol);
518 signed short *rvol = (short *)(mix_vol_table + spl->rvol);
523 *(buf++) += lvol[(spl->data16[spl->pos>>MIXER_FIX_SHIFT])>>8]; \
524 *(buf++) += rvol[(spl->data16[spl->pos>>MIXER_FIX_SHIFT])>>8];
531 static END_OF_FUNCTION(mix_stereo_16_samples_slow);
535 /* _mix_some_samples:
536 * Mixes samples into a buffer in conventional memory (the buf parameter
537 * should be a linear offset into the specified segment), using the buffer
538 * size, sample frequency, etc, set when you called _mixer_init(). This
539 * should be called by the hardware end-of-buffer interrupt routine to
540 * get the next buffer full of samples to DMA to the card.
542 void _mix_some_samples(unsigned long buf, unsigned short seg, int issigned)
545 unsigned short *p = mix_buffer;
546 unsigned long *l = (unsigned long *)p;
548 /* clear mixing buffer */
549 for (i=0; i<mix_size/2; i++)
552 /* mix the samples */
554 for (i=0; i<mix_voices; i++) {
555 if ((mixer_voice[i].playing) &&
556 ((_phys_voice[i].vol > 0) || (_phys_voice[i].dvol > 0))) {
557 if ((_phys_voice[i].dvol) || (_phys_voice[i].dfreq) || (_phys_voice[i].dpan)) {
558 if (mixer_voice[i].data8)
559 mix_stereo_8_samples_slow(mixer_voice+i, _phys_voice+i, p, mix_size);
561 mix_stereo_16_samples_slow(mixer_voice+i, _phys_voice+i, p, mix_size);
564 if (mixer_voice[i].data8)
565 mix_stereo_8_samples(mixer_voice+i, _phys_voice+i, p, mix_size);
567 mix_stereo_16_samples(mixer_voice+i, _phys_voice+i, p, mix_size);
573 for (i=0; i<mix_voices; i++) {
574 if ((mixer_voice[i].playing) &&
575 ((_phys_voice[i].vol > 0) || (_phys_voice[i].dvol > 0))) {
576 if ((_phys_voice[i].dvol) || (_phys_voice[i].dfreq) || (_phys_voice[i].dpan)) {
577 if (mixer_voice[i].data8)
578 mix_mono_8_samples_slow(mixer_voice+i, _phys_voice+i, p, mix_size);
580 mix_mono_16_samples_slow(mixer_voice+i, _phys_voice+i, p, mix_size);
583 if (mixer_voice[i].data8)
584 mix_mono_8_samples(mixer_voice+i, _phys_voice+i, p, mix_size);
586 mix_mono_16_samples(mixer_voice+i, _phys_voice+i, p, mix_size);
594 /* transfer to conventional memory buffer */
597 for (i=0; i<mix_size; i++) {
598 _farnspokew(buf, mix_clip_table[*p >> (16-MIX_RES_16)] ^ 0x8000);
604 for (i=0; i<mix_size; i++) {
605 _farnspokew(buf, mix_clip_table[*p >> (16-MIX_RES_16)]);
612 for (i=0; i<mix_size; i++) {
613 _farnspokeb(buf, mix_clip_table[*p >> (16-MIX_RES_8)]);
620 END_OF_FUNCTION(_mix_some_samples);
624 /* _mixer_init_voice:
625 * Initialises the specificed voice ready for playing a sample.
627 void _mixer_init_voice(int voice, SAMPLE *sample)
629 mixer_voice[voice].playing = FALSE;
630 mixer_voice[voice].pos = 0;
631 mixer_voice[voice].len = sample->len << MIXER_FIX_SHIFT;
632 mixer_voice[voice].loop_start = sample->loop_start << MIXER_FIX_SHIFT;
633 mixer_voice[voice].loop_end = sample->loop_end << MIXER_FIX_SHIFT;
635 if (sample->bits == 8) {
636 mixer_voice[voice].data8 = sample->data;
637 mixer_voice[voice].data16 = NULL;
640 mixer_voice[voice].data8 = NULL;
641 mixer_voice[voice].data16 = sample->data;
644 update_mixer_volume(mixer_voice+voice, _phys_voice+voice);
645 update_mixer_freq(mixer_voice+voice, _phys_voice+voice);
648 END_OF_FUNCTION(_mixer_init_voice);
652 /* _mixer_release_voice:
653 * Releases a voice when it is no longer required.
655 void _mixer_release_voice(int voice)
657 mixer_voice[voice].playing = FALSE;
658 mixer_voice[voice].data8 = NULL;
659 mixer_voice[voice].data16 = NULL;
662 END_OF_FUNCTION(_mixer_release_voice);
666 /* _mixer_start_voice:
667 * Activates a voice, with the currently selected parameters.
669 void _mixer_start_voice(int voice)
671 if (mixer_voice[voice].pos >= mixer_voice[voice].len)
672 mixer_voice[voice].pos = 0;
674 mixer_voice[voice].playing = TRUE;
677 END_OF_FUNCTION(_mixer_start_voice);
681 /* _mixer_stop_voice:
682 * Stops a voice from playing.
684 void _mixer_stop_voice(int voice)
686 mixer_voice[voice].playing = FALSE;
689 END_OF_FUNCTION(_mixer_stop_voice);
693 /* _mixer_loop_voice:
694 * Sets the loopmode for a voice.
696 void _mixer_loop_voice(int voice, int loopmode)
698 update_mixer_freq(mixer_voice+voice, _phys_voice+voice);
701 END_OF_FUNCTION(_mixer_loop_voice);
705 /* _mixer_get_position:
706 * Returns the current play position of a voice, or -1 if it has finished.
708 int _mixer_get_position(int voice)
710 if (mixer_voice[voice].pos >= mixer_voice[voice].len)
713 return (mixer_voice[voice].pos >> MIXER_FIX_SHIFT);
716 END_OF_FUNCTION(_mixer_get_position);
720 /* _mixer_set_position:
721 * Sets the current play position of a voice.
723 void _mixer_set_position(int voice, int position)
725 mixer_voice[voice].pos = (position << MIXER_FIX_SHIFT);
727 if (mixer_voice[voice].pos >= mixer_voice[voice].len)
728 mixer_voice[voice].playing = FALSE;
731 END_OF_FUNCTION(_mixer_set_position);
735 /* _mixer_get_volume:
736 * Returns the current volume of a voice.
738 int _mixer_get_volume(int voice)
740 return (_phys_voice[voice].vol >> 12);
743 END_OF_FUNCTION(_mixer_get_volume);
747 /* _mixer_set_volume:
748 * Sets the volume of a voice.
750 void _mixer_set_volume(int voice, int volume)
752 update_mixer_volume(mixer_voice+voice, _phys_voice+voice);
755 END_OF_FUNCTION(_mixer_set_volume);
759 /* _mixer_ramp_volume:
760 * Starts a volume ramping operation.
762 void _mixer_ramp_volume(int voice, int time, int endvol)
764 int d = (endvol << 12) - _phys_voice[voice].vol;
765 time = MAX(time * (mix_freq / UPDATE_FREQ) / 1000, 1);
767 _phys_voice[voice].target_vol = endvol << 12;
768 _phys_voice[voice].dvol = d / time;
771 END_OF_FUNCTION(_mixer_ramp_volume);
775 /* _mixer_stop_volume_ramp:
776 * Ends a volume ramp operation.
778 void _mixer_stop_volume_ramp(int voice)
780 _phys_voice[voice].dvol = 0;
783 END_OF_FUNCTION(_mixer_stop_volume_ramp);
787 /* _mixer_get_frequency:
788 * Returns the current frequency of a voice.
790 int _mixer_get_frequency(int voice)
792 return (_phys_voice[voice].freq >> 12);
795 END_OF_FUNCTION(_mixer_get_frequency);
799 /* _mixer_set_frequency:
800 * Sets the frequency of a voice.
802 void _mixer_set_frequency(int voice, int frequency)
804 update_mixer_freq(mixer_voice+voice, _phys_voice+voice);
807 END_OF_FUNCTION(_mixer_set_frequency);
811 /* _mixer_sweep_frequency:
812 * Starts a frequency sweep.
814 void _mixer_sweep_frequency(int voice, int time, int endfreq)
816 int d = (endfreq << 12) - _phys_voice[voice].freq;
817 time = MAX(time * (mix_freq / UPDATE_FREQ) / 1000, 1);
819 _phys_voice[voice].target_freq = endfreq << 12;
820 _phys_voice[voice].dfreq = d / time;
823 END_OF_FUNCTION(_mixer_sweep_frequency);
827 /* _mixer_stop_frequency_sweep:
828 * Ends a frequency sweep.
830 void _mixer_stop_frequency_sweep(int voice)
832 _phys_voice[voice].dfreq = 0;
835 END_OF_FUNCTION(_mixer_stop_frequency_sweep);
840 * Returns the current pan position of a voice.
842 int _mixer_get_pan(int voice)
844 return (_phys_voice[voice].pan >> 12);
847 END_OF_FUNCTION(_mixer_get_pan);
852 * Sets the pan position of a voice.
854 void _mixer_set_pan(int voice, int pan)
856 update_mixer_volume(mixer_voice+voice, _phys_voice+voice);
859 END_OF_FUNCTION(_mixer_set_pan);
864 * Starts a pan sweep.
866 void _mixer_sweep_pan(int voice, int time, int endpan)
868 int d = (endpan << 12) - _phys_voice[voice].pan;
869 time = MAX(time * (mix_freq / UPDATE_FREQ) / 1000, 1);
871 _phys_voice[voice].target_pan = endpan << 12;
872 _phys_voice[voice].dpan = d / time;
875 END_OF_FUNCTION(_mixer_sweep_pan);
879 /* _mixer_stop_pan_sweep:
882 void _mixer_stop_pan_sweep(int voice)
884 _phys_voice[voice].dpan = 0;
887 END_OF_FUNCTION(_mixer_stop_pan_sweep);
892 * Sets the echo parameters for a voice.
894 void _mixer_set_echo(int voice, int strength, int delay)
896 /* not implemented */
899 END_OF_FUNCTION(_mixer_set_echo);
903 /* _mixer_set_tremolo:
904 * Sets the tremolo parameters for a voice.
906 void _mixer_set_tremolo(int voice, int rate, int depth)
908 /* not implemented */
911 END_OF_FUNCTION(_mixer_set_tremolo);
915 /* _mixer_set_vibrato:
916 * Sets the amount of vibrato for a voice.
918 void _mixer_set_vibrato(int voice, int rate, int depth)
920 /* not implemented */
923 END_OF_FUNCTION(_mixer_set_vibrato);
928 * Locks memory used by the functions in this file.
930 static void mixer_lock_mem()
932 LOCK_VARIABLE(mixer_voice);
933 LOCK_VARIABLE(mix_buffer);
934 LOCK_VARIABLE(mix_vol_table);
935 LOCK_VARIABLE(mix_clip_table);
936 LOCK_VARIABLE(mix_voices);
937 LOCK_VARIABLE(mix_size);
938 LOCK_VARIABLE(mix_freq);
939 LOCK_VARIABLE(mix_stereo);
940 LOCK_VARIABLE(mix_16bit);
941 LOCK_FUNCTION(mix_mono_8_samples);
942 LOCK_FUNCTION(mix_stereo_8_samples);
943 LOCK_FUNCTION(mix_mono_16_samples);
944 LOCK_FUNCTION(mix_stereo_16_samples);
945 LOCK_FUNCTION(mix_mono_8_samples_slow);
946 LOCK_FUNCTION(mix_stereo_8_samples_slow);
947 LOCK_FUNCTION(mix_mono_16_samples_slow);
948 LOCK_FUNCTION(mix_stereo_16_samples_slow);
949 LOCK_FUNCTION(_mix_some_samples);
950 LOCK_FUNCTION(_mixer_init_voice);
951 LOCK_FUNCTION(_mixer_release_voice);
952 LOCK_FUNCTION(_mixer_start_voice);
953 LOCK_FUNCTION(_mixer_stop_voice);
954 LOCK_FUNCTION(_mixer_loop_voice);
955 LOCK_FUNCTION(_mixer_get_position);
956 LOCK_FUNCTION(_mixer_set_position);
957 LOCK_FUNCTION(_mixer_get_volume);
958 LOCK_FUNCTION(_mixer_set_volume);
959 LOCK_FUNCTION(_mixer_ramp_volume);
960 LOCK_FUNCTION(_mixer_stop_volume_ramp);
961 LOCK_FUNCTION(_mixer_get_frequency);
962 LOCK_FUNCTION(_mixer_set_frequency);
963 LOCK_FUNCTION(_mixer_sweep_frequency);
964 LOCK_FUNCTION(_mixer_stop_frequency_sweep);
965 LOCK_FUNCTION(_mixer_get_pan);
966 LOCK_FUNCTION(_mixer_set_pan);
967 LOCK_FUNCTION(_mixer_sweep_pan);
968 LOCK_FUNCTION(_mixer_stop_pan_sweep);
969 LOCK_FUNCTION(_mixer_set_echo);
970 LOCK_FUNCTION(_mixer_set_tremolo);
971 LOCK_FUNCTION(_mixer_set_vibrato);