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, &regs, &regs);
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, &regs, &regs) == 0) 304 if (_kernel_swi(DigitalRenderer_GetFrequency, &regs, &regs) == 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, &regs, &regs);
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, &regs, &regs); 378 regs.r[1] = current_audio->spec.samples * current_audio->spec.channels;
290 379 _kernel_swi(DigitalRenderer_Stream16BitSamples, &regs, &regs);
291 if (buffer != NULL) free(buffer); 380 }
292 } 381
293 382 #endif