Mercurial > sdl-ios-xcode
comparison src/audio/riscos/SDL_drenderer.c @ 955:d74fbf56f2f6
Date: Fri, 25 Jun 2004 13:29:15 +0100
From: "alan buckley"
Subject: Modification for RISC OS version of SDL
Ive attached a zip file with the changes to this email, it contains the
following:
The file sdldiff.txt is the output from cvs diff u. .
The directory thread/riscos contains all the new files to support threading.
Readme.riscos is a new readme file to add.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 17 Sep 2004 13:20:10 +0000 |
parents | b8d311d90021 |
children |
comparison
equal
deleted
inserted
replaced
954:3acd16ea0180 | 955:d74fbf56f2f6 |
---|---|
32 #include "SDL_audio.h" | 32 #include "SDL_audio.h" |
33 #include "SDL_audio_c.h" | 33 #include "SDL_audio_c.h" |
34 #include "SDL_audiomem.h" | 34 #include "SDL_audiomem.h" |
35 #include "SDL_sysaudio.h" | 35 #include "SDL_sysaudio.h" |
36 #include "SDL_drenderer.h" | 36 #include "SDL_drenderer.h" |
37 | |
38 #ifndef DISABLE_THREADS | |
39 #include <pthread.h> | |
40 #endif | |
37 | 41 |
38 #define DigitalRenderer_Activate 0x4F700 | 42 #define DigitalRenderer_Activate 0x4F700 |
39 #define DigitalRenderer_Deactivate 0x4F701 | 43 #define DigitalRenderer_Deactivate 0x4F701 |
40 #define DigitalRenderer_ReadState 0x4F705 | 44 #define DigitalRenderer_ReadState 0x4F705 |
41 #define DigitalRenderer_NewSample 0x4F706 | 45 #define DigitalRenderer_NewSample 0x4F706 |
55 /* Audio driver functions */ | 59 /* Audio driver functions */ |
56 | 60 |
57 static void DRenderer_CloseAudio(_THIS); | 61 static void DRenderer_CloseAudio(_THIS); |
58 static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec); | 62 static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec); |
59 | 63 |
64 #ifndef DISABLE_THREADS | |
65 static void DRenderer_WaitAudio(_THIS); | |
66 static Uint8 *DRenderer_GetAudioBuf(_THIS); | |
67 static void DRenderer_PlayAudio(_THIS); | |
68 #endif | |
69 | |
60 /* Audio driver bootstrap functions */ | 70 /* Audio driver bootstrap functions */ |
61 | 71 |
62 /* Define following to dump stats to stdout */ | 72 /* Define following to dump stats to stdout */ |
63 /* #define DUMP_AUDIO */ | 73 /* #define DUMP_AUDIO */ |
64 | 74 |
102 memset(this->hidden, 0, (sizeof *this->hidden)); | 112 memset(this->hidden, 0, (sizeof *this->hidden)); |
103 | 113 |
104 /* Set the function pointers */ | 114 /* Set the function pointers */ |
105 this->OpenAudio = DRenderer_OpenAudio; | 115 this->OpenAudio = DRenderer_OpenAudio; |
106 this->CloseAudio = DRenderer_CloseAudio; | 116 this->CloseAudio = DRenderer_CloseAudio; |
117 #ifndef DISABLE_THREADS | |
118 this->GetAudioBuf = DRenderer_GetAudioBuf; | |
119 this->PlayAudio = DRenderer_PlayAudio; | |
120 this->WaitAudio = DRenderer_WaitAudio; | |
121 #endif | |
107 this->free = Audio_DeleteDevice; | 122 this->free = Audio_DeleteDevice; |
108 | 123 |
109 return this; | 124 return this; |
110 } | 125 } |
111 | 126 |
115 }; | 130 }; |
116 | 131 |
117 /* Routine called to check and fill audio buffers if necessary */ | 132 /* Routine called to check and fill audio buffers if necessary */ |
118 static Uint8 *buffer = NULL; | 133 static Uint8 *buffer = NULL; |
119 | 134 |
135 #ifdef DISABLE_THREADS | |
136 | |
137 /* Buffer fill routine called during polling */ | |
120 void DRenderer_FillBuffers() | 138 void DRenderer_FillBuffers() |
121 { | 139 { |
122 SDL_AudioDevice *audio = current_audio; | 140 SDL_AudioDevice *audio = current_audio; |
123 | 141 |
124 if ( !audio || ! audio->enabled ) | 142 if ( !audio || ! audio->enabled ) |
180 } | 198 } |
181 | 199 |
182 } | 200 } |
183 } | 201 } |
184 | 202 |
203 #endif | |
204 | |
185 /* Size of DMA buffer to use */ | 205 /* Size of DMA buffer to use */ |
186 #define DRENDERER_BUFFER_SIZE 512 | 206 #define DRENDERER_BUFFER_SIZE 512 |
187 | 207 |
188 /* Number of centiseconds of sound to buffer. | 208 /* Number of centiseconds of sound to buffer. |
189 Hopefully more than the maximum time between calls to the | 209 Hopefully more than the maximum time between calls to the |
190 FillBuffers routine above | 210 FillBuffers routine above (non-threaded) or the PlayAudio |
211 routine below (threaded). | |
191 */ | 212 */ |
213 | |
192 #define DRENDERER_CSEC_TO_BUFFER 10 | 214 #define DRENDERER_CSEC_TO_BUFFER 10 |
215 | |
216 static void DeactivateAudio() | |
217 { | |
218 _kernel_swi_regs regs; | |
219 | |
220 /* Close down the digital renderer */ | |
221 _kernel_swi(DigitalRenderer_Deactivate, ®s, ®s); | |
222 | |
223 if (buffer != NULL) | |
224 { | |
225 free(buffer); | |
226 buffer = NULL; | |
227 } | |
228 } | |
193 | 229 |
194 static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec) | 230 static int DRenderer_OpenAudio(_THIS, SDL_AudioSpec *spec) |
195 { | 231 { |
196 _kernel_swi_regs regs; | 232 _kernel_swi_regs regs; |
197 int buffers_per_sample; | 233 int buffers_per_sample; |
198 | 234 |
199 #ifdef DUMP_AUDIO | 235 #ifdef DUMP_AUDIO |
200 printf("Request format %d\n", spec->format); | 236 printf("Request format %d\n", spec->format); |
201 printf("Request freq %d\n", spec->freq); | 237 printf("Request freq %d\n", spec->freq); |
202 printf("Samples %d\n", spec->samples); | 238 printf("Samples %d\n", spec->samples); |
239 printf("Channels %d\n", spec->channels); | |
203 #endif | 240 #endif |
204 | 241 |
205 /* Only support signed 16bit format */ | 242 /* Only support signed 16bit format */ |
206 spec->format = AUDIO_S16LSB; | 243 spec->format = AUDIO_S16LSB; |
207 | 244 |
208 if (spec->samples < DRENDERER_BUFFER_SIZE) spec->samples = DRENDERER_BUFFER_SIZE; | 245 if (spec->samples < DRENDERER_BUFFER_SIZE) spec->samples = DRENDERER_BUFFER_SIZE; |
209 | 246 |
210 SDL_CalculateAudioSpec(spec); | |
211 | |
212 | |
213 buffers_per_sample = spec->samples / DRENDERER_BUFFER_SIZE; | 247 buffers_per_sample = spec->samples / DRENDERER_BUFFER_SIZE; |
214 | 248 |
215 if ((spec->samples % DRENDERER_BUFFER_SIZE) != 0) | 249 if ((spec->samples % DRENDERER_BUFFER_SIZE) != 0) |
216 { | 250 { |
217 buffers_per_sample++; | 251 buffers_per_sample++; |
218 spec->samples = buffers_per_sample * DRENDERER_BUFFER_SIZE; | 252 spec->samples = buffers_per_sample * DRENDERER_BUFFER_SIZE; |
219 } | 253 } |
254 | |
220 | 255 |
221 /* Set number of buffers to use - the following should give enough | 256 /* Set number of buffers to use - the following should give enough |
222 data between calls to the sound polling. | 257 data between calls to the sound polling. |
223 */ | 258 */ |
224 | 259 |
225 if (riscos_audiobuffer == 0) | 260 if (riscos_audiobuffer == 0) |
226 { | 261 { |
227 FillBuffer = (int)((double)DRENDERER_CSEC_TO_BUFFER / ((double)DRENDERER_BUFFER_SIZE * 100.0 / (double)spec->freq)) + 1; | 262 FillBuffer = (int)((double)DRENDERER_CSEC_TO_BUFFER / ((double)DRENDERER_BUFFER_SIZE * 100.0 / (double)spec->freq)) + 1; |
228 } else FillBuffer = riscos_audiobuffer/DRENDERER_BUFFER_SIZE - buffers_per_sample; | 263 } else FillBuffer = riscos_audiobuffer/DRENDERER_BUFFER_SIZE - buffers_per_sample; |
229 | 264 |
230 if (FillBuffer < buffers_per_sample) FillBuffer = buffers_per_sample; | 265 if (FillBuffer < buffers_per_sample) FillBuffer = buffers_per_sample; |
266 #ifndef DISABLE_THREADS | |
267 if (buffers_per_sample < FillBuffer) | |
268 { | |
269 /* For the threaded version we are only called once per cycle | |
270 so the callback needs to give us the full data we need in | |
271 one go, rather than multiple calls as it the case for the | |
272 non threaded version */ | |
273 buffers_per_sample = FillBuffer; | |
274 spec->samples = buffers_per_sample * DRENDERER_BUFFER_SIZE; | |
275 } | |
276 #endif | |
277 SDL_CalculateAudioSpec(spec); | |
231 regs.r[0] = FillBuffer + buffers_per_sample; | 278 regs.r[0] = FillBuffer + buffers_per_sample; |
232 | 279 |
233 #ifdef DUMP_AUDIO | 280 #ifdef DUMP_AUDIO |
234 printf("Buffers per sample %d\n", buffers_per_sample); | 281 printf("Buffers per sample %d\n", buffers_per_sample); |
235 printf("Fill buffer %d\n", FillBuffer); | 282 printf("Fill buffer %d\n", FillBuffer); |
257 if (_kernel_swi(DigitalRenderer_GetFrequency, ®s, ®s) == 0) | 304 if (_kernel_swi(DigitalRenderer_GetFrequency, ®s, ®s) == 0) |
258 { | 305 { |
259 spec->freq = regs.r[0]; | 306 spec->freq = regs.r[0]; |
260 } | 307 } |
261 | 308 |
309 /* Ensure sound is deactivated if we exit without calling SDL_Quit */ | |
310 atexit(DeactivateAudio); | |
311 | |
262 #ifdef DUMP_AUDIO | 312 #ifdef DUMP_AUDIO |
263 printf("Got format %d\n", spec->format); | 313 printf("Got format %d\n", spec->format); |
264 printf("Frequency %d\n", spec->freq); | 314 printf("Frequency %d\n", spec->freq); |
265 printf("Samples %d\n", spec->samples); | 315 printf("Samples %d\n", spec->samples); |
266 #endif | 316 #endif |
275 { | 325 { |
276 SDL_OutOfMemory(); | 326 SDL_OutOfMemory(); |
277 return -1; | 327 return -1; |
278 } | 328 } |
279 | 329 |
330 #ifdef DISABLE_THREADS | |
280 /* Hopefully returning 2 will show success, but not start up an audio thread */ | 331 /* Hopefully returning 2 will show success, but not start up an audio thread */ |
281 return 2; | 332 return 2; |
333 #else | |
334 /* Success and start audio thread */ | |
335 return 0; | |
336 #endif | |
282 } | 337 } |
283 | 338 |
284 static void DRenderer_CloseAudio(_THIS) | 339 static void DRenderer_CloseAudio(_THIS) |
285 { | 340 { |
341 DeactivateAudio(); | |
342 } | |
343 | |
344 #ifndef DISABLE_THREADS | |
345 | |
346 /* Routines for threaded version of audio */ | |
347 | |
348 void DRenderer_WaitAudio(_THIS) | |
349 { | |
350 _kernel_swi_regs regs; | |
351 int waiting = 1; | |
352 | |
353 while (waiting) | |
354 { | |
355 /* Check filled buffers count */ | |
356 _kernel_swi(DigitalRenderer_StreamStatistics, ®s, ®s); | |
357 #if 0 | |
358 if (regs.r[0] <= FillBuffer) | |
359 { | |
360 printf("Buffers in use %d\n", regs.r[0]); | |
361 } | |
362 #endif | |
363 if (regs.r[0] <= FillBuffer) waiting = 0; | |
364 else pthread_yield(); | |
365 } | |
366 } | |
367 | |
368 Uint8 *DRenderer_GetAudioBuf(_THIS) | |
369 { | |
370 return buffer; | |
371 } | |
372 | |
373 void DRenderer_PlayAudio(_THIS) | |
374 { | |
286 _kernel_swi_regs regs; | 375 _kernel_swi_regs regs; |
287 | 376 |
288 /* Close down the digital renderer */ | 377 regs.r[0] = (int)buffer; |
289 _kernel_swi(DigitalRenderer_Deactivate, ®s, ®s); | 378 regs.r[1] = current_audio->spec.samples * current_audio->spec.channels; |
290 | 379 _kernel_swi(DigitalRenderer_Stream16BitSamples, ®s, ®s); |
291 if (buffer != NULL) free(buffer); | 380 } |
292 } | 381 |
293 | 382 #endif |