Loading audio/coreaudio.c +69 −61 Original line number Diff line number Diff line Loading @@ -43,9 +43,6 @@ typedef struct coreaudioVoiceOut { UInt32 audioDevicePropertyBufferFrameSize; AudioStreamBasicDescription outputStreamBasicDescription; AudioDeviceIOProcID ioprocid; size_t live; size_t decr; size_t rpos; } coreaudioVoiceOut; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 Loading Loading @@ -397,31 +394,29 @@ static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name) return 0; } static size_t coreaudio_run_out(HWVoiceOut *hw, size_t live) { size_t decr; coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; if (coreaudio_lock (core, "coreaudio_run_out")) { return 0; } if (core->decr > live) { ldebug ("core->decr %d live %d core->live %d\n", core->decr, live, core->live); } decr = MIN (core->decr, live); core->decr -= decr; core->live = live - decr; hw->rpos = core->rpos; coreaudio_unlock (core, "coreaudio_run_out"); return decr; } #define COREAUDIO_WRAPPER_FUNC(name, ret_type, args_decl, args) \ static ret_type glue(coreaudio_, name)args_decl \ { \ coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; \ ret_type ret; \ \ if (coreaudio_lock(core, "coreaudio_" #name)) { \ return 0; \ } \ \ ret = glue(audio_generic_, name)args; \ \ coreaudio_unlock(core, "coreaudio_" #name); \ return ret; \ } COREAUDIO_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size), (hw, size)) COREAUDIO_WRAPPER_FUNC(put_buffer_out_nowrite, size_t, (HWVoiceOut *hw, void *buf, size_t size), (hw, buf, size)) COREAUDIO_WRAPPER_FUNC(write, size_t, (HWVoiceOut *hw, void *buf, size_t size), (hw, buf, size)) #undef COREAUDIO_WRAPPER_FUNC /* callback to feed audiooutput buffer */ static OSStatus audioDeviceIOProc( Loading @@ -433,19 +428,11 @@ static OSStatus audioDeviceIOProc( const AudioTimeStamp* inOutputTime, void* hwptr) { UInt32 frame, frameCount; float *out = outOutputData->mBuffers[0].mData; UInt32 frameCount, pending_frames; void *out = outOutputData->mBuffers[0].mData; HWVoiceOut *hw = hwptr; coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr; int rpos, live; struct st_sample *src; #ifndef FLOAT_MIXENG #ifdef RECIPROCAL const float scale = 1.f / UINT_MAX; #else const float scale = UINT_MAX; #endif #endif size_t len; if (coreaudio_lock (core, "audioDeviceIOProc")) { inInputTime = 0; Loading @@ -453,42 +440,51 @@ static OSStatus audioDeviceIOProc( } frameCount = core->audioDevicePropertyBufferFrameSize; live = core->live; pending_frames = hw->pending_emul >> hw->info.shift; /* if there are not enough samples, set signal and return */ if (live < frameCount) { if (pending_frames < frameCount) { inInputTime = 0; coreaudio_unlock (core, "audioDeviceIOProc(empty)"); return 0; } rpos = core->rpos; src = hw->mix_buf + rpos; /* fill buffer */ for (frame = 0; frame < frameCount; frame++) { #ifdef FLOAT_MIXENG *out++ = src[frame].l; /* left channel */ *out++ = src[frame].r; /* right channel */ #else #ifdef RECIPROCAL *out++ = src[frame].l * scale; /* left channel */ *out++ = src[frame].r * scale; /* right channel */ #else *out++ = src[frame].l / scale; /* left channel */ *out++ = src[frame].r / scale; /* right channel */ #endif #endif len = frameCount << hw->info.shift; while (len) { size_t write_len; ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul; if (start < 0) { start += hw->size_emul; } assert(start >= 0 && start < hw->size_emul); write_len = MIN(MIN(hw->pending_emul, len), hw->size_emul - start); rpos = (rpos + frameCount) % hw->samples; core->decr += frameCount; core->rpos = rpos; memcpy(out, hw->buf_emul + start, write_len); hw->pending_emul -= write_len; len -= write_len; out += write_len; } coreaudio_unlock (core, "audioDeviceIOProc"); return 0; } static UInt32 coreaudio_get_flags(struct audio_pcm_info *info, struct audsettings *as) { UInt32 flags = info->sign ? kAudioFormatFlagIsSignedInteger : 0; if (as->endianness) { /* 0 = little, 1 = big */ flags |= kAudioFormatFlagIsBigEndian; } if (flags == 0) { /* must not be 0 */ flags = kAudioFormatFlagsAreAllClear; } return flags; } static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) { Loading Loading @@ -576,6 +572,16 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, /* set Samplerate */ core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq; core->outputStreamBasicDescription.mFormatID = kAudioFormatLinearPCM; core->outputStreamBasicDescription.mFormatFlags = coreaudio_get_flags(&hw->info, as); core->outputStreamBasicDescription.mBytesPerPacket = core->outputStreamBasicDescription.mBytesPerFrame = hw->info.nchannels * hw->info.bits / 8; core->outputStreamBasicDescription.mFramesPerPacket = 1; core->outputStreamBasicDescription.mChannelsPerFrame = hw->info.nchannels; core->outputStreamBasicDescription.mBitsPerChannel = hw->info.bits; status = coreaudio_set_streamformat(core->outputDeviceID, &core->outputStreamBasicDescription); if (status != kAudioHardwareNoError) { Loading Loading @@ -686,7 +692,9 @@ static void coreaudio_audio_fini (void *opaque) static struct audio_pcm_ops coreaudio_pcm_ops = { .init_out = coreaudio_init_out, .fini_out = coreaudio_fini_out, .run_out = coreaudio_run_out, .write = coreaudio_write, .get_buffer_out = coreaudio_get_buffer_out, .put_buffer_out = coreaudio_put_buffer_out_nowrite, .ctl_out = coreaudio_ctl_out }; Loading Loading
audio/coreaudio.c +69 −61 Original line number Diff line number Diff line Loading @@ -43,9 +43,6 @@ typedef struct coreaudioVoiceOut { UInt32 audioDevicePropertyBufferFrameSize; AudioStreamBasicDescription outputStreamBasicDescription; AudioDeviceIOProcID ioprocid; size_t live; size_t decr; size_t rpos; } coreaudioVoiceOut; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 Loading Loading @@ -397,31 +394,29 @@ static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name) return 0; } static size_t coreaudio_run_out(HWVoiceOut *hw, size_t live) { size_t decr; coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; if (coreaudio_lock (core, "coreaudio_run_out")) { return 0; } if (core->decr > live) { ldebug ("core->decr %d live %d core->live %d\n", core->decr, live, core->live); } decr = MIN (core->decr, live); core->decr -= decr; core->live = live - decr; hw->rpos = core->rpos; coreaudio_unlock (core, "coreaudio_run_out"); return decr; } #define COREAUDIO_WRAPPER_FUNC(name, ret_type, args_decl, args) \ static ret_type glue(coreaudio_, name)args_decl \ { \ coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; \ ret_type ret; \ \ if (coreaudio_lock(core, "coreaudio_" #name)) { \ return 0; \ } \ \ ret = glue(audio_generic_, name)args; \ \ coreaudio_unlock(core, "coreaudio_" #name); \ return ret; \ } COREAUDIO_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size), (hw, size)) COREAUDIO_WRAPPER_FUNC(put_buffer_out_nowrite, size_t, (HWVoiceOut *hw, void *buf, size_t size), (hw, buf, size)) COREAUDIO_WRAPPER_FUNC(write, size_t, (HWVoiceOut *hw, void *buf, size_t size), (hw, buf, size)) #undef COREAUDIO_WRAPPER_FUNC /* callback to feed audiooutput buffer */ static OSStatus audioDeviceIOProc( Loading @@ -433,19 +428,11 @@ static OSStatus audioDeviceIOProc( const AudioTimeStamp* inOutputTime, void* hwptr) { UInt32 frame, frameCount; float *out = outOutputData->mBuffers[0].mData; UInt32 frameCount, pending_frames; void *out = outOutputData->mBuffers[0].mData; HWVoiceOut *hw = hwptr; coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr; int rpos, live; struct st_sample *src; #ifndef FLOAT_MIXENG #ifdef RECIPROCAL const float scale = 1.f / UINT_MAX; #else const float scale = UINT_MAX; #endif #endif size_t len; if (coreaudio_lock (core, "audioDeviceIOProc")) { inInputTime = 0; Loading @@ -453,42 +440,51 @@ static OSStatus audioDeviceIOProc( } frameCount = core->audioDevicePropertyBufferFrameSize; live = core->live; pending_frames = hw->pending_emul >> hw->info.shift; /* if there are not enough samples, set signal and return */ if (live < frameCount) { if (pending_frames < frameCount) { inInputTime = 0; coreaudio_unlock (core, "audioDeviceIOProc(empty)"); return 0; } rpos = core->rpos; src = hw->mix_buf + rpos; /* fill buffer */ for (frame = 0; frame < frameCount; frame++) { #ifdef FLOAT_MIXENG *out++ = src[frame].l; /* left channel */ *out++ = src[frame].r; /* right channel */ #else #ifdef RECIPROCAL *out++ = src[frame].l * scale; /* left channel */ *out++ = src[frame].r * scale; /* right channel */ #else *out++ = src[frame].l / scale; /* left channel */ *out++ = src[frame].r / scale; /* right channel */ #endif #endif len = frameCount << hw->info.shift; while (len) { size_t write_len; ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul; if (start < 0) { start += hw->size_emul; } assert(start >= 0 && start < hw->size_emul); write_len = MIN(MIN(hw->pending_emul, len), hw->size_emul - start); rpos = (rpos + frameCount) % hw->samples; core->decr += frameCount; core->rpos = rpos; memcpy(out, hw->buf_emul + start, write_len); hw->pending_emul -= write_len; len -= write_len; out += write_len; } coreaudio_unlock (core, "audioDeviceIOProc"); return 0; } static UInt32 coreaudio_get_flags(struct audio_pcm_info *info, struct audsettings *as) { UInt32 flags = info->sign ? kAudioFormatFlagIsSignedInteger : 0; if (as->endianness) { /* 0 = little, 1 = big */ flags |= kAudioFormatFlagIsBigEndian; } if (flags == 0) { /* must not be 0 */ flags = kAudioFormatFlagsAreAllClear; } return flags; } static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) { Loading Loading @@ -576,6 +572,16 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as, /* set Samplerate */ core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq; core->outputStreamBasicDescription.mFormatID = kAudioFormatLinearPCM; core->outputStreamBasicDescription.mFormatFlags = coreaudio_get_flags(&hw->info, as); core->outputStreamBasicDescription.mBytesPerPacket = core->outputStreamBasicDescription.mBytesPerFrame = hw->info.nchannels * hw->info.bits / 8; core->outputStreamBasicDescription.mFramesPerPacket = 1; core->outputStreamBasicDescription.mChannelsPerFrame = hw->info.nchannels; core->outputStreamBasicDescription.mBitsPerChannel = hw->info.bits; status = coreaudio_set_streamformat(core->outputDeviceID, &core->outputStreamBasicDescription); if (status != kAudioHardwareNoError) { Loading Loading @@ -686,7 +692,9 @@ static void coreaudio_audio_fini (void *opaque) static struct audio_pcm_ops coreaudio_pcm_ops = { .init_out = coreaudio_init_out, .fini_out = coreaudio_fini_out, .run_out = coreaudio_run_out, .write = coreaudio_write, .get_buffer_out = coreaudio_get_buffer_out, .put_buffer_out = coreaudio_put_buffer_out_nowrite, .ctl_out = coreaudio_ctl_out }; Loading