size_t RingBufferPool::getData(AudioBuffer& buffer, const std::string& call_id) { std::lock_guard<std::recursive_mutex> lk(stateLock_); const auto bindings = getReadBindings(call_id); if (not bindings) return 0; // No mixing if (bindings->size() == 1) return (*bindings->cbegin())->get(buffer, call_id); buffer.reset(); buffer.setFormat(internalAudioFormat_); size_t size = 0; AudioBuffer mixBuffer(buffer); for (const auto& rbuf : *bindings) { // XXX: is it normal to only return the last positive size? size = rbuf->get(mixBuffer, call_id); if (size > 0) buffer.mix(mixBuffer); } return size; }
void JackLayer::fillWithToneOrRingtone(AudioBuffer &buffer) { buffer.resize(hardwareBufferSize_); AudioLoop *tone = Manager::instance().getTelephoneTone(); AudioLoop *file_tone = Manager::instance().getTelephoneFile(); // In case of a dtmf, the pointers will be set to nullptr once the dtmf length is // reached. For this reason we need to fill audio buffer with zeros if pointer is nullptr if (tone) { tone->getNext(buffer, playbackGain_); } else if (file_tone) { file_tone->getNext(buffer, playbackGain_); } else { buffer.reset(); } }
size_t RingBufferPool::getAvailableData(AudioBuffer& buffer, const std::string& call_id) { std::lock_guard<std::recursive_mutex> lk(stateLock_); auto bindings = getReadBindings(call_id); if (not bindings) return 0; // No mixing if (bindings->size() == 1) { return (*bindings->cbegin())->get(buffer, call_id); } size_t availableSamples = std::numeric_limits<size_t>::max(); for (const auto& rbuf : *bindings) availableSamples = std::min(availableSamples, rbuf->availableForGet(call_id)); if (availableSamples == std::numeric_limits<size_t>::max()) return 0; availableSamples = std::min(availableSamples, buffer.frames()); buffer.resize(availableSamples); buffer.reset(); buffer.setFormat(internalAudioFormat_); AudioBuffer mixBuffer(buffer); for (const auto &rbuf : *bindings) { if (rbuf->get(mixBuffer, call_id) > 0) buffer.mix(mixBuffer); } return availableSamples; }