Mercurial > SDL_sound_CoreAudio
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 |