This change: Reduces complexity for audio playout by removing a redundant memcopy in the output audio path. Adds support for iOS simulator for playout since we now allow the audio layer to ask for different sizes of audio buffers at each callback. Real iOS devices always asks for the same size, simulators does not. This change comes without any new cost for real devices. BUG=b/37580746 Review-Url: https://codereview.webrtc.org/2894873002 Cr-Commit-Position: refs/heads/master@{#18321}
93 lines
3.7 KiB
C++
93 lines
3.7 KiB
C++
/*
|
|
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "webrtc/modules/audio_device/fine_audio_buffer.h"
|
|
|
|
#include <memory.h>
|
|
#include <stdio.h>
|
|
#include <algorithm>
|
|
|
|
#include "webrtc/base/checks.h"
|
|
#include "webrtc/base/logging.h"
|
|
#include "webrtc/modules/audio_device/audio_device_buffer.h"
|
|
|
|
namespace webrtc {
|
|
|
|
FineAudioBuffer::FineAudioBuffer(AudioDeviceBuffer* device_buffer,
|
|
int sample_rate,
|
|
size_t capacity)
|
|
: device_buffer_(device_buffer),
|
|
sample_rate_(sample_rate),
|
|
samples_per_10_ms_(static_cast<size_t>(sample_rate_ * 10 / 1000)),
|
|
bytes_per_10_ms_(samples_per_10_ms_ * sizeof(int16_t)),
|
|
playout_buffer_(0, capacity),
|
|
record_buffer_(0, capacity) {
|
|
LOG(INFO) << "samples_per_10_ms_:" << samples_per_10_ms_;
|
|
}
|
|
|
|
FineAudioBuffer::~FineAudioBuffer() {}
|
|
|
|
void FineAudioBuffer::ResetPlayout() {
|
|
playout_buffer_.Clear();
|
|
}
|
|
|
|
void FineAudioBuffer::ResetRecord() {
|
|
record_buffer_.Clear();
|
|
}
|
|
|
|
void FineAudioBuffer::GetPlayoutData(rtc::ArrayView<int8_t> audio_buffer) {
|
|
// Ask WebRTC for new data in chunks of 10ms until we have enough to
|
|
// fulfill the request. It is possible that the buffer already contains
|
|
// enough samples from the last round.
|
|
const size_t num_bytes = audio_buffer.size();
|
|
while (playout_buffer_.size() < num_bytes) {
|
|
// Get 10ms decoded audio from WebRTC.
|
|
device_buffer_->RequestPlayoutData(samples_per_10_ms_);
|
|
// Append |bytes_per_10_ms_| elements to the end of the buffer.
|
|
const size_t bytes_written = playout_buffer_.AppendData(
|
|
bytes_per_10_ms_, [&](rtc::ArrayView<int8_t> buf) {
|
|
const size_t samples_per_channel =
|
|
device_buffer_->GetPlayoutData(buf.data());
|
|
// TODO(henrika): this class is only used on mobile devices and is
|
|
// currently limited to mono. Modifications are needed for stereo.
|
|
return sizeof(int16_t) * samples_per_channel;
|
|
});
|
|
RTC_DCHECK_EQ(bytes_per_10_ms_, bytes_written);
|
|
}
|
|
// Provide the requested number of bytes to the consumer.
|
|
memcpy(audio_buffer.data(), playout_buffer_.data(), num_bytes);
|
|
// Move remaining samples to start of buffer to prepare for next round.
|
|
memmove(playout_buffer_.data(), playout_buffer_.data() + num_bytes,
|
|
playout_buffer_.size() - num_bytes);
|
|
playout_buffer_.SetSize(playout_buffer_.size() - num_bytes);
|
|
}
|
|
|
|
void FineAudioBuffer::DeliverRecordedData(
|
|
rtc::ArrayView<const int8_t> audio_buffer,
|
|
int playout_delay_ms,
|
|
int record_delay_ms) {
|
|
// Always append new data and grow the buffer if needed.
|
|
record_buffer_.AppendData(audio_buffer.data(), audio_buffer.size());
|
|
// Consume samples from buffer in chunks of 10ms until there is not
|
|
// enough data left. The number of remaining bytes in the cache is given by
|
|
// the new size of the buffer.
|
|
while (record_buffer_.size() >= bytes_per_10_ms_) {
|
|
device_buffer_->SetRecordedBuffer(record_buffer_.data(),
|
|
samples_per_10_ms_);
|
|
device_buffer_->SetVQEData(playout_delay_ms, record_delay_ms, 0);
|
|
device_buffer_->DeliverRecordedData();
|
|
memmove(record_buffer_.data(), record_buffer_.data() + bytes_per_10_ms_,
|
|
record_buffer_.size() - bytes_per_10_ms_);
|
|
record_buffer_.SetSize(record_buffer_.size() - bytes_per_10_ms_);
|
|
}
|
|
}
|
|
|
|
} // namespace webrtc
|