comparison src/audio/nas/SDL_nasaudio.c @ 1668:4da1ee79c9af SDL-1.3

more tweaking indent options
author Sam Lantinga <slouken@libsdl.org>
date Mon, 29 May 2006 04:04:35 +0000
parents 782fd950bd46
children
comparison
equal deleted inserted replaced
1667:1fddae038bc8 1668:4da1ee79c9af
41 #define NAS_DRIVER_NAME "nas" 41 #define NAS_DRIVER_NAME "nas"
42 42
43 static struct SDL_PrivateAudioData *this2 = NULL; 43 static struct SDL_PrivateAudioData *this2 = NULL;
44 44
45 /* Audio driver functions */ 45 /* Audio driver functions */
46 static int NAS_OpenAudio (_THIS, SDL_AudioSpec * spec); 46 static int NAS_OpenAudio(_THIS, SDL_AudioSpec * spec);
47 static void NAS_WaitAudio (_THIS); 47 static void NAS_WaitAudio(_THIS);
48 static void NAS_PlayAudio (_THIS); 48 static void NAS_PlayAudio(_THIS);
49 static Uint8 *NAS_GetAudioBuf (_THIS); 49 static Uint8 *NAS_GetAudioBuf(_THIS);
50 static void NAS_CloseAudio (_THIS); 50 static void NAS_CloseAudio(_THIS);
51 51
52 /* Audio driver bootstrap functions */ 52 /* Audio driver bootstrap functions */
53 53
54 static int 54 static int
55 Audio_Available (void) 55 Audio_Available(void)
56 { 56 {
57 AuServer *aud = AuOpenServer ("", 0, NULL, 0, NULL, NULL); 57 AuServer *aud = AuOpenServer("", 0, NULL, 0, NULL, NULL);
58 if (!aud) 58 if (!aud)
59 return 0; 59 return 0;
60 60
61 AuCloseServer (aud); 61 AuCloseServer(aud);
62 return 1; 62 return 1;
63 } 63 }
64 64
65 static void 65 static void
66 Audio_DeleteDevice (SDL_AudioDevice * device) 66 Audio_DeleteDevice(SDL_AudioDevice * device)
67 { 67 {
68 SDL_free (device->hidden); 68 SDL_free(device->hidden);
69 SDL_free (device); 69 SDL_free(device);
70 } 70 }
71 71
72 static SDL_AudioDevice * 72 static SDL_AudioDevice *
73 Audio_CreateDevice (int devindex) 73 Audio_CreateDevice(int devindex)
74 { 74 {
75 SDL_AudioDevice *this; 75 SDL_AudioDevice *this;
76 76
77 /* Initialize all variables that we clean on shutdown */ 77 /* Initialize all variables that we clean on shutdown */
78 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice)); 78 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
79 if (this) { 79 if (this) {
80 SDL_memset (this, 0, (sizeof *this)); 80 SDL_memset(this, 0, (sizeof *this));
81 this->hidden = (struct SDL_PrivateAudioData *) 81 this->hidden = (struct SDL_PrivateAudioData *)
82 SDL_malloc ((sizeof *this->hidden)); 82 SDL_malloc((sizeof *this->hidden));
83 } 83 }
84 if ((this == NULL) || (this->hidden == NULL)) { 84 if ((this == NULL) || (this->hidden == NULL)) {
85 SDL_OutOfMemory (); 85 SDL_OutOfMemory();
86 if (this) { 86 if (this) {
87 SDL_free (this); 87 SDL_free(this);
88 } 88 }
89 return (0); 89 return (0);
90 } 90 }
91 SDL_memset (this->hidden, 0, (sizeof *this->hidden)); 91 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
92 92
93 /* Set the function pointers */ 93 /* Set the function pointers */
94 this->OpenAudio = NAS_OpenAudio; 94 this->OpenAudio = NAS_OpenAudio;
95 this->WaitAudio = NAS_WaitAudio; 95 this->WaitAudio = NAS_WaitAudio;
96 this->PlayAudio = NAS_PlayAudio; 96 this->PlayAudio = NAS_PlayAudio;
107 Audio_Available, Audio_CreateDevice 107 Audio_Available, Audio_CreateDevice
108 }; 108 };
109 109
110 /* This function waits until it is possible to write a full sound buffer */ 110 /* This function waits until it is possible to write a full sound buffer */
111 static void 111 static void
112 NAS_WaitAudio (_THIS) 112 NAS_WaitAudio(_THIS)
113 { 113 {
114 while (this->hidden->buf_free < this->hidden->mixlen) { 114 while (this->hidden->buf_free < this->hidden->mixlen) {
115 AuEvent ev; 115 AuEvent ev;
116 AuNextEvent (this->hidden->aud, AuTrue, &ev); 116 AuNextEvent(this->hidden->aud, AuTrue, &ev);
117 AuDispatchEvent (this->hidden->aud, &ev); 117 AuDispatchEvent(this->hidden->aud, &ev);
118 } 118 }
119 } 119 }
120 120
121 static void 121 static void
122 NAS_PlayAudio (_THIS) 122 NAS_PlayAudio(_THIS)
123 { 123 {
124 while (this->hidden->mixlen > this->hidden->buf_free) { /* We think the buffer is full? Yikes! Ask the server for events, 124 while (this->hidden->mixlen > this->hidden->buf_free) { /* We think the buffer is full? Yikes! Ask the server for events,
125 in the hope that some of them is LowWater events telling us more 125 in the hope that some of them is LowWater events telling us more
126 of the buffer is free now than what we think. */ 126 of the buffer is free now than what we think. */
127 AuEvent ev; 127 AuEvent ev;
128 AuNextEvent (this->hidden->aud, AuTrue, &ev); 128 AuNextEvent(this->hidden->aud, AuTrue, &ev);
129 AuDispatchEvent (this->hidden->aud, &ev); 129 AuDispatchEvent(this->hidden->aud, &ev);
130 } 130 }
131 this->hidden->buf_free -= this->hidden->mixlen; 131 this->hidden->buf_free -= this->hidden->mixlen;
132 132
133 /* Write the audio data */ 133 /* Write the audio data */
134 AuWriteElement (this->hidden->aud, this->hidden->flow, 0, 134 AuWriteElement(this->hidden->aud, this->hidden->flow, 0,
135 this->hidden->mixlen, this->hidden->mixbuf, AuFalse, 135 this->hidden->mixlen, this->hidden->mixbuf, AuFalse, NULL);
136 NULL);
137 136
138 this->hidden->written += this->hidden->mixlen; 137 this->hidden->written += this->hidden->mixlen;
139 138
140 #ifdef DEBUG_AUDIO 139 #ifdef DEBUG_AUDIO
141 fprintf (stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen); 140 fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen);
142 #endif 141 #endif
143 } 142 }
144 143
145 static Uint8 * 144 static Uint8 *
146 NAS_GetAudioBuf (_THIS) 145 NAS_GetAudioBuf(_THIS)
147 { 146 {
148 return (this->hidden->mixbuf); 147 return (this->hidden->mixbuf);
149 } 148 }
150 149
151 static void 150 static void
152 NAS_CloseAudio (_THIS) 151 NAS_CloseAudio(_THIS)
153 { 152 {
154 if (this->hidden->mixbuf != NULL) { 153 if (this->hidden->mixbuf != NULL) {
155 SDL_FreeAudioMem (this->hidden->mixbuf); 154 SDL_FreeAudioMem(this->hidden->mixbuf);
156 this->hidden->mixbuf = NULL; 155 this->hidden->mixbuf = NULL;
157 } 156 }
158 if (this->hidden->aud) { 157 if (this->hidden->aud) {
159 AuCloseServer (this->hidden->aud); 158 AuCloseServer(this->hidden->aud);
160 this->hidden->aud = 0; 159 this->hidden->aud = 0;
161 } 160 }
162 } 161 }
163 162
164 static unsigned char 163 static unsigned char
165 sdlformat_to_auformat (unsigned int fmt) 164 sdlformat_to_auformat(unsigned int fmt)
166 { 165 {
167 switch (fmt) { 166 switch (fmt) {
168 case AUDIO_U8: 167 case AUDIO_U8:
169 return AuFormatLinearUnsigned8; 168 return AuFormatLinearUnsigned8;
170 case AUDIO_S8: 169 case AUDIO_S8:
180 } 179 }
181 return AuNone; 180 return AuNone;
182 } 181 }
183 182
184 static AuBool 183 static AuBool
185 event_handler (AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd) 184 event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd)
186 { 185 {
187 switch (ev->type) { 186 switch (ev->type) {
188 case AuEventTypeElementNotify: 187 case AuEventTypeElementNotify:
189 { 188 {
190 AuElementNotifyEvent *event = (AuElementNotifyEvent *) ev; 189 AuElementNotifyEvent *event = (AuElementNotifyEvent *) ev;
191 190
192 switch (event->kind) { 191 switch (event->kind) {
193 case AuElementNotifyKindLowWater: 192 case AuElementNotifyKindLowWater:
194 if (this2->buf_free >= 0) { 193 if (this2->buf_free >= 0) {
195 this2->really += event->num_bytes; 194 this2->really += event->num_bytes;
196 gettimeofday (&this2->last_tv, 0); 195 gettimeofday(&this2->last_tv, 0);
197 this2->buf_free += event->num_bytes; 196 this2->buf_free += event->num_bytes;
198 } else { 197 } else {
199 this2->buf_free = event->num_bytes; 198 this2->buf_free = event->num_bytes;
200 } 199 }
201 break; 200 break;
203 switch (event->cur_state) { 202 switch (event->cur_state) {
204 case AuStatePause: 203 case AuStatePause:
205 if (event->reason != AuReasonUser) { 204 if (event->reason != AuReasonUser) {
206 if (this2->buf_free >= 0) { 205 if (this2->buf_free >= 0) {
207 this2->really += event->num_bytes; 206 this2->really += event->num_bytes;
208 gettimeofday (&this2->last_tv, 0); 207 gettimeofday(&this2->last_tv, 0);
209 this2->buf_free += event->num_bytes; 208 this2->buf_free += event->num_bytes;
210 } else { 209 } else {
211 this2->buf_free = event->num_bytes; 210 this2->buf_free = event->num_bytes;
212 } 211 }
213 } 212 }
218 } 217 }
219 return AuTrue; 218 return AuTrue;
220 } 219 }
221 220
222 static AuDeviceID 221 static AuDeviceID
223 find_device (_THIS, int nch) 222 find_device(_THIS, int nch)
224 { 223 {
225 int i; 224 int i;
226 for (i = 0; i < AuServerNumDevices (this->hidden->aud); i++) { 225 for (i = 0; i < AuServerNumDevices(this->hidden->aud); i++) {
227 if ((AuDeviceKind (AuServerDevice (this->hidden->aud, i)) == 226 if ((AuDeviceKind(AuServerDevice(this->hidden->aud, i)) ==
228 AuComponentKindPhysicalOutput) && 227 AuComponentKindPhysicalOutput) &&
229 AuDeviceNumTracks (AuServerDevice (this->hidden->aud, i)) == 228 AuDeviceNumTracks(AuServerDevice(this->hidden->aud, i)) == nch) {
230 nch) { 229 return AuDeviceIdentifier(AuServerDevice(this->hidden->aud, i));
231 return AuDeviceIdentifier (AuServerDevice (this->hidden->aud, i));
232 } 230 }
233 } 231 }
234 return AuNone; 232 return AuNone;
235 } 233 }
236 234
237 static int 235 static int
238 NAS_OpenAudio (_THIS, SDL_AudioSpec * spec) 236 NAS_OpenAudio(_THIS, SDL_AudioSpec * spec)
239 { 237 {
240 AuElement elms[3]; 238 AuElement elms[3];
241 int buffer_size; 239 int buffer_size;
242 Uint16 test_format, format; 240 Uint16 test_format, format;
243 241
244 this->hidden->mixbuf = NULL; 242 this->hidden->mixbuf = NULL;
245 243
246 /* Try for a closest match on audio format */ 244 /* Try for a closest match on audio format */
247 format = 0; 245 format = 0;
248 for (test_format = SDL_FirstAudioFormat (spec->format); 246 for (test_format = SDL_FirstAudioFormat(spec->format);
249 !format && test_format;) { 247 !format && test_format;) {
250 format = sdlformat_to_auformat (test_format); 248 format = sdlformat_to_auformat(test_format);
251 249
252 if (format == AuNone) { 250 if (format == AuNone) {
253 test_format = SDL_NextAudioFormat (); 251 test_format = SDL_NextAudioFormat();
254 } 252 }
255 } 253 }
256 if (format == 0) { 254 if (format == 0) {
257 SDL_SetError ("Couldn't find any hardware audio formats"); 255 SDL_SetError("Couldn't find any hardware audio formats");
258 return (-1); 256 return (-1);
259 } 257 }
260 spec->format = test_format; 258 spec->format = test_format;
261 259
262 this->hidden->aud = AuOpenServer ("", 0, NULL, 0, NULL, NULL); 260 this->hidden->aud = AuOpenServer("", 0, NULL, 0, NULL, NULL);
263 if (this->hidden->aud == 0) { 261 if (this->hidden->aud == 0) {
264 SDL_SetError ("Couldn't open connection to NAS server"); 262 SDL_SetError("Couldn't open connection to NAS server");
265 return (-1); 263 return (-1);
266 } 264 }
267 265
268 this->hidden->dev = find_device (this, spec->channels); 266 this->hidden->dev = find_device(this, spec->channels);
269 if ((this->hidden->dev == AuNone) 267 if ((this->hidden->dev == AuNone)
270 || (!(this->hidden->flow = AuCreateFlow (this->hidden->aud, NULL)))) { 268 || (!(this->hidden->flow = AuCreateFlow(this->hidden->aud, NULL)))) {
271 AuCloseServer (this->hidden->aud); 269 AuCloseServer(this->hidden->aud);
272 this->hidden->aud = 0; 270 this->hidden->aud = 0;
273 SDL_SetError 271 SDL_SetError("Couldn't find a fitting playback device on NAS server");
274 ("Couldn't find a fitting playback device on NAS server");
275 return (-1); 272 return (-1);
276 } 273 }
277 274
278 buffer_size = spec->freq; 275 buffer_size = spec->freq;
279 if (buffer_size < 4096) 276 if (buffer_size < 4096)
281 278
282 if (buffer_size > 32768) 279 if (buffer_size > 32768)
283 buffer_size = 32768; /* So that the buffer won't get unmanageably big. */ 280 buffer_size = 32768; /* So that the buffer won't get unmanageably big. */
284 281
285 /* Calculate the final parameters for this audio specification */ 282 /* Calculate the final parameters for this audio specification */
286 SDL_CalculateAudioSpec (spec); 283 SDL_CalculateAudioSpec(spec);
287 284
288 this2 = this->hidden; 285 this2 = this->hidden;
289 286
290 AuMakeElementImportClient (elms, spec->freq, format, spec->channels, 287 AuMakeElementImportClient(elms, spec->freq, format, spec->channels,
291 AuTrue, buffer_size, buffer_size / 4, 0, NULL); 288 AuTrue, buffer_size, buffer_size / 4, 0, NULL);
292 AuMakeElementExportDevice (elms + 1, 0, this->hidden->dev, spec->freq, 289 AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, spec->freq,
293 AuUnlimitedSamples, 0, NULL); 290 AuUnlimitedSamples, 0, NULL);
294 AuSetElements (this->hidden->aud, this->hidden->flow, AuTrue, 2, elms, 291 AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue, 2, elms,
295 NULL); 292 NULL);
296 AuRegisterEventHandler (this->hidden->aud, AuEventHandlerIDMask, 0, 293 AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0,
297 this->hidden->flow, event_handler, 294 this->hidden->flow, event_handler,
298 (AuPointer) NULL); 295 (AuPointer) NULL);
299 296
300 AuStartFlow (this->hidden->aud, this->hidden->flow, NULL); 297 AuStartFlow(this->hidden->aud, this->hidden->flow, NULL);
301 298
302 /* Allocate mixing buffer */ 299 /* Allocate mixing buffer */
303 this->hidden->mixlen = spec->size; 300 this->hidden->mixlen = spec->size;
304 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem (this->hidden->mixlen); 301 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
305 if (this->hidden->mixbuf == NULL) { 302 if (this->hidden->mixbuf == NULL) {
306 return (-1); 303 return (-1);
307 } 304 }
308 SDL_memset (this->hidden->mixbuf, spec->silence, spec->size); 305 SDL_memset(this->hidden->mixbuf, spec->silence, spec->size);
309 306
310 /* Get the parent process id (we're the parent of the audio thread) */ 307 /* Get the parent process id (we're the parent of the audio thread) */
311 this->hidden->parent = getpid (); 308 this->hidden->parent = getpid();
312 309
313 /* We're ready to rock and roll. :-) */ 310 /* We're ready to rock and roll. :-) */
314 return (0); 311 return (0);
315 } 312 }
316 313