comparison src/audio/dsp/SDL_dspaudio.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
56 56
57 /* Open the audio device for playback, and don't block if busy */ 57 /* Open the audio device for playback, and don't block if busy */
58 #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) 58 #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK)
59 59
60 /* Audio driver functions */ 60 /* Audio driver functions */
61 static int DSP_OpenAudio (_THIS, SDL_AudioSpec * spec); 61 static int DSP_OpenAudio(_THIS, SDL_AudioSpec * spec);
62 static void DSP_WaitAudio (_THIS); 62 static void DSP_WaitAudio(_THIS);
63 static void DSP_PlayAudio (_THIS); 63 static void DSP_PlayAudio(_THIS);
64 static Uint8 *DSP_GetAudioBuf (_THIS); 64 static Uint8 *DSP_GetAudioBuf(_THIS);
65 static void DSP_CloseAudio (_THIS); 65 static void DSP_CloseAudio(_THIS);
66 66
67 /* Audio driver bootstrap functions */ 67 /* Audio driver bootstrap functions */
68 68
69 static int 69 static int
70 Audio_Available (void) 70 Audio_Available(void)
71 { 71 {
72 int fd; 72 int fd;
73 int available; 73 int available;
74 74
75 available = 0; 75 available = 0;
76 fd = SDL_OpenAudioPath (NULL, 0, OPEN_FLAGS, 0); 76 fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
77 if (fd >= 0) { 77 if (fd >= 0) {
78 available = 1; 78 available = 1;
79 close (fd); 79 close(fd);
80 } 80 }
81 return (available); 81 return (available);
82 } 82 }
83 83
84 static void 84 static void
85 Audio_DeleteDevice (SDL_AudioDevice * device) 85 Audio_DeleteDevice(SDL_AudioDevice * device)
86 { 86 {
87 SDL_free (device->hidden); 87 SDL_free(device->hidden);
88 SDL_free (device); 88 SDL_free(device);
89 } 89 }
90 90
91 static SDL_AudioDevice * 91 static SDL_AudioDevice *
92 Audio_CreateDevice (int devindex) 92 Audio_CreateDevice(int devindex)
93 { 93 {
94 SDL_AudioDevice *this; 94 SDL_AudioDevice *this;
95 95
96 /* Initialize all variables that we clean on shutdown */ 96 /* Initialize all variables that we clean on shutdown */
97 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice)); 97 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
98 if (this) { 98 if (this) {
99 SDL_memset (this, 0, (sizeof *this)); 99 SDL_memset(this, 0, (sizeof *this));
100 this->hidden = (struct SDL_PrivateAudioData *) 100 this->hidden = (struct SDL_PrivateAudioData *)
101 SDL_malloc ((sizeof *this->hidden)); 101 SDL_malloc((sizeof *this->hidden));
102 } 102 }
103 if ((this == NULL) || (this->hidden == NULL)) { 103 if ((this == NULL) || (this->hidden == NULL)) {
104 SDL_OutOfMemory (); 104 SDL_OutOfMemory();
105 if (this) { 105 if (this) {
106 SDL_free (this); 106 SDL_free(this);
107 } 107 }
108 return (0); 108 return (0);
109 } 109 }
110 SDL_memset (this->hidden, 0, (sizeof *this->hidden)); 110 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
111 audio_fd = -1; 111 audio_fd = -1;
112 112
113 /* Set the function pointers */ 113 /* Set the function pointers */
114 this->OpenAudio = DSP_OpenAudio; 114 this->OpenAudio = DSP_OpenAudio;
115 this->WaitAudio = DSP_WaitAudio; 115 this->WaitAudio = DSP_WaitAudio;
127 Audio_Available, Audio_CreateDevice 127 Audio_Available, Audio_CreateDevice
128 }; 128 };
129 129
130 /* This function waits until it is possible to write a full sound buffer */ 130 /* This function waits until it is possible to write a full sound buffer */
131 static void 131 static void
132 DSP_WaitAudio (_THIS) 132 DSP_WaitAudio(_THIS)
133 { 133 {
134 /* Not needed at all since OSS handles waiting automagically */ 134 /* Not needed at all since OSS handles waiting automagically */
135 } 135 }
136 136
137 static void 137 static void
138 DSP_PlayAudio (_THIS) 138 DSP_PlayAudio(_THIS)
139 { 139 {
140 if (write (audio_fd, mixbuf, mixlen) == -1) { 140 if (write(audio_fd, mixbuf, mixlen) == -1) {
141 perror ("Audio write"); 141 perror("Audio write");
142 this->enabled = 0; 142 this->enabled = 0;
143 } 143 }
144 #ifdef DEBUG_AUDIO 144 #ifdef DEBUG_AUDIO
145 fprintf (stderr, "Wrote %d bytes of audio data\n", mixlen); 145 fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen);
146 #endif 146 #endif
147 } 147 }
148 148
149 static Uint8 * 149 static Uint8 *
150 DSP_GetAudioBuf (_THIS) 150 DSP_GetAudioBuf(_THIS)
151 { 151 {
152 return (mixbuf); 152 return (mixbuf);
153 } 153 }
154 154
155 static void 155 static void
156 DSP_CloseAudio (_THIS) 156 DSP_CloseAudio(_THIS)
157 { 157 {
158 if (mixbuf != NULL) { 158 if (mixbuf != NULL) {
159 SDL_FreeAudioMem (mixbuf); 159 SDL_FreeAudioMem(mixbuf);
160 mixbuf = NULL; 160 mixbuf = NULL;
161 } 161 }
162 if (audio_fd >= 0) { 162 if (audio_fd >= 0) {
163 close (audio_fd); 163 close(audio_fd);
164 audio_fd = -1; 164 audio_fd = -1;
165 } 165 }
166 } 166 }
167 167
168 static int 168 static int
169 DSP_OpenAudio (_THIS, SDL_AudioSpec * spec) 169 DSP_OpenAudio(_THIS, SDL_AudioSpec * spec)
170 { 170 {
171 char audiodev[1024]; 171 char audiodev[1024];
172 int format; 172 int format;
173 int value; 173 int value;
174 int frag_spec; 174 int frag_spec;
175 Uint16 test_format; 175 Uint16 test_format;
176 176
177 /* Open the audio device */ 177 /* Open the audio device */
178 audio_fd = SDL_OpenAudioPath (audiodev, sizeof (audiodev), OPEN_FLAGS, 0); 178 audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0);
179 if (audio_fd < 0) { 179 if (audio_fd < 0) {
180 SDL_SetError ("Couldn't open %s: %s", audiodev, strerror (errno)); 180 SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
181 return (-1); 181 return (-1);
182 } 182 }
183 mixbuf = NULL; 183 mixbuf = NULL;
184 184
185 /* Make the file descriptor use blocking writes with fcntl() */ 185 /* Make the file descriptor use blocking writes with fcntl() */
186 { 186 {
187 long flags; 187 long flags;
188 flags = fcntl (audio_fd, F_GETFL); 188 flags = fcntl(audio_fd, F_GETFL);
189 flags &= ~O_NONBLOCK; 189 flags &= ~O_NONBLOCK;
190 if (fcntl (audio_fd, F_SETFL, flags) < 0) { 190 if (fcntl(audio_fd, F_SETFL, flags) < 0) {
191 SDL_SetError ("Couldn't set audio blocking mode"); 191 SDL_SetError("Couldn't set audio blocking mode");
192 DSP_CloseAudio (this); 192 DSP_CloseAudio(this);
193 return (-1); 193 return (-1);
194 } 194 }
195 } 195 }
196 196
197 /* Get a list of supported hardware formats */ 197 /* Get a list of supported hardware formats */
198 if (ioctl (audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) { 198 if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
199 perror ("SNDCTL_DSP_GETFMTS"); 199 perror("SNDCTL_DSP_GETFMTS");
200 SDL_SetError ("Couldn't get audio format list"); 200 SDL_SetError("Couldn't get audio format list");
201 DSP_CloseAudio (this); 201 DSP_CloseAudio(this);
202 return (-1); 202 return (-1);
203 } 203 }
204 204
205 /* Try for a closest match on audio format */ 205 /* Try for a closest match on audio format */
206 format = 0; 206 format = 0;
207 for (test_format = SDL_FirstAudioFormat (spec->format); 207 for (test_format = SDL_FirstAudioFormat(spec->format);
208 !format && test_format;) { 208 !format && test_format;) {
209 #ifdef DEBUG_AUDIO 209 #ifdef DEBUG_AUDIO
210 fprintf (stderr, "Trying format 0x%4.4x\n", test_format); 210 fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
211 #endif 211 #endif
212 switch (test_format) { 212 switch (test_format) {
213 case AUDIO_U8: 213 case AUDIO_U8:
214 if (value & AFMT_U8) { 214 if (value & AFMT_U8) {
215 format = AFMT_U8; 215 format = AFMT_U8;
249 default: 249 default:
250 format = 0; 250 format = 0;
251 break; 251 break;
252 } 252 }
253 if (!format) { 253 if (!format) {
254 test_format = SDL_NextAudioFormat (); 254 test_format = SDL_NextAudioFormat();
255 } 255 }
256 } 256 }
257 if (format == 0) { 257 if (format == 0) {
258 SDL_SetError ("Couldn't find any hardware audio formats"); 258 SDL_SetError("Couldn't find any hardware audio formats");
259 DSP_CloseAudio (this); 259 DSP_CloseAudio(this);
260 return (-1); 260 return (-1);
261 } 261 }
262 spec->format = test_format; 262 spec->format = test_format;
263 263
264 /* Set the audio format */ 264 /* Set the audio format */
265 value = format; 265 value = format;
266 if ((ioctl (audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || 266 if ((ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) {
267 (value != format)) { 267 perror("SNDCTL_DSP_SETFMT");
268 perror ("SNDCTL_DSP_SETFMT"); 268 SDL_SetError("Couldn't set audio format");
269 SDL_SetError ("Couldn't set audio format"); 269 DSP_CloseAudio(this);
270 DSP_CloseAudio (this);
271 return (-1); 270 return (-1);
272 } 271 }
273 272
274 /* Set the number of channels of output */ 273 /* Set the number of channels of output */
275 value = spec->channels; 274 value = spec->channels;
276 if (ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) { 275 if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) {
277 perror ("SNDCTL_DSP_CHANNELS"); 276 perror("SNDCTL_DSP_CHANNELS");
278 SDL_SetError ("Cannot set the number of channels"); 277 SDL_SetError("Cannot set the number of channels");
279 DSP_CloseAudio (this); 278 DSP_CloseAudio(this);
280 return (-1); 279 return (-1);
281 } 280 }
282 spec->channels = value; 281 spec->channels = value;
283 282
284 /* Set the DSP frequency */ 283 /* Set the DSP frequency */
285 value = spec->freq; 284 value = spec->freq;
286 if (ioctl (audio_fd, SNDCTL_DSP_SPEED, &value) < 0) { 285 if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
287 perror ("SNDCTL_DSP_SPEED"); 286 perror("SNDCTL_DSP_SPEED");
288 SDL_SetError ("Couldn't set audio frequency"); 287 SDL_SetError("Couldn't set audio frequency");
289 DSP_CloseAudio (this); 288 DSP_CloseAudio(this);
290 return (-1); 289 return (-1);
291 } 290 }
292 spec->freq = value; 291 spec->freq = value;
293 292
294 /* Calculate the final parameters for this audio specification */ 293 /* Calculate the final parameters for this audio specification */
295 SDL_CalculateAudioSpec (spec); 294 SDL_CalculateAudioSpec(spec);
296 295
297 /* Determine the power of two of the fragment size */ 296 /* Determine the power of two of the fragment size */
298 for (frag_spec = 0; (0x01U << frag_spec) < spec->size; ++frag_spec); 297 for (frag_spec = 0; (0x01U << frag_spec) < spec->size; ++frag_spec);
299 if ((0x01U << frag_spec) != spec->size) { 298 if ((0x01U << frag_spec) != spec->size) {
300 SDL_SetError ("Fragment size must be a power of two"); 299 SDL_SetError("Fragment size must be a power of two");
301 DSP_CloseAudio (this); 300 DSP_CloseAudio(this);
302 return (-1); 301 return (-1);
303 } 302 }
304 frag_spec |= 0x00020000; /* two fragments, for low latency */ 303 frag_spec |= 0x00020000; /* two fragments, for low latency */
305 304
306 /* Set the audio buffering parameters */ 305 /* Set the audio buffering parameters */
307 #ifdef DEBUG_AUDIO 306 #ifdef DEBUG_AUDIO
308 fprintf (stderr, "Requesting %d fragments of size %d\n", 307 fprintf(stderr, "Requesting %d fragments of size %d\n",
309 (frag_spec >> 16), 1 << (frag_spec & 0xFFFF)); 308 (frag_spec >> 16), 1 << (frag_spec & 0xFFFF));
310 #endif 309 #endif
311 if (ioctl (audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) { 310 if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) {
312 perror ("SNDCTL_DSP_SETFRAGMENT"); 311 perror("SNDCTL_DSP_SETFRAGMENT");
313 } 312 }
314 #ifdef DEBUG_AUDIO 313 #ifdef DEBUG_AUDIO
315 { 314 {
316 audio_buf_info info; 315 audio_buf_info info;
317 ioctl (audio_fd, SNDCTL_DSP_GETOSPACE, &info); 316 ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info);
318 fprintf (stderr, "fragments = %d\n", info.fragments); 317 fprintf(stderr, "fragments = %d\n", info.fragments);
319 fprintf (stderr, "fragstotal = %d\n", info.fragstotal); 318 fprintf(stderr, "fragstotal = %d\n", info.fragstotal);
320 fprintf (stderr, "fragsize = %d\n", info.fragsize); 319 fprintf(stderr, "fragsize = %d\n", info.fragsize);
321 fprintf (stderr, "bytes = %d\n", info.bytes); 320 fprintf(stderr, "bytes = %d\n", info.bytes);
322 } 321 }
323 #endif 322 #endif
324 323
325 /* Allocate mixing buffer */ 324 /* Allocate mixing buffer */
326 mixlen = spec->size; 325 mixlen = spec->size;
327 mixbuf = (Uint8 *) SDL_AllocAudioMem (mixlen); 326 mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen);
328 if (mixbuf == NULL) { 327 if (mixbuf == NULL) {
329 DSP_CloseAudio (this); 328 DSP_CloseAudio(this);
330 return (-1); 329 return (-1);
331 } 330 }
332 SDL_memset (mixbuf, spec->silence, spec->size); 331 SDL_memset(mixbuf, spec->silence, spec->size);
333 332
334 /* Get the parent process id (we're the parent of the audio thread) */ 333 /* Get the parent process id (we're the parent of the audio thread) */
335 parent = getpid (); 334 parent = getpid();
336 335
337 /* We're ready to rock and roll. :-) */ 336 /* We're ready to rock and roll. :-) */
338 return (0); 337 return (0);
339 } 338 }
340 339