Mercurial > almixer_isolated
comparison SDL_ALmixer.h @ 1:a8a8fe374984
Subversion era
author | Eric Wing <ewing . public |-at-| gmail . com> |
---|---|
date | Wed, 27 Oct 2010 16:51:16 -0700 |
parents | 01e39f9f58d5 |
children | 279d0427ef26 |
comparison
equal
deleted
inserted
replaced
0:01e39f9f58d5 | 1:a8a8fe374984 |
---|---|
21 */ | 21 */ |
22 #ifndef _SDL_ALMIXER_H_ | 22 #ifndef _SDL_ALMIXER_H_ |
23 #define _SDL_ALMIXER_H_ | 23 #define _SDL_ALMIXER_H_ |
24 | 24 |
25 #include "SDL_types.h" | 25 #include "SDL_types.h" |
26 /* | |
27 #include "SDL_rwops.h" | 26 #include "SDL_rwops.h" |
27 #include "SDL_error.h" | |
28 #include "SDL_version.h" | |
29 /* | |
28 #include "SDL_audio.h" | 30 #include "SDL_audio.h" |
29 #include "SDL_byteorder.h" | 31 #include "SDL_byteorder.h" |
30 */ | 32 */ |
31 #include "SDL_version.h" | |
32 | 33 |
33 /* | 34 /* |
34 #include "begin_code.h" | 35 #include "begin_code.h" |
35 */ | 36 */ |
36 | 37 |
38 /* | |
37 #include "SDL_sound.h" | 39 #include "SDL_sound.h" |
40 */ | |
41 /* Crap! altypes.h is missing from 1.1 | |
38 #include "altypes.h" | 42 #include "altypes.h" |
43 */ | |
44 #include "al.h" | |
39 | 45 |
40 /* Set up for C function definitions, even when using C++ */ | 46 /* Set up for C function definitions, even when using C++ */ |
41 #ifdef __cplusplus | 47 #ifdef __cplusplus |
42 extern "C" { | 48 extern "C" { |
43 #endif | 49 #endif |
79 /* Default Queue Buffers must be at least 2 */ | 85 /* Default Queue Buffers must be at least 2 */ |
80 #define ALMIXER_DEFAULT_QUEUE_BUFFERS 5 | 86 #define ALMIXER_DEFAULT_QUEUE_BUFFERS 5 |
81 /* Default startup buffers should be at least 1 */ | 87 /* Default startup buffers should be at least 1 */ |
82 #define ALMIXER_DEFAULT_STARTUP_BUFFERS 2 | 88 #define ALMIXER_DEFAULT_STARTUP_BUFFERS 2 |
83 | 89 |
90 /* | |
84 #define ALMIXER_DECODE_STREAM 0 | 91 #define ALMIXER_DECODE_STREAM 0 |
85 #define ALMIXER_DECODE_ALL 1 | 92 #define ALMIXER_DECODE_ALL 1 |
93 */ | |
86 | 94 |
87 | 95 |
88 #define ALmixer_GetError SDL_GetError | 96 #define ALmixer_GetError SDL_GetError |
89 #define ALmixer_SetError SDL_SetError | 97 #define ALmixer_SetError SDL_SetError |
90 | 98 |
91 typedef struct { | 99 |
92 ALuint albuffer; | 100 /* This is a trick I picked up from Lua. Doing the typedef separately |
93 Sint32 index; /* might not need */ | 101 * (and I guess before the definition) instead of a single |
94 Uint8* data; | 102 * entry: typedef struct {...} YourName; seems to allow me |
95 Uint32 num_bytes; | 103 * to use forward declarations. Doing it the other way (like SDL) |
96 } Buffer_Map; | 104 * seems to prevent me from using forward declarions as I get conflicting |
97 | 105 * definition errors. I don't really understand why though. |
98 typedef struct { | 106 */ |
99 Uint8 decoded_all; /* dictates different behaviors */ | 107 typedef struct ALmixer_Data ALmixer_Data; |
100 Sint32 total_time; /* total playing time of sample (msec) */ | 108 typedef struct ALmixer_AudioInfo ALmixer_AudioInfo; |
101 | 109 |
102 Uint32 in_use; /* needed to prevent sharing for streams */ | 110 /** |
103 Uint8 eof; /* flag for eof, only used for streams */ | 111 * Equvialent to the Sound_AudioInfo struct in SDL_sound. |
104 | 112 * Originally, I just used the Sound_AudioInfo directly, but |
105 Uint32 total_bytes; /* For predecoded */ | 113 * I've been trying to reduce the header dependencies for this file. |
106 Uint32 loaded_bytes; /* For predecoded (for seek) */ | 114 * But more to the point, I've been interested in dealing with the |
107 | 115 * WinMain override problem Josh faced when trying to use SDL components |
108 Sound_Sample* sample; /* SDL_Sound provides the data */ | 116 * in an MFC app which didn't like losing control of WinMain. |
109 ALuint* buffer; /* array of OpenAL buffers (at least 1 for predecoded) */ | 117 * My theory is that if I can purge the header of any thing that |
110 | 118 * #include's SDL_main.h, then this might work. |
111 /* Needed for streamed buffers */ | 119 * So I am now introducing my own AudioInfo struct. |
112 Uint32 max_queue_buffers; /* Max number of queue buffers */ | 120 */ |
113 Uint32 num_startup_buffers; /* Number of ramp-up buffers */ | 121 struct ALmixer_AudioInfo |
114 Uint8 num_buffers_in_use; /* number of buffers in use */ | 122 { |
115 | 123 Uint16 format; /**< Equivalent of SDL_AudioSpec.format. */ |
116 /* This stuff is for streamed buffers that require data access */ | 124 Uint8 channels; /**< Number of sound channels. 1 == mono, 2 == stereo. */ |
117 Buffer_Map* buffer_map_list; /* translate ALbuffer to index | 125 Uint32 rate; /**< Sample rate; frequency of sample points per second. */ |
118 and holds pointer to copy of data for | 126 }; |
119 data access */ | |
120 ALuint current_buffer; /* The current playing buffer */ | |
121 | |
122 /* Nvidia distribution refuses to recognize a simple buffer query command | |
123 * unlike all other distributions. It's forcing me to redo the code | |
124 * to accomodate this Nvidia flaw by making me maintain a "best guess" | |
125 * copy of what I think the buffer queue state looks like. | |
126 * A circular queue would a helpful data structure for this task, | |
127 * but I wanted to avoid making an additional header requirement, | |
128 * so I'm making it a void* | |
129 */ | |
130 void* circular_buffer_queue; | |
131 | |
132 | |
133 } ALmixer_Data; | |
134 | 127 |
135 | 128 |
136 #if 0 | 129 #if 0 |
137 typedef struct { | 130 typedef struct { |
138 Sound_Sample* sample; | 131 Sound_Sample* sample; |
172 * clean up everything. | 165 * clean up everything. |
173 */ | 166 */ |
174 extern DECLSPEC Sint32 SDLCALL ALmixer_Init_Mixer(Sint32 num_sources); | 167 extern DECLSPEC Sint32 SDLCALL ALmixer_Init_Mixer(Sint32 num_sources); |
175 | 168 |
176 extern DECLSPEC void SDLCALL ALmixer_Quit(); | 169 extern DECLSPEC void SDLCALL ALmixer_Quit(); |
177 extern DECLSPEC Uint8 SDLCALL ALmixer_IsInitialized(); | 170 extern DECLSPEC SDL_bool SDLCALL ALmixer_IsInitialized(); |
178 | 171 |
179 extern DECLSPEC Uint32 SDLCALL ALmixer_GetFrequency(); | 172 extern DECLSPEC Uint32 SDLCALL ALmixer_GetFrequency(); |
180 | 173 |
181 extern DECLSPEC Sint32 SDLCALL ALmixer_AllocateChannels(Sint32 numchans); | 174 extern DECLSPEC Sint32 SDLCALL ALmixer_AllocateChannels(Sint32 numchans); |
182 extern DECLSPEC Sint32 SDLCALL ALmixer_ReserveChannels(Sint32 num); | 175 extern DECLSPEC Sint32 SDLCALL ALmixer_ReserveChannels(Sint32 num); |
183 | 176 |
184 extern DECLSPEC ALmixer_Data * SDLCALL ALmixer_LoadSample_RW(SDL_RWops* rwops, const char* fileext, Uint32 buffersize, Uint8 decode_mode, Uint32 max_queue_buffers, Uint32 num_startup_buffers, Uint8 access_data); | 177 extern DECLSPEC ALmixer_Data * SDLCALL ALmixer_LoadSample_RW(SDL_RWops* rwops, const char* fileext, Uint32 buffersize, SDL_bool decode_mode_is_predecoded, Uint32 max_queue_buffers, Uint32 num_startup_buffers, SDL_bool access_data); |
185 | 178 |
186 | 179 |
187 #define ALmixer_LoadStream_RW(rwops,fileext,buffersize,max_queue_buffers,num_startup_buffers,access_data) ALmixer_LoadSample_RW(rwops,fileext,buffersize,ALMIXER_DECODE_STREAM, max_queue_buffers, num_startup_buffers,access_data) | 180 #define ALmixer_LoadStream_RW(rwops,fileext,buffersize,max_queue_buffers,num_startup_buffers,access_data) ALmixer_LoadSample_RW(rwops,fileext,buffersize, SDL_FALSE, max_queue_buffers, num_startup_buffers,access_data) |
188 | 181 |
189 #define ALmixer_LoadAll_RW(rwops,fileext,buffersize,access_data) ALmixer_LoadSample_RW(rwops,fileext,buffersize,ALMIXER_DECODE_ALL, 0, 0,access_data) | 182 #define ALmixer_LoadAll_RW(rwops,fileext,buffersize,access_data) ALmixer_LoadSample_RW(rwops,fileext,buffersize, SDL_TRUE, 0, 0,access_data) |
190 | 183 |
191 | 184 |
192 | 185 |
193 extern DECLSPEC ALmixer_Data * SDLCALL ALmixer_LoadSample(const char* filename, Uint32 buffersize, Uint8 decode_mode, Uint32 max_queue_buffers, Uint32 num_startup_buffers, Uint8 access_data); | 186 extern DECLSPEC ALmixer_Data * SDLCALL ALmixer_LoadSample(const char* filename, Uint32 buffersize, SDL_bool decode_mode_is_predecoded, Uint32 max_queue_buffers, Uint32 num_startup_buffers, SDL_bool access_data); |
194 | 187 |
195 | 188 |
196 #define ALmixer_LoadStream(filename,buffersize,max_queue_buffers,num_startup_buffers,access_data) ALmixer_LoadSample(filename,buffersize,ALMIXER_DECODE_STREAM, max_queue_buffers, num_startup_buffers,access_data) | 189 #define ALmixer_LoadStream(filename,buffersize,max_queue_buffers,num_startup_buffers,access_data) ALmixer_LoadSample(filename,buffersize, SDL_FALSE, max_queue_buffers, num_startup_buffers,access_data) |
197 | 190 |
198 #define ALmixer_LoadAll(filename,buffersize,access_data) ALmixer_LoadSample(filename,buffersize,ALMIXER_DECODE_ALL, 0, 0,access_data) | 191 #define ALmixer_LoadAll(filename,buffersize,access_data) ALmixer_LoadSample(filename,buffersize, SDL_TRUE, 0, 0,access_data) |
199 | 192 |
200 | 193 |
201 extern DECLSPEC ALmixer_Data * SDLCALL ALmixer_LoadSample_RAW_RW(SDL_RWops* rwops, const char* fileext, Sound_AudioInfo* desired, Uint32 buffersize, Uint8 decode_mode, Uint32 max_queue_buffers, Uint32 num_startup_buffers, Uint8 access_data); | 194 extern DECLSPEC ALmixer_Data * SDLCALL ALmixer_LoadSample_RAW_RW(SDL_RWops* rwops, const char* fileext, ALmixer_AudioInfo* desired, Uint32 buffersize, SDL_bool decode_mode_is_predecoded, Uint32 max_queue_buffers, Uint32 num_startup_buffers, SDL_bool access_data); |
202 | 195 |
203 #define ALmixer_LoadStream_RAW_RW(rwops,fileext,desired,buffersize,max_queue_buffers,num_startup_buffers,access_data) ALmixer_LoadSample_RAW_RW(rwops,fileext,desired,buffersize,ALMIXER_DECODE_STREAM, max_queue_buffers, num_startup_buffers,access_data) | 196 #define ALmixer_LoadStream_RAW_RW(rwops,fileext,desired,buffersize,max_queue_buffers,num_startup_buffers,access_data) ALmixer_LoadSample_RAW_RW(rwops,fileext,desired,buffersize, SDL_FALSE, max_queue_buffers, num_startup_buffers,access_data) |
204 | 197 |
205 #define ALmixer_LoadAll_RAW_RW(rwops,fileext,desired,buffersize,access_data) ALmixer_LoadSample_RAW_RW(rwops,fileext,desired,buffersize,ALMIXER_DECODE_ALL, 0, 0,access_data) | 198 #define ALmixer_LoadAll_RAW_RW(rwops,fileext,desired,buffersize,access_data) ALmixer_LoadSample_RAW_RW(rwops,fileext,desired,buffersize, SDL_TRUE, 0, 0,access_data) |
206 | 199 |
207 extern DECLSPEC ALmixer_Data * SDLCALL ALmixer_LoadSample_RAW(const char* filename, Sound_AudioInfo* desired, Uint32 buffersize, Uint8 decode_mode, Uint32 max_queue_buffers, Uint32 num_startup_buffers, Uint8 access_data); | 200 extern DECLSPEC ALmixer_Data * SDLCALL ALmixer_LoadSample_RAW(const char* filename, ALmixer_AudioInfo* desired, Uint32 buffersize, SDL_bool decode_mode_is_predecoded, Uint32 max_queue_buffers, Uint32 num_startup_buffers, SDL_bool access_data); |
208 | 201 |
209 | 202 |
210 | 203 |
211 extern DECLSPEC void SDLCALL ALmixer_FreeData(ALmixer_Data* data); | 204 extern DECLSPEC void SDLCALL ALmixer_FreeData(ALmixer_Data* data); |
212 | 205 |
247 extern DECLSPEC Sint32 SDLCALL ALmixer_GetChannel(ALuint source); | 240 extern DECLSPEC Sint32 SDLCALL ALmixer_GetChannel(ALuint source); |
248 | 241 |
249 extern DECLSPEC Sint32 SDLCALL ALmixer_FindFreeChannel(Sint32 start_channel); | 242 extern DECLSPEC Sint32 SDLCALL ALmixer_FindFreeChannel(Sint32 start_channel); |
250 | 243 |
251 extern DECLSPEC void SDLCALL ALmixer_ChannelFinished(void (*channel_finished)(Sint32 channel, void* userdata), void* userdata); | 244 extern DECLSPEC void SDLCALL ALmixer_ChannelFinished(void (*channel_finished)(Sint32 channel, void* userdata), void* userdata); |
245 | |
246 /* | |
252 extern DECLSPEC void SDLCALL ALmixer_ChannelData(void (*channel_data)(Sint32 which_chan, Uint8* data, Uint32 num_bytes, Uint32 frequency, Uint8 channels, Uint8 bitdepth, Uint16 format, Uint8 decode_mode)); | 247 extern DECLSPEC void SDLCALL ALmixer_ChannelData(void (*channel_data)(Sint32 which_chan, Uint8* data, Uint32 num_bytes, Uint32 frequency, Uint8 channels, Uint8 bitdepth, Uint16 format, Uint8 decode_mode)); |
248 */ | |
249 /** | |
250 * Audio data callback system. | |
251 * This is a callback function pointer that when set, will trigger a function | |
252 * anytime there is new data loaded for a sample. The appropriate load | |
253 * parameter must be set in order for a sample to appear here. | |
254 * Keep in mind the the current backend implementation must do an end run | |
255 * around OpenAL because OpenAL lacks support for this kind of thing. | |
256 * As such, buffers are copied at decode time, and there is no attempt to do | |
257 * fine grained timing syncronization. You will be provided the entire buffer | |
258 * that is decoded regardless of length. So if you predecoded the entire | |
259 * audio file, the entire data buffer will be provided in a single callback. | |
260 * If you stream the data, you will be getting chunk sizes that are the same as | |
261 * what you specified the decode size to be. Unfortunely, this means if you | |
262 * pick smaller buffers, you get finer detail at the expense/risk of buffer | |
263 * underruns. If you decode more data, you have to deal with the syncronization | |
264 * issues if you want to display the data during playback in something like an | |
265 * oscilloscope. | |
266 * | |
267 * @param which_chan The ALmixer channel that the data is currently playing on. | |
268 * @param data This is a pointer to the data buffer containing ALmixer's | |
269 * version of the decoded data. Consider this data as read-only. In the | |
270 * non-threaded backend, this data will persist until potentially the next call | |
271 * to Update(). Currently, data buffers are preallocated and not destroyed | |
272 * until FreeData() is called (though this behavior is subject to change), | |
273 * but the contents will change when the buffer needs to be reused for a | |
274 * future callback. The buffer reuse is tied to the amount of buffers that | |
275 * may be queued. | |
276 * But assuming I don't change this, this may allow for some optimization | |
277 * so you can try referencing data from these buffers without worrying | |
278 * about crashing. (You still need to be aware that the data could be | |
279 * modified behind the scenes on an Update().) | |
280 * | |
281 * The data type listed is an Unsigned 8-bit format, but the real data may | |
282 * not actually be this. Uint8 was chosen as a convenience. If you have | |
283 * a 16 bit format, you will want to cast the data and also divide the num_bytes | |
284 * by 2. Typically, data is either Sint16 or Uint8. This seems to be a | |
285 * convention audio people seem to follow though I'm not sure what the | |
286 * underlying reasons (if any) are for this. I suspect that there may be | |
287 * some nice alignment/conversion property if you need to cast from Uint8 | |
288 * to Sint16. | |
289 * | |
290 * @param num_bytes This is the total length of the data buffer. It presumes | |
291 * that this length is measured for Uint8. So if you have Sint16 data, you | |
292 * should divide num_bytes by two if you access the data as Sint16. | |
293 * | |
294 * @param frequency The frequency the data was decoded at. | |
295 * | |
296 * @param channels 1 for mono, 2 for stereo. | |
297 * | |
298 * @param bit_depth Bits per sample. This is expected to be 8 or 16. This | |
299 * number will tell you if you if you need to treat the data buffer as | |
300 * 16 bit or not. | |
301 * | |
302 * @param is_unsigned 1 if the data is unsigned, 0 if signed. Using this | |
303 * combined with bit_depth will tell you if you need to treat the data | |
304 * as Uint8, Sint8, Uint32, or Sint32. | |
305 * | |
306 * @param decode_mode_is_predecoded This is here to tell you if the data was totally | |
307 * predecoded or loaded as a stream. If predecoded, you will only get | |
308 * one data callback per playback instance. (This might also be true for | |
309 * looping the same sample...I don't remember how it was implemented. | |
310 * Maybe this should be fixed.) | |
311 * 0 (ALMIXER_DECODE_STREAM) for streamed. | |
312 * 1 (ALMIXER_DECODE_ALL) for predecoded. | |
313 * | |
314 * @param length_in_msec This returns the total length (time) of the data | |
315 * buffer in milliseconds. This could be computed yourself, but is provided | |
316 * as a convenince. | |
317 * | |
318 * | |
319 */ | |
320 extern DECLSPEC void SDLCALL ALmixer_ChannelData(void (*channel_data)(Sint32 which_chan, Uint8* data, Uint32 num_bytes, Uint32 frequency, Uint8 channels, Uint8 bit_depth, SDL_bool is_unsigned, SDL_bool decode_mode_is_predecoded, Uint32 length_in_msec, void* user_data), void* user_data); | |
253 | 321 |
254 | 322 |
255 extern DECLSPEC Sint32 SDLCALL ALmixer_HaltChannel(Sint32 channel); | 323 extern DECLSPEC Sint32 SDLCALL ALmixer_HaltChannel(Sint32 channel); |
256 extern DECLSPEC Sint32 SDLCALL ALmixer_HaltSource(ALuint source); | 324 extern DECLSPEC Sint32 SDLCALL ALmixer_HaltSource(ALuint source); |
257 | 325 |
319 extern DECLSPEC Sint32 SDLCALL ALmixer_CountUnreservedFreeChannels(); | 387 extern DECLSPEC Sint32 SDLCALL ALmixer_CountUnreservedFreeChannels(); |
320 extern DECLSPEC Sint32 SDLCALL ALmixer_CountAllUsedChannels(); | 388 extern DECLSPEC Sint32 SDLCALL ALmixer_CountAllUsedChannels(); |
321 extern DECLSPEC Sint32 SDLCALL ALmixer_CountUnreservedUsedChannels(); | 389 extern DECLSPEC Sint32 SDLCALL ALmixer_CountUnreservedUsedChannels(); |
322 #define ALmixer_CountTotalChannels() ALmixer_AllocateChannels(-1) | 390 #define ALmixer_CountTotalChannels() ALmixer_AllocateChannels(-1) |
323 #define ALmixer_CountReservedChannels() ALmixer_ReserveChannels(-1) | 391 #define ALmixer_CountReservedChannels() ALmixer_ReserveChannels(-1) |
392 | |
393 extern DECLSPEC SDL_bool SDLCALL ALmixer_IsPredecoded(ALmixer_Data* data); | |
324 | 394 |
325 | 395 |
326 | 396 |
327 /* For testing */ | 397 /* For testing */ |
328 #if 0 | 398 #if 0 |