inline void VCR::onAudioCB(AudioIOData& io) { // cached, because it may be being used in a different thread sampletime r = mAudioReadIndex; sampletime w = mAudioWriteIndex; unsigned channels = io.channelsOut(); if (channels > mAudioChans) channels = mAudioChans; unsigned numAudioFrames = io.framesPerBuffer(); unsigned numSamples = numAudioFrames * channels; unsigned length = mAudioRing.size(); sampletime ahead = w - r; // how much writer is ahead of reader if (ahead > (length - numSamples)) { // not enough space left in ringbuffer! fprintf(stderr, "audio underflow\n"); mAudioUnderflows++; return; } sampletime wnext = w + numSamples; unsigned wu = (unsigned)(w % length); //printf("writing %u samples to %llu\n", numSamples, wnext); for (unsigned c=0; c < channels; c++) { float * src = io.outBuffer(c); float * dst = &mAudioRing[0]; unsigned wc = wu + c; unsigned srcIdx = 0; while (srcIdx < numAudioFrames) { dst[wc] = src[srcIdx]; srcIdx++; wc += mAudioChans; if (wc >= length) wc -= length; } } // update write head position mAudioWriteIndex = wnext; }