Mercurial > mplayer.hg
comparison libao2/ao_macosx.c @ 10152:b252d1b6829e
cleanup/cosmetic patch by the author :)
author | alex |
---|---|
date | Thu, 22 May 2003 16:12:54 +0000 |
parents | f2725d6717bd |
children | 99798c3cdb93 |
comparison
equal
deleted
inserted
replaced
10151:f096d8578c3d | 10152:b252d1b6829e |
---|---|
18 * GNU General Public License for more details. | 18 * GNU General Public License for more details. |
19 * | 19 * |
20 * You should have received a copy of the GNU General Public License | 20 * You should have received a copy of the GNU General Public License |
21 * along with GNU Make; see the file COPYING. If not, write to | 21 * along with GNU Make; see the file COPYING. If not, write to |
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
23 * | |
24 * $Id$ | |
25 */ | 23 */ |
26 | 24 |
27 /* | 25 /* |
28 * The MacOS X CoreAudio framework doesn't mesh as simply as some | 26 * The MacOS X CoreAudio framework doesn't mesh as simply as some |
29 * simpler frameworks do. This is due to the fact that CoreAudio pulls | 27 * simpler frameworks do. This is due to the fact that CoreAudio pulls |
35 * | 33 * |
36 * 14/5-2003: Ported to MPlayer libao2 by Dan Christiansen | 34 * 14/5-2003: Ported to MPlayer libao2 by Dan Christiansen |
37 * | 35 * |
38 * AC-3 and MPEG audio passthrough is possible, but I don't have | 36 * AC-3 and MPEG audio passthrough is possible, but I don't have |
39 * access to a sound card that supports it. | 37 * access to a sound card that supports it. |
40 */ | |
41 | |
42 | |
43 */ | 38 */ |
44 | 39 |
45 #include <CoreAudio/AudioHardware.h> | 40 #include <CoreAudio/AudioHardware.h> |
46 #include <stdio.h> | 41 #include <stdio.h> |
47 #include <string.h> | 42 #include <string.h> |
62 "" | 57 "" |
63 }; | 58 }; |
64 | 59 |
65 LIBAO_EXTERN(macosx) | 60 LIBAO_EXTERN(macosx) |
66 | 61 |
62 /* Prefix for all mp_msg() calls */ | |
63 #define ao_msg(a, b, c...) mp_msg(a, b, "AO: [macosx] " c) | |
64 | |
67 /* This is large, but best (maybe it should be even larger). | 65 /* This is large, but best (maybe it should be even larger). |
68 * CoreAudio supposedly has an internal latency in the order of 2ms */ | 66 * CoreAudio supposedly has an internal latency in the order of 2ms */ |
69 #define NUM_BUFS 128 | 67 #define NUM_BUFS 128 |
70 | 68 |
71 typedef struct ao_macosx_s | 69 typedef struct ao_macosx_s |
95 int len2=0; | 93 int len2=0; |
96 int x; | 94 int x; |
97 | 95 |
98 while(len>0){ | 96 while(len>0){ |
99 if(ao->full_buffers==NUM_BUFS) { | 97 if(ao->full_buffers==NUM_BUFS) { |
100 mp_msg(MSGT_AO,MSGL_V, "ao_macosx: Buffer overrun\n"); | 98 ao_msg(MSGT_AO,MSGL_V, "Buffer overrun\n"); |
101 break; | 99 break; |
102 } | 100 } |
103 | 101 |
104 x=ao->buffer_len-ao->buf_write_pos; | 102 x=ao->buffer_len-ao->buf_write_pos; |
105 if(x>len) x=len; | 103 if(x>len) x=len; |
125 int len2=0; | 123 int len2=0; |
126 int x; | 124 int x; |
127 | 125 |
128 while(len>0){ | 126 while(len>0){ |
129 if(ao->full_buffers==0) { | 127 if(ao->full_buffers==0) { |
130 mp_msg(MSGT_AO,MSGL_V, "ao_macosx: Buffer underrun\n"); | 128 ao_msg(MSGT_AO,MSGL_V, "Buffer underrun\n"); |
131 break; | 129 break; |
132 } | 130 } |
133 | 131 |
134 x=ao->buffer_len-ao->buf_read_pos; | 132 x=ao->buffer_len-ao->buf_read_pos; |
135 if(x>len) x=len; | 133 if(x>len) x=len; |
169 case AOCONTROL_SET_DEVICE: | 167 case AOCONTROL_SET_DEVICE: |
170 case AOCONTROL_GET_DEVICE: | 168 case AOCONTROL_GET_DEVICE: |
171 case AOCONTROL_GET_VOLUME: | 169 case AOCONTROL_GET_VOLUME: |
172 case AOCONTROL_SET_VOLUME: | 170 case AOCONTROL_SET_VOLUME: |
173 /* unimplemented/meaningless */ | 171 /* unimplemented/meaningless */ |
174 return CONTROL_NA; | 172 return CONTROL_FALSE; |
175 case AOCONTROL_QUERY_FORMAT: | 173 case AOCONTROL_QUERY_FORMAT: |
176 /* stick with what CoreAudio requests */ | 174 /* stick with what CoreAudio requests */ |
177 return CONTROL_NA; | 175 return CONTROL_FALSE; |
178 default: | 176 default: |
179 return CONTROL_UNKNOWN; | 177 return CONTROL_FALSE; |
180 } | 178 } |
181 | 179 |
182 } | 180 } |
183 | 181 |
184 | 182 |
197 | 195 |
198 /* get default output device */ | 196 /* get default output device */ |
199 propertySize = sizeof(ao->outputDeviceID); | 197 propertySize = sizeof(ao->outputDeviceID); |
200 status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propertySize, &(ao->outputDeviceID)); | 198 status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propertySize, &(ao->outputDeviceID)); |
201 if (status) { | 199 if (status) { |
202 mp_msg(MSGT_AO,MSGL_WARN, | 200 ao_msg(MSGT_AO,MSGL_WARN, |
203 "ao_coreaudio: AudioHardwareGetProperty returned %d\n", | 201 "AudioHardwareGetProperty returned %d\n", |
204 (int)status); | 202 (int)status); |
205 return CONTROL_ERROR; | 203 return CONTROL_FALSE; |
206 } | 204 } |
207 | 205 |
208 if (ao->outputDeviceID == kAudioDeviceUnknown) { | 206 if (ao->outputDeviceID == kAudioDeviceUnknown) { |
209 mp_msg(MSGT_AO,MSGL_WARN, "ao_coreaudio: AudioHardwareGetProperty: ao->outputDeviceID is kAudioDeviceUnknown\n"); | 207 ao_msg(MSGT_AO,MSGL_WARN, "AudioHardwareGetProperty: ao->outputDeviceID is kAudioDeviceUnknown\n"); |
210 return CONTROL_ERROR; | 208 return CONTROL_FALSE; |
211 } | 209 } |
212 | 210 |
213 /* get default output format | 211 /* get default output format |
214 * TODO: get all support formats and iterate through them | 212 * TODO: get all support formats and iterate through them |
215 */ | 213 */ |
216 propertySize = sizeof(ao->outputStreamBasicDescription); | 214 propertySize = sizeof(ao->outputStreamBasicDescription); |
217 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &propertySize, &ao->outputStreamBasicDescription); | 215 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &propertySize, &ao->outputStreamBasicDescription); |
218 if (status) { | 216 if (status) { |
219 mp_msg(MSGT_AO,MSGL_WARN, "ao_coreaudio: AudioDeviceGetProperty returned %d when getting kAudioDevicePropertyStreamFormat\n", (int)status); | 217 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceGetProperty returned %d when getting kAudioDevicePropertyStreamFormat\n", (int)status); |
220 return CONTROL_ERROR; | 218 return CONTROL_FALSE; |
221 } | 219 } |
222 | 220 |
223 mp_msg(MSGT_AO,MSGL_V, "hardware format...\n"); | 221 ao_msg(MSGT_AO,MSGL_V, "hardware format...\n"); |
224 mp_msg(MSGT_AO,MSGL_V, "%f mSampleRate\n", ao->outputStreamBasicDescription.mSampleRate); | 222 ao_msg(MSGT_AO,MSGL_V, "%f mSampleRate\n", ao->outputStreamBasicDescription.mSampleRate); |
225 mp_msg(MSGT_AO,MSGL_V, " %c%c%c%c mFormatID\n", | 223 ao_msg(MSGT_AO,MSGL_V, " %c%c%c%c mFormatID\n", |
226 (int)(ao->outputStreamBasicDescription.mFormatID & 0xff000000) >> 24, | 224 (int)(ao->outputStreamBasicDescription.mFormatID & 0xff000000) >> 24, |
227 (int)(ao->outputStreamBasicDescription.mFormatID & 0x00ff0000) >> 16, | 225 (int)(ao->outputStreamBasicDescription.mFormatID & 0x00ff0000) >> 16, |
228 (int)(ao->outputStreamBasicDescription.mFormatID & 0x0000ff00) >> 8, | 226 (int)(ao->outputStreamBasicDescription.mFormatID & 0x0000ff00) >> 8, |
229 (int)(ao->outputStreamBasicDescription.mFormatID & 0x000000ff) >> 0); | 227 (int)(ao->outputStreamBasicDescription.mFormatID & 0x000000ff) >> 0); |
230 mp_msg(MSGT_AO,MSGL_V, "%5d mBytesPerPacket\n", | 228 ao_msg(MSGT_AO,MSGL_V, "%5d mBytesPerPacket\n", |
231 (int)ao->outputStreamBasicDescription.mBytesPerPacket); | 229 (int)ao->outputStreamBasicDescription.mBytesPerPacket); |
232 mp_msg(MSGT_AO,MSGL_V, "%5d mFramesPerPacket\n", | 230 ao_msg(MSGT_AO,MSGL_V, "%5d mFramesPerPacket\n", |
233 (int)ao->outputStreamBasicDescription.mFramesPerPacket); | 231 (int)ao->outputStreamBasicDescription.mFramesPerPacket); |
234 mp_msg(MSGT_AO,MSGL_V, "%5d mBytesPerFrame\n", | 232 ao_msg(MSGT_AO,MSGL_V, "%5d mBytesPerFrame\n", |
235 (int)ao->outputStreamBasicDescription.mBytesPerFrame); | 233 (int)ao->outputStreamBasicDescription.mBytesPerFrame); |
236 mp_msg(MSGT_AO,MSGL_V, "%5d mChannelsPerFrame\n", | 234 ao_msg(MSGT_AO,MSGL_V, "%5d mChannelsPerFrame\n", |
237 (int)ao->outputStreamBasicDescription.mChannelsPerFrame); | 235 (int)ao->outputStreamBasicDescription.mChannelsPerFrame); |
238 | 236 |
239 /* get requested buffer length */ | 237 /* get requested buffer length */ |
240 propertySize = sizeof(ao->buffer_len); | 238 propertySize = sizeof(ao->buffer_len); |
241 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyBufferSize, &propertySize, &ao->buffer_len); | 239 status = AudioDeviceGetProperty(ao->outputDeviceID, 0, false, kAudioDevicePropertyBufferSize, &propertySize, &ao->buffer_len); |
242 if (status) { | 240 if (status) { |
243 mp_msg(MSGT_AO,MSGL_WARN, "ao_coreaudio: AudioDeviceGetProperty returned %d when getting kAudioDevicePropertyBufferSize\n", (int)status); | 241 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceGetProperty returned %d when getting kAudioDevicePropertyBufferSize\n", (int)status); |
244 return CONTROL_ERROR; | 242 return CONTROL_FALSE; |
245 } | 243 } |
246 mp_msg(MSGT_AO,MSGL_V, "%5d ao->buffer_len\n", (int)ao->buffer_len); | 244 ao_msg(MSGT_AO,MSGL_V, "%5d ao->buffer_len\n", (int)ao->buffer_len); |
247 | 245 |
248 ao_data.samplerate = (int)ao->outputStreamBasicDescription.mSampleRate; | 246 /* FIXME: |
247 * | |
248 * Resampling of 32-bit float audio is broken in MPlayer. Refuse to | |
249 * handle anything other than the native format until this is fixed | |
250 * or this module is rewritten, whichever comes first. | |
251 */ | |
252 if (ao_data.samplerate == ao->outputStreamBasicDescription.mSampleRate) { | |
253 ao_data.samplerate = (int)ao->outputStreamBasicDescription.mSampleRate; | |
254 } else { | |
255 ao_msg(MSGT_AO,MSGL_WARN, "Resampling not supported yet.\n"); | |
256 return 0; | |
257 } | |
258 | |
249 ao_data.channels = ao->outputStreamBasicDescription.mChannelsPerFrame; | 259 ao_data.channels = ao->outputStreamBasicDescription.mChannelsPerFrame; |
250 ao_data.outburst = ao_data.buffersize = ao->buffer_len; | 260 ao_data.outburst = ao_data.buffersize = ao->buffer_len; |
251 ao_data.bps = | 261 ao_data.bps = |
252 ao_data.samplerate * ao->outputStreamBasicDescription.mBytesPerFrame; | 262 ao_data.samplerate * ao->outputStreamBasicDescription.mBytesPerFrame; |
253 | 263 |
254 if (ao->outputStreamBasicDescription.mFormatID == kAudioFormatLinearPCM) { | 264 if (ao->outputStreamBasicDescription.mFormatID == kAudioFormatLinearPCM) { |
255 uint32_t flags = ao->outputStreamBasicDescription.mFormatFlags; | 265 uint32_t flags = ao->outputStreamBasicDescription.mFormatFlags; |
256 if (flags & kAudioFormatFlagIsFloat) { | 266 if (flags & kAudioFormatFlagIsFloat) { |
257 ao_data.format = AFMT_FLOAT; | 267 ao_data.format = AFMT_FLOAT; |
258 } else { | 268 } else { |
259 mp_msg(MSGT_AO,MSGL_WARN, "ao_coreaudio: Unsupported audio output " | 269 ao_msg(MSGT_AO,MSGL_WARN, "Unsupported audio output " |
260 "format. Please report this to the developers\n", | 270 "format %d. Please report this to the developer\n", |
261 (int)status); | 271 (int)status); |
262 } | 272 return CONTROL_FALSE; |
263 | 273 } |
274 | |
264 } else { | 275 } else { |
265 /* TODO: handle AFMT_AC3, AFMT_MPEG & friends */ | 276 /* TODO: handle AFMT_AC3, AFMT_MPEG & friends */ |
266 mp_msg(MSGT_AO,MSGL_WARN, "ao_coreaudio: Default Audio Device doesn't " | 277 ao_msg(MSGT_AO,MSGL_WARN, "Default Audio Device doesn't " |
267 "support Linear PCM!\n"); | 278 "support Linear PCM!\n"); |
268 return CONTROL_ERROR; | 279 return CONTROL_FALSE; |
269 } | 280 } |
270 | 281 |
271 /* Allocate ring-buffer memory */ | 282 /* Allocate ring-buffer memory */ |
272 for(i=0;i<NUM_BUFS;i++) | 283 for(i=0;i<NUM_BUFS;i++) |
273 ao->buffer[i]=(unsigned char *) malloc(ao->buffer_len); | 284 ao->buffer[i]=(unsigned char *) malloc(ao->buffer_len); |
278 reset(); | 289 reset(); |
279 | 290 |
280 /* Set the IO proc that CoreAudio will call when it needs data */ | 291 /* Set the IO proc that CoreAudio will call when it needs data */ |
281 status = AudioDeviceAddIOProc(ao->outputDeviceID, audioDeviceIOProc, NULL); | 292 status = AudioDeviceAddIOProc(ao->outputDeviceID, audioDeviceIOProc, NULL); |
282 if (status) { | 293 if (status) { |
283 mp_msg(MSGT_AO,MSGL_WARN, "ao_coreaudio: AudioDeviceAddIOProc returned %d\n", (int)status); | 294 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceAddIOProc returned %d\n", (int)status); |
284 return CONTROL_ERROR; | 295 return CONTROL_FALSE; |
285 } | 296 } |
286 | 297 |
287 /* Start callback */ | 298 /* Start callback */ |
288 status = AudioDeviceStart(ao->outputDeviceID, audioDeviceIOProc); | 299 status = AudioDeviceStart(ao->outputDeviceID, audioDeviceIOProc); |
289 if (status) { | 300 if (status) { |
290 mp_msg(MSGT_AO,MSGL_WARN, "ao_coreaudio: AudioDeviceStart returned %d\n", | 301 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceStart returned %d\n", |
291 (int)status); | 302 (int)status); |
292 return CONTROL_ERROR; | 303 return CONTROL_FALSE; |
293 } | 304 } |
294 | 305 |
295 return CONTROL_OK; | 306 return CONTROL_OK; |
296 } | 307 } |
297 | 308 |
315 ao->buf_write_pos=0; | 326 ao->buf_write_pos=0; |
316 | 327 |
317 ao->full_buffers=0; | 328 ao->full_buffers=0; |
318 ao->buffered_bytes=0; | 329 ao->buffered_bytes=0; |
319 | 330 |
331 /* zero output buffer */ | |
320 for (i = 0; i < NUM_BUFS; i++) | 332 for (i = 0; i < NUM_BUFS; i++) |
321 bzero(ao->buffer[i], ao->buffer_len); | 333 bzero(ao->buffer[i], ao->buffer_len); |
322 | 334 |
323 pthread_mutex_unlock(&ao->buffer_mutex); | 335 pthread_mutex_unlock(&ao->buffer_mutex); |
324 | 336 |
325 return; | 337 return; |
326 } | 338 } |
327 | 339 |
331 { | 343 { |
332 return (NUM_BUFS-ao->full_buffers)*ao_data.buffersize - ao->buf_write_pos; | 344 return (NUM_BUFS-ao->full_buffers)*ao_data.buffersize - ao->buf_write_pos; |
333 } | 345 } |
334 | 346 |
335 | 347 |
336 /* return delay until audio is played | 348 /* return delay until audio is played */ |
337 * FIXME */ | |
338 static float get_delay() | 349 static float get_delay() |
339 { | 350 { |
340 return (float)(ao->buffered_bytes)/(float)ao_data.bps; | 351 return (float)(ao->buffered_bytes)/(float)ao_data.bps; |
341 } | 352 } |
342 | 353 |
349 | 360 |
350 reset(); | 361 reset(); |
351 | 362 |
352 status = AudioDeviceRemoveIOProc(ao->outputDeviceID, audioDeviceIOProc); | 363 status = AudioDeviceRemoveIOProc(ao->outputDeviceID, audioDeviceIOProc); |
353 if (status) | 364 if (status) |
354 mp_msg(MSGT_AO,MSGL_WARN, "ao_coreaudio: AudioDeviceRemoveIOProc " | 365 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceRemoveIOProc " |
355 "returned %d\n", (int)status); | 366 "returned %d\n", (int)status); |
356 | 367 |
357 for(i=0;i<NUM_BUFS;i++) free(ao->buffer[i]); | 368 for(i=0;i<NUM_BUFS;i++) free(ao->buffer[i]); |
358 free(ao); | 369 free(ao); |
359 } | 370 } |
365 OSErr status; | 376 OSErr status; |
366 | 377 |
367 /* stop callback */ | 378 /* stop callback */ |
368 status = AudioDeviceStop(ao->outputDeviceID, audioDeviceIOProc); | 379 status = AudioDeviceStop(ao->outputDeviceID, audioDeviceIOProc); |
369 if (status) | 380 if (status) |
370 mp_msg(MSGT_AO,MSGL_WARN, "ao_coreaudio: AudioDeviceStop returned %d\n", | 381 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceStop returned %d\n", |
371 (int)status); | 382 (int)status); |
372 } | 383 } |
373 | 384 |
374 | 385 |
375 /* resume playing, after audio_pause() */ | 386 /* resume playing, after audio_pause() */ |
376 static void audio_resume() | 387 static void audio_resume() |
377 { | 388 { |
378 OSErr status = AudioDeviceStart(ao->outputDeviceID, audioDeviceIOProc); | 389 OSErr status = AudioDeviceStart(ao->outputDeviceID, audioDeviceIOProc); |
379 if (status) | 390 if (status) |
380 mp_msg(MSGT_AO,MSGL_WARN, "ao_coreaudio: AudioDeviceStart returned %d\n", | 391 ao_msg(MSGT_AO,MSGL_WARN, "AudioDeviceStart returned %d\n", |
381 (int)status); | 392 (int)status); |
382 } | 393 } |
383 | |
384 |