blob: 4af344aef3786a30027307585b6171e9145d234e [file] [log] [blame]
henrika86d907c2015-09-07 16:09:50 +02001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/audio_device/fine_audio_buffer.h"
henrika86d907c2015-09-07 16:09:50 +020012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "modules/audio_device/audio_device_buffer.h"
14#include "rtc_base/checks.h"
15#include "rtc_base/logging.h"
henrika29e865a2018-04-24 13:22:31 +020016#include "rtc_base/numerics/safe_conversions.h"
henrika86d907c2015-09-07 16:09:50 +020017
18namespace webrtc {
19
henrika29e865a2018-04-24 13:22:31 +020020FineAudioBuffer::FineAudioBuffer(AudioDeviceBuffer* audio_device_buffer)
21 : audio_device_buffer_(audio_device_buffer),
22 playout_samples_per_channel_10ms_(rtc::dchecked_cast<size_t>(
23 audio_device_buffer->PlayoutSampleRate() * 10 / 1000)),
24 record_samples_per_channel_10ms_(rtc::dchecked_cast<size_t>(
25 audio_device_buffer->RecordingSampleRate() * 10 / 1000)),
26 playout_channels_(audio_device_buffer->PlayoutChannels()),
27 record_channels_(audio_device_buffer->RecordingChannels()) {
28 RTC_DCHECK(audio_device_buffer_);
henrika5b6afc02018-09-05 14:34:40 +020029 RTC_DLOG(INFO) << __FUNCTION__;
henrika29e865a2018-04-24 13:22:31 +020030 if (IsReadyForPlayout()) {
31 RTC_DLOG(INFO) << "playout_samples_per_channel_10ms: "
32 << playout_samples_per_channel_10ms_;
33 RTC_DLOG(INFO) << "playout_channels: " << playout_channels_;
34 }
35 if (IsReadyForRecord()) {
36 RTC_DLOG(INFO) << "record_samples_per_channel_10ms: "
37 << record_samples_per_channel_10ms_;
38 RTC_DLOG(INFO) << "record_channels: " << record_channels_;
39 }
henrika86d907c2015-09-07 16:09:50 +020040}
41
henrika5b6afc02018-09-05 14:34:40 +020042FineAudioBuffer::~FineAudioBuffer() {
43 RTC_DLOG(INFO) << __FUNCTION__;
44}
henrika86d907c2015-09-07 16:09:50 +020045
henrika86d907c2015-09-07 16:09:50 +020046void FineAudioBuffer::ResetPlayout() {
henrikab3ebc1a2017-02-27 05:14:17 -080047 playout_buffer_.Clear();
henrika86d907c2015-09-07 16:09:50 +020048}
49
50void FineAudioBuffer::ResetRecord() {
henrikaf166e1b2017-02-23 02:44:55 -080051 record_buffer_.Clear();
henrika86d907c2015-09-07 16:09:50 +020052}
53
henrika29e865a2018-04-24 13:22:31 +020054bool FineAudioBuffer::IsReadyForPlayout() const {
55 return playout_samples_per_channel_10ms_ > 0 && playout_channels_ > 0;
56}
57
58bool FineAudioBuffer::IsReadyForRecord() const {
59 return record_samples_per_channel_10ms_ > 0 && record_channels_ > 0;
60}
61
henrika8d7393b2018-04-19 13:40:15 +020062void FineAudioBuffer::GetPlayoutData(rtc::ArrayView<int16_t> audio_buffer,
henrika883d00f2018-03-16 10:09:49 +010063 int playout_delay_ms) {
henrika29e865a2018-04-24 13:22:31 +020064 RTC_DCHECK(IsReadyForPlayout());
henrikab3ebc1a2017-02-27 05:14:17 -080065 // Ask WebRTC for new data in chunks of 10ms until we have enough to
66 // fulfill the request. It is possible that the buffer already contains
67 // enough samples from the last round.
henrika8d7393b2018-04-19 13:40:15 +020068 while (playout_buffer_.size() < audio_buffer.size()) {
henrika29e865a2018-04-24 13:22:31 +020069 // Get 10ms decoded audio from WebRTC. The ADB knows about number of
70 // channels; hence we can ask for number of samples per channel here.
henrikaec9c7452018-06-08 16:10:03 +020071 if (audio_device_buffer_->RequestPlayoutData(
72 playout_samples_per_channel_10ms_) ==
73 static_cast<int32_t>(playout_samples_per_channel_10ms_)) {
74 // Append 10ms to the end of the local buffer taking number of channels
75 // into account.
76 const size_t num_elements_10ms =
77 playout_channels_ * playout_samples_per_channel_10ms_;
78 const size_t written_elements = playout_buffer_.AppendData(
79 num_elements_10ms, [&](rtc::ArrayView<int16_t> buf) {
80 const size_t samples_per_channel_10ms =
81 audio_device_buffer_->GetPlayoutData(buf.data());
82 return playout_channels_ * samples_per_channel_10ms;
83 });
84 RTC_DCHECK_EQ(num_elements_10ms, written_elements);
85 } else {
86 // Provide silence if AudioDeviceBuffer::RequestPlayoutData() fails.
87 // Can e.g. happen when an AudioTransport has not been registered.
88 const size_t num_bytes = audio_buffer.size() * sizeof(int16_t);
89 std::memset(audio_buffer.data(), 0, num_bytes);
90 return;
91 }
henrika86d907c2015-09-07 16:09:50 +020092 }
henrika8d7393b2018-04-19 13:40:15 +020093
henrikab3ebc1a2017-02-27 05:14:17 -080094 // Provide the requested number of bytes to the consumer.
henrika29e865a2018-04-24 13:22:31 +020095 const size_t num_bytes = audio_buffer.size() * sizeof(int16_t);
henrikabb6f7522017-05-30 02:01:30 -070096 memcpy(audio_buffer.data(), playout_buffer_.data(), num_bytes);
henrikab3ebc1a2017-02-27 05:14:17 -080097 // Move remaining samples to start of buffer to prepare for next round.
henrika8d7393b2018-04-19 13:40:15 +020098 memmove(playout_buffer_.data(), playout_buffer_.data() + audio_buffer.size(),
99 (playout_buffer_.size() - audio_buffer.size()) * sizeof(int16_t));
100 playout_buffer_.SetSize(playout_buffer_.size() - audio_buffer.size());
henrika883d00f2018-03-16 10:09:49 +0100101 // Cache playout latency for usage in DeliverRecordedData();
102 playout_delay_ms_ = playout_delay_ms;
henrika86d907c2015-09-07 16:09:50 +0200103}
104
henrikabb6f7522017-05-30 02:01:30 -0700105void FineAudioBuffer::DeliverRecordedData(
henrika8d7393b2018-04-19 13:40:15 +0200106 rtc::ArrayView<const int16_t> audio_buffer,
henrikabb6f7522017-05-30 02:01:30 -0700107 int record_delay_ms) {
henrika29e865a2018-04-24 13:22:31 +0200108 RTC_DCHECK(IsReadyForRecord());
109 // Always append new data and grow the buffer when needed.
henrikabb6f7522017-05-30 02:01:30 -0700110 record_buffer_.AppendData(audio_buffer.data(), audio_buffer.size());
henrikaf166e1b2017-02-23 02:44:55 -0800111 // Consume samples from buffer in chunks of 10ms until there is not
henrika8d7393b2018-04-19 13:40:15 +0200112 // enough data left. The number of remaining samples in the cache is given by
henrika29e865a2018-04-24 13:22:31 +0200113 // the new size of the internal |record_buffer_|.
114 const size_t num_elements_10ms =
115 record_channels_ * record_samples_per_channel_10ms_;
116 while (record_buffer_.size() >= num_elements_10ms) {
117 audio_device_buffer_->SetRecordedBuffer(record_buffer_.data(),
118 record_samples_per_channel_10ms_);
119 audio_device_buffer_->SetVQEData(playout_delay_ms_, record_delay_ms);
120 audio_device_buffer_->DeliverRecordedData();
121 memmove(record_buffer_.data(), record_buffer_.data() + num_elements_10ms,
122 (record_buffer_.size() - num_elements_10ms) * sizeof(int16_t));
123 record_buffer_.SetSize(record_buffer_.size() - num_elements_10ms);
henrika86d907c2015-09-07 16:09:50 +0200124 }
125}
126
127} // namespace webrtc