void ca_Play(audio_output_t * p_aout, block_t * p_block) { struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys; /* Do the channel reordering */ if (p_sys->chans_to_reorder) aout_ChannelReorder(p_block->p_buffer, p_block->i_buffer, p_sys->chans_to_reorder, p_sys->chan_table, VLC_CODEC_FL32); /* move data to buffer */ while (!TPCircularBufferProduceBytes(&p_sys->circular_buffer, p_block->p_buffer, p_block->i_buffer)) { if (atomic_load_explicit(&p_sys->b_paused, memory_order_relaxed)) { msg_Warn(p_aout, "dropping block because the circular buffer is " "full and paused"); break; } /* Try to play what we can */ int32_t i_avalaible_bytes; TPCircularBufferHead(&p_sys->circular_buffer, &i_avalaible_bytes); assert(i_avalaible_bytes >= 0); if (unlikely((size_t) i_avalaible_bytes >= p_block->i_buffer)) continue; bool ret = TPCircularBufferProduceBytes(&p_sys->circular_buffer, p_block->p_buffer, i_avalaible_bytes); assert(ret == true); p_block->p_buffer += i_avalaible_bytes; p_block->i_buffer -= i_avalaible_bytes; /* Wait for the render buffer to play the remaining data */ const mtime_t i_frame_us = FramesToUs(p_sys, BytesToFrames(p_sys, p_block->i_buffer)); msleep(i_frame_us / 2); } unsigned i_underrun_size = atomic_exchange(&p_sys->i_underrun_size, 0); if (i_underrun_size > 0) msg_Warn(p_aout, "underrun of %u bytes", i_underrun_size); block_Release(p_block); }
// ---------------------------------------------------------- OSStatus RenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) // ---------------------------------------------------------- { InputContext * ctx = static_cast<InputContext *>(inRefCon); OSStatus s = AudioUnitRender(*(ctx->inputUnit), ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ctx->bufferList.get()); OFXAU_PRINT(s, "rendering audio input"); if(s == noErr) { size_t buffersToCopy = std::min<size_t>(ctx->bufferList->mNumberBuffers, ctx->circularBuffers.size()); for(int i = 0; i < buffersToCopy; i++) { TPCircularBuffer * circBuffer = &ctx->circularBuffers[i]; if(circBuffer) { TPCircularBufferProduceBytes(circBuffer, ctx->bufferList->mBuffers[i].mData, inNumberFrames * sizeof(Float32)); } } } return s; }