comparison mixer/mixercore.c @ 486:859dd2ef3197

Added some seriously INCOMPLETE mixer code.
author Ryan C. Gordon <icculus@icculus.org>
date Sun, 27 Feb 2005 19:55:29 +0000
parents
children 2df1f5c62d38
comparison
equal deleted inserted replaced
485:137c0b00ea4c 486:859dd2ef3197
1 /*
2 * SDL_sound -- An sound processing toolkit.
3 * Copyright (C) 2001 Ryan C. Gordon.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library 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 GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser 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 02111-1307 USA
18 */
19
20 /**
21 * This file implements the mixer itself. Largely, this is handled in the
22 * SDL audio callback.
23 *
24 * Documentation is in SDL_sound.h ... It's verbose, honest. :)
25 *
26 * Please see the file COPYING in the source's root directory.
27 *
28 * This file written by Ryan C. Gordon. (icculus@clutteredmind.org)
29 */
30
31 #if HAVE_CONFIG_H
32 # include <config.h>
33 #endif
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 #include "SDL.h"
40 #include "SDL_thread.h"
41 #include "SDL_sound.h"
42
43 #define __SDL_SOUND_INTERNAL__
44 #include "SDL_sound_internal.h"
45
46
47
48 typedef struct S_PlayingList
49 {
50 Sound_Sample *sample;
51 struct S_PlayingList *next;
52 } PlayingList;
53
54 static PlayingList *playlist = NULL;
55
56 static inline void mix_predecoded(Sound_Sample *samp,
57 UInt32 *samp_frames_left,
58 float *gains)
59 {
60 Sound_SampleInternal *internal = (Sound_SampleInternal *) samp->opaque;
61 Uint32 sfl = *samp_frames_left; /* move to a local. */
62 Uint32 max = internal->buffer_size - internal->mix_position;
63 float *wptr; /* write pointer */
64
65 /* !!! FIXME: max must be converted to sample frame count... */
66
67 if (max > sfl) /* we have more data than mix buffer? */
68 max = sfl;
69
70 assert(max > 0);
71 *samp_frames_left -= max;
72
73 wptr = mixbuf + ((mixbufsize / sizeof (float)) - (max * MAX_CHANNELS));
74 internal->mix(wptr, internal->buffer, max, gains);
75 } /* mix_predecoded */
76
77
78 static void mix_playing_samples(Uint8 *stream, int len)
79 {
80 PlayingList *samples = playlist;
81 const int frames = len / framesize;
82 const Uint32 ticks = SDL_GetTicks(); /* used for calculating fade. */
83
84 while (samples) /* iterate linked list of playing samples... */
85 {
86 Sound_Sample *samp = samples->sample;
87 Uint32 sample_frames_left = mixbuf_frames;
88 float gains[MAX_CHANNELS];
89
90 calculate_gains(samp, ticks, gains);
91 while (sample_frames_left)
92 {
93 mix_predecoded(samp, &sample_frames_left);
94 if (!decode_more(samp))
95 break;
96 } /* while */
97
98 samples = samples->next; /* set up for next iteration. */
99 } /* while */
100 } /* mix_playing_samples */
101
102
103 static inline void run_pre_mix(void)
104 {
105 if (premixer)
106 premixer(mixbuf, mixbufsize);
107 else /* !!! FIXME: Do memset in another thread after mix is done. */
108 memset(mixbuf, '\0', mixbufsize * sizeof (float) * 2);
109 } /* run_pre_mix */
110
111
112 static inline void run_post_mix(void)
113 {
114 if (postmixer)
115 postmixer(mixbuf, mixbufsize);
116 } /* run_post_mix */
117
118
119 /* this is where it happens: the SDL audio callback. */
120 static void audio_callback(void *userdata, Uint8 *stream, int len)
121 {
122 mixer_callback_running = 1;
123 run_pre_mix();
124 mix_playing_samples();
125 run_post_mix();
126 mixer_callback_running = 0;
127 } /* audio_callback */
128
129 /* end of mixercore.c ... */
130