blob: d19b669bf2828ddbc194acf7366b00309e1f6a43 [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_);
29 if (IsReadyForPlayout()) {
30 RTC_DLOG(INFO) << "playout_samples_per_channel_10ms: "
31 << playout_samples_per_channel_10ms_;
32 RTC_DLOG(INFO) << "playout_channels: " << playout_channels_;
33 }
34 if (IsReadyForRecord()) {
35 RTC_DLOG(INFO) << "record_samples_per_channel_10ms: "
36 << record_samples_per_channel_10ms_;
37 RTC_DLOG(INFO) << "record_channels: " << record_channels_;
38 }
henrika86d907c2015-09-07 16:09:50 +020039}
40
41FineAudioBuffer::~FineAudioBuffer() {}
42
henrika86d907c2015-09-07 16:09:50 +020043void FineAudioBuffer::ResetPlayout() {
henrikab3ebc1a2017-02-27 05:14:17 -080044 playout_buffer_.Clear();
henrika86d907c2015-09-07 16:09:50 +020045}
46
47void FineAudioBuffer::ResetRecord() {
henrikaf166e1b2017-02-23 02:44:55 -080048 record_buffer_.Clear();
henrika86d907c2015-09-07 16:09:50 +020049}
50
henrika29e865a2018-04-24 13:22:31 +020051bool FineAudioBuffer::IsReadyForPlayout() const {
52 return playout_samples_per_channel_10ms_ > 0 && playout_channels_ > 0;
53}
54
55bool FineAudioBuffer::IsReadyForRecord() const {
56 return record_samples_per_channel_10ms_ > 0 && record_channels_ > 0;
57}
58
henrika8d7393b2018-04-19 13:40:15 +020059void FineAudioBuffer::GetPlayoutData(rtc::ArrayView<int16_t> audio_buffer,
henrika883d00f2018-03-16 10:09:49 +010060 int playout_delay_ms) {
henrika29e865a2018-04-24 13:22:31 +020061 RTC_DCHECK(IsReadyForPlayout());
henrikab3ebc1a2017-02-27 05:14:17 -080062 // Ask WebRTC for new data in chunks of 10ms until we have enough to
63 // fulfill the request. It is possible that the buffer already contains
64 // enough samples from the last round.
henrika8d7393b2018-04-19 13:40:15 +020065 while (playout_buffer_.size() < audio_buffer.size()) {
henrika29e865a2018-04-24 13:22:31 +020066 // Get 10ms decoded audio from WebRTC. The ADB knows about number of
67 // channels; hence we can ask for number of samples per channel here.
68 audio_device_buffer_->RequestPlayoutData(playout_samples_per_channel_10ms_);
69 // Append 10ms to the end of the local buffer taking number of channels
70 // into account.
71 const size_t num_elements_10ms =
72 playout_channels_ * playout_samples_per_channel_10ms_;
73 const size_t written_elements = playout_buffer_.AppendData(
74 num_elements_10ms, [&](rtc::ArrayView<int16_t> buf) {
75 const size_t samples_per_channel_10ms =
76 audio_device_buffer_->GetPlayoutData(buf.data());
77 return playout_channels_ * samples_per_channel_10ms;
henrikab3ebc1a2017-02-27 05:14:17 -080078 });
henrika29e865a2018-04-24 13:22:31 +020079 RTC_DCHECK_EQ(num_elements_10ms, written_elements);
henrika86d907c2015-09-07 16:09:50 +020080 }
henrika8d7393b2018-04-19 13:40:15 +020081
henrikab3ebc1a2017-02-27 05:14:17 -080082 // Provide the requested number of bytes to the consumer.
henrika29e865a2018-04-24 13:22:31 +020083 const size_t num_bytes = audio_buffer.size() * sizeof(int16_t);
henrikabb6f7522017-05-30 02:01:30 -070084 memcpy(audio_buffer.data(), playout_buffer_.data(), num_bytes);
henrikab3ebc1a2017-02-27 05:14:17 -080085 // Move remaining samples to start of buffer to prepare for next round.
henrika8d7393b2018-04-19 13:40:15 +020086 memmove(playout_buffer_.data(), playout_buffer_.data() + audio_buffer.size(),
87 (playout_buffer_.size() - audio_buffer.size()) * sizeof(int16_t));
88 playout_buffer_.SetSize(playout_buffer_.size() - audio_buffer.size());
henrika883d00f2018-03-16 10:09:49 +010089 // Cache playout latency for usage in DeliverRecordedData();
90 playout_delay_ms_ = playout_delay_ms;
henrika86d907c2015-09-07 16:09:50 +020091}
92
henrikabb6f7522017-05-30 02:01:30 -070093void FineAudioBuffer::DeliverRecordedData(
henrika8d7393b2018-04-19 13:40:15 +020094 rtc::ArrayView<const int16_t> audio_buffer,
henrikabb6f7522017-05-30 02:01:30 -070095 int record_delay_ms) {
henrika29e865a2018-04-24 13:22:31 +020096 RTC_DCHECK(IsReadyForRecord());
97 // Always append new data and grow the buffer when needed.
henrikabb6f7522017-05-30 02:01:30 -070098 record_buffer_.AppendData(audio_buffer.data(), audio_buffer.size());
henrikaf166e1b2017-02-23 02:44:55 -080099 // Consume samples from buffer in chunks of 10ms until there is not
henrika8d7393b2018-04-19 13:40:15 +0200100 // enough data left. The number of remaining samples in the cache is given by
henrika29e865a2018-04-24 13:22:31 +0200101 // the new size of the internal |record_buffer_|.
102 const size_t num_elements_10ms =
103 record_channels_ * record_samples_per_channel_10ms_;
104 while (record_buffer_.size() >= num_elements_10ms) {
105 audio_device_buffer_->SetRecordedBuffer(record_buffer_.data(),
106 record_samples_per_channel_10ms_);
107 audio_device_buffer_->SetVQEData(playout_delay_ms_, record_delay_ms);
108 audio_device_buffer_->DeliverRecordedData();
109 memmove(record_buffer_.data(), record_buffer_.data() + num_elements_10ms,
110 (record_buffer_.size() - num_elements_10ms) * sizeof(int16_t));
111 record_buffer_.SetSize(record_buffer_.size() - num_elements_10ms);
henrika86d907c2015-09-07 16:09:50 +0200112 }
113}
114
115} // namespace webrtc