Mercurial > mplayer.hg
comparison libao2/ao_macosx.c @ 19427:ada359817b61
fix buffering issues with short audio samples on macosx. patch by Chris Roccati <roccati@pobox.com>
author | nplourde |
---|---|
date | Fri, 18 Aug 2006 01:19:19 +0000 |
parents | 99e20a22d5d0 |
children | 2d786b7625d7 |
comparison
equal
deleted
inserted
replaced
19426:99f95ed2d1e5 | 19427:ada359817b61 |
---|---|
73 typedef struct ao_macosx_s | 73 typedef struct ao_macosx_s |
74 { | 74 { |
75 /* AudioUnit */ | 75 /* AudioUnit */ |
76 AudioUnit theOutputUnit; | 76 AudioUnit theOutputUnit; |
77 int packetSize; | 77 int packetSize; |
78 int paused; | |
78 | 79 |
79 /* Ring-buffer */ | 80 /* Ring-buffer */ |
80 /* does not need explicit synchronization, but needs to allocate | 81 /* does not need explicit synchronization, but needs to allocate |
81 * (num_chunks + 1) * chunk_size memory to store num_chunks * chunk_size | 82 * (num_chunks + 1) * chunk_size memory to store num_chunks * chunk_size |
82 * data */ | 83 * data */ |
309 ao_msg(MSGT_AO,MSGL_WARN, "AudioUnitGetProperty returned %d when getting kAudioDevicePropertyBufferSize\n", (int)err); | 310 ao_msg(MSGT_AO,MSGL_WARN, "AudioUnitGetProperty returned %d when getting kAudioDevicePropertyBufferSize\n", (int)err); |
310 return CONTROL_FALSE; | 311 return CONTROL_FALSE; |
311 } | 312 } |
312 | 313 |
313 ao->chunk_size = maxFrames;//*inDesc.mBytesPerFrame; | 314 ao->chunk_size = maxFrames;//*inDesc.mBytesPerFrame; |
314 ao_msg(MSGT_AO,MSGL_V, "%5d chunk size\n", (int)ao->chunk_size); | |
315 | 315 |
316 ao->num_chunks = NUM_BUFS; | 316 ao_data.samplerate = inDesc.mSampleRate; |
317 ao_data.channels = inDesc.mChannelsPerFrame; | |
318 ao_data.bps = ao_data.samplerate * inDesc.mBytesPerFrame; | |
319 ao_data.outburst = ao->chunk_size; | |
320 ao_data.buffersize = ao_data.bps; | |
321 | |
322 ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; | |
317 ao->buffer_len = (ao->num_chunks + 1) * ao->chunk_size; | 323 ao->buffer_len = (ao->num_chunks + 1) * ao->chunk_size; |
318 ao->buffer = aoIsCreated ? realloc(ao->buffer,(ao->num_chunks + 1)*ao->chunk_size) | 324 ao->buffer = aoIsCreated ? realloc(ao->buffer,(ao->num_chunks + 1)*ao->chunk_size) |
319 : calloc(ao->num_chunks + 1, ao->chunk_size); | 325 : calloc(ao->num_chunks + 1, ao->chunk_size); |
320 | 326 |
321 ao_data.samplerate = inDesc.mSampleRate; | 327 ao_msg(MSGT_AO,MSGL_V, "using %5d chunks of %d bytes (buffer len %d bytes)\n", (int)ao->num_chunks, (int)ao->chunk_size, (int)ao->buffer_len); |
322 ao_data.channels = inDesc.mChannelsPerFrame; | |
323 ao_data.outburst = ao_data.buffersize = ao->chunk_size; | |
324 ao_data.bps = ao_data.samplerate * inDesc.mBytesPerFrame; | |
325 | 328 |
326 renderCallback.inputProc = theRenderProc; | 329 renderCallback.inputProc = theRenderProc; |
327 renderCallback.inputProcRefCon = 0; | 330 renderCallback.inputProcRefCon = 0; |
328 err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &renderCallback, sizeof(AURenderCallbackStruct)); | 331 err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &renderCallback, sizeof(AURenderCallbackStruct)); |
329 if (err) { | 332 if (err) { |
330 ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the render callback (err=%d)\n", err); | 333 ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the render callback (err=%d)\n", err); |
331 return CONTROL_FALSE; | 334 return CONTROL_FALSE; |
332 } | 335 } |
333 | 336 |
334 audio_pause(); | 337 reset(); |
335 ao->buf_read_pos=0; | |
336 ao->buf_write_pos=0; | |
337 | 338 |
338 return CONTROL_OK; | 339 return CONTROL_OK; |
339 } | 340 } |
340 | 341 |
341 | 342 |
342 static int play(void* output_samples,int num_bytes,int flags) | 343 static int play(void* output_samples,int num_bytes,int flags) |
343 { | 344 { |
345 int wrote=write_buffer(output_samples, num_bytes); | |
346 | |
344 audio_resume(); | 347 audio_resume(); |
345 return write_buffer(output_samples, num_bytes); | 348 return wrote; |
346 } | 349 } |
347 | 350 |
348 /* set variables and buffer to initial state */ | 351 /* set variables and buffer to initial state */ |
349 static void reset(void) | 352 static void reset(void) |
350 { | 353 { |
351 audio_pause(); | 354 audio_pause(); |
352 /* reset ring-buffer state */ | 355 /* reset ring-buffer state */ |
353 ao->buf_read_pos=0; | 356 ao->buf_read_pos=0; |
354 ao->buf_write_pos=0; | 357 ao->buf_write_pos=0; |
355 audio_resume(); | |
356 | 358 |
357 return; | 359 return; |
358 } | 360 } |
359 | 361 |
360 | 362 |
378 static void uninit(int immed) | 380 static void uninit(int immed) |
379 { | 381 { |
380 int i; | 382 int i; |
381 OSErr status; | 383 OSErr status; |
382 | 384 |
383 reset(); | 385 if (!immed) { |
386 long long timeleft=(1000000LL*buf_used())/ao_data.bps; | |
387 ao_msg(MSGT_AO,MSGL_DBG2, "%d bytes left @%d bps (%ld usec)\n", buf_used(), ao_data.bps, (int)timeleft); | |
388 usec_sleep((int)timeleft); | |
389 } | |
384 | 390 |
385 AudioOutputUnitStop(ao->theOutputUnit); | 391 AudioOutputUnitStop(ao->theOutputUnit); |
386 AudioUnitUninitialize(ao->theOutputUnit); | 392 AudioUnitUninitialize(ao->theOutputUnit); |
387 CloseComponent(ao->theOutputUnit); | 393 CloseComponent(ao->theOutputUnit); |
388 | 394 |
400 /* stop callback */ | 406 /* stop callback */ |
401 status=AudioOutputUnitStop(ao->theOutputUnit); | 407 status=AudioOutputUnitStop(ao->theOutputUnit); |
402 if (status) | 408 if (status) |
403 ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStop returned %d\n", | 409 ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStop returned %d\n", |
404 (int)status); | 410 (int)status); |
411 ao->paused=1; | |
405 } | 412 } |
406 | 413 |
407 | 414 |
408 /* resume playing, after audio_pause() */ | 415 /* resume playing, after audio_pause() */ |
409 static void audio_resume(void) | 416 static void audio_resume(void) |
410 { | 417 { |
418 if(ao->paused) { | |
411 OSErr status=noErr; | 419 OSErr status=noErr; |
412 | 420 /* start callback */ |
413 status=AudioOutputUnitStart(ao->theOutputUnit); | 421 status=AudioOutputUnitStart(ao->theOutputUnit); |
414 if (status) | 422 if (status) |
415 ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStart returned %d\n", | 423 ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStart returned %d\n", |
416 (int)status); | 424 (int)status); |
417 } | 425 ao->paused=0; |
426 } | |
427 } |