comparison src/audio/dc/SDL_dcaudio.c @ 3819:b225d9820ee3 SDL-ryan-multiple-audio-device

Updated a bunch of audio backends to 1.3 API (Dreamcast, OS/2, ALSA, and BeOS). None are tested, so anyu could fail to compile.
author Ryan C. Gordon <icculus@icculus.org>
date Fri, 06 Oct 2006 20:36:23 +0000
parents 9d070c1a45fa
children 66fb40445587
comparison
equal deleted inserted replaced
3818:49eadd6e8962 3819:b225d9820ee3
30 #include "../SDL_audio_c.h" 30 #include "../SDL_audio_c.h"
31 #include "SDL_dcaudio.h" 31 #include "SDL_dcaudio.h"
32 32
33 #include "aica.h" 33 #include "aica.h"
34 #include <dc/spu.h> 34 #include <dc/spu.h>
35
36 /* Audio driver functions */
37 static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec * spec);
38 static void DCAUD_WaitAudio(_THIS);
39 static void DCAUD_PlayAudio(_THIS);
40 static Uint8 *DCAUD_GetAudioBuf(_THIS);
41 static void DCAUD_CloseAudio(_THIS);
42
43 /* Audio driver bootstrap functions */
44 static int
45 DCAUD_Available(void)
46 {
47 return 1;
48 }
49
50 static void
51 DCAUD_DeleteDevice(SDL_AudioDevice * device)
52 {
53 SDL_free(device->hidden);
54 SDL_free(device);
55 }
56
57 static SDL_AudioDevice *
58 DCAUD_CreateDevice(int devindex)
59 {
60 SDL_AudioDevice *this;
61
62 /* Initialize all variables that we clean on shutdown */
63 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
64 if (this) {
65 SDL_memset(this, 0, (sizeof *this));
66 this->hidden = (struct SDL_PrivateAudioData *)
67 SDL_malloc((sizeof *this->hidden));
68 }
69 if ((this == NULL) || (this->hidden == NULL)) {
70 SDL_OutOfMemory();
71 if (this) {
72 SDL_free(this);
73 }
74 return (0);
75 }
76 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
77
78 /* Set the function pointers */
79 this->OpenAudio = DCAUD_OpenAudio;
80 this->WaitAudio = DCAUD_WaitAudio;
81 this->PlayAudio = DCAUD_PlayAudio;
82 this->GetAudioBuf = DCAUD_GetAudioBuf;
83 this->CloseAudio = DCAUD_CloseAudio;
84
85 this->free = DCAUD_DeleteDevice;
86
87 spu_init();
88
89 return this;
90 }
91
92 AudioBootStrap DCAUD_bootstrap = {
93 "dcaudio", "Dreamcast AICA audio",
94 DCAUD_Available, DCAUD_CreateDevice, 0
95 };
96
97 /* This function waits until it is possible to write a full sound buffer */
98 static void
99 DCAUD_WaitAudio(_THIS)
100 {
101 if (this->hidden->playing) {
102 /* wait */
103 while (aica_get_pos(0) / this->spec.samples == this->hidden->nextbuf) {
104 thd_pass();
105 }
106 }
107 }
108 35
109 #define SPU_RAM_BASE 0xa0800000 36 #define SPU_RAM_BASE 0xa0800000
110 37
111 static void 38 static void
112 spu_memload_stereo8(int leftpos, int rightpos, void *src0, size_t size) 39 spu_memload_stereo8(int leftpos, int rightpos, void *src0, size_t size)
149 g2_fifo_wait(); 76 g2_fifo_wait();
150 } 77 }
151 } 78 }
152 79
153 static void 80 static void
154 DCAUD_PlayAudio(_THIS) 81 DCAUD_PlayDevice(_THIS)
155 { 82 {
156 SDL_AudioSpec *spec = &this->spec; 83 SDL_AudioSpec *spec = &this->spec;
157 unsigned int offset; 84 unsigned int offset;
158 85
159 if (this->hidden->playing) { 86 if (this->hidden->playing) {
197 } 124 }
198 } 125 }
199 } 126 }
200 127
201 static Uint8 * 128 static Uint8 *
202 DCAUD_GetAudioBuf(_THIS) 129 DCAUD_GetDeviceBuf(_THIS)
203 { 130 {
204 return (this->hidden->mixbuf); 131 return (this->hidden->mixbuf);
205 } 132 }
206 133
207 static void 134 /* This function waits until it is possible to write a full sound buffer */
208 DCAUD_CloseAudio(_THIS) 135 static void
209 { 136 DCAUD_WaitDevice(_THIS)
210 aica_stop(0); 137 {
211 if (this->spec.channels == 2) 138 if (this->hidden->playing) {
212 aica_stop(1); 139 /* wait */
213 if (this->hidden->mixbuf != NULL) { 140 while (aica_get_pos(0) / this->spec.samples == this->hidden->nextbuf) {
214 SDL_FreeAudioMem(this->hidden->mixbuf); 141 thd_pass();
215 this->hidden->mixbuf = NULL; 142 }
143 }
144 }
145
146 static void
147 DCAUD_CloseDevice(_THIS)
148 {
149 if (this->hidden != NULL) {
150 aica_stop(0);
151 if (this->spec.channels == 2) {
152 aica_stop(1);
153 }
154 if (this->hidden->mixbuf != NULL) {
155 SDL_FreeAudioMem(this->hidden->mixbuf);
156 this->hidden->mixbuf = NULL;
157 }
158 SDL_free(this->hidden);
159 this->hidden = NULL;
160
161 /* !!! FIXME: is there a reverse of spu_init()? */
216 } 162 }
217 } 163 }
218 164
219 static int 165 static int
220 DCAUD_OpenAudio(_THIS, SDL_AudioSpec * spec) 166 DCAUD_OpenDevice(_THIS, SDL_AudioSpec * spec)
221 { 167 {
222 SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); 168 SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
223 int valid_datatype = 0; 169 int valid_datatype = 0;
170
171 /* Initialize all variables that we clean on shutdown */
172 this->hidden = (struct SDL_PrivateAudioData *)
173 SDL_malloc((sizeof *this->hidden));
174 if (this->hidden == NULL) {
175 SDL_OutOfMemory();
176 return 0;
177 }
178 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
179
180 spu_init();
181
224 while ((!valid_datatype) && (test_format)) { 182 while ((!valid_datatype) && (test_format)) {
225 spec->format = test_format; 183 spec->format = test_format;
226 switch (test_format) { 184 switch (test_format) {
227 /* only formats Dreamcast accepts... */ 185 /* only formats Dreamcast accepts... */
228 case AUDIO_S8: 186 case AUDIO_S8:
235 break; 193 break;
236 } 194 }
237 } 195 }
238 196
239 if (!valid_datatype) { /* shouldn't happen, but just in case... */ 197 if (!valid_datatype) { /* shouldn't happen, but just in case... */
198 DCAUD_CloseDevice(this);
240 SDL_SetError("Unsupported audio format"); 199 SDL_SetError("Unsupported audio format");
241 return (-1); 200 return 0;
242 } 201 }
243 202
244 if (spec->channels > 2) 203 if (spec->channels > 2)
245 spec->channels = 2; /* no more than stereo on the Dreamcast. */ 204 spec->channels = 2; /* no more than stereo on the Dreamcast. */
246 205
249 208
250 /* Allocate mixing buffer */ 209 /* Allocate mixing buffer */
251 this->hidden->mixlen = spec->size; 210 this->hidden->mixlen = spec->size;
252 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); 211 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
253 if (this->hidden->mixbuf == NULL) { 212 if (this->hidden->mixbuf == NULL) {
254 return (-1); 213 DCAUD_CloseDevice(this);
214 SDL_OutOfMemory();
215 return 0;
255 } 216 }
256 SDL_memset(this->hidden->mixbuf, spec->silence, spec->size); 217 SDL_memset(this->hidden->mixbuf, spec->silence, spec->size);
257 this->hidden->leftpos = 0x11000; 218 this->hidden->leftpos = 0x11000;
258 this->hidden->rightpos = 0x11000 + spec->size; 219 this->hidden->rightpos = 0x11000 + spec->size;
259 this->hidden->playing = 0; 220 this->hidden->playing = 0;
260 this->hidden->nextbuf = 0; 221 this->hidden->nextbuf = 0;
261 222
262 /* We're ready to rock and roll. :-) */ 223 /* We're ready to rock and roll. :-) */
263 return (0); 224 return 1;
264 } 225 }
226
227 static int
228 DCAUD_Available(void)
229 {
230 return 1; /* Dreamcast hardware is always available. :) */
231 }
232
233 static int
234 DCAUD_Init(SDL_AudioDriverImpl *impl)
235 {
236 /* Set the function pointers */
237 impl->OpenDevice = DCAUD_OpenDevice;
238 impl->PlayDevice = DCAUD_PlayDevice;
239 impl->WaitDevice = DCAUD_WaitDevice;
240 impl->GetDeviceBuf = DCAUD_GetDeviceBuf;
241 impl->CloseDevice = DCAUD_CloseDevice;
242 impl->OnlyHasDefaultOutputDevice = 1;
243
244 return 1;
245 }
246
247 AudioBootStrap DCAUD_bootstrap = {
248 "dcaudio", "Dreamcast AICA audio",
249 DCAUD_Available, DCAUD_Init, 0
250 };
265 251
266 /* vi: set ts=4 sw=4 expandtab: */ 252 /* vi: set ts=4 sw=4 expandtab: */