LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_device - fine_audio_buffer.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 76 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       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             : 
      11             : #include "webrtc/modules/audio_device/fine_audio_buffer.h"
      12             : 
      13             : #include <memory.h>
      14             : #include <stdio.h>
      15             : #include <algorithm>
      16             : 
      17             : #include "webrtc/base/checks.h"
      18             : #include "webrtc/base/logging.h"
      19             : #include "webrtc/modules/audio_device/audio_device_buffer.h"
      20             : 
      21             : namespace webrtc {
      22             : 
      23           0 : FineAudioBuffer::FineAudioBuffer(AudioDeviceBuffer* device_buffer,
      24             :                                  size_t desired_frame_size_bytes,
      25           0 :                                  int sample_rate)
      26             :     : device_buffer_(device_buffer),
      27             :       desired_frame_size_bytes_(desired_frame_size_bytes),
      28             :       sample_rate_(sample_rate),
      29           0 :       samples_per_10_ms_(static_cast<size_t>(sample_rate_ * 10 / 1000)),
      30           0 :       bytes_per_10_ms_(samples_per_10_ms_ * sizeof(int16_t)),
      31             :       playout_cached_buffer_start_(0),
      32             :       playout_cached_bytes_(0),
      33             :       // Allocate extra space on the recording side to reduce the number of
      34             :       // memmove() calls.
      35             :       required_record_buffer_size_bytes_(
      36           0 :           5 * (desired_frame_size_bytes + bytes_per_10_ms_)),
      37             :       record_cached_bytes_(0),
      38             :       record_read_pos_(0),
      39           0 :       record_write_pos_(0) {
      40           0 :   playout_cache_buffer_.reset(new int8_t[bytes_per_10_ms_]);
      41           0 :   record_cache_buffer_.reset(new int8_t[required_record_buffer_size_bytes_]);
      42           0 :   memset(record_cache_buffer_.get(), 0, required_record_buffer_size_bytes_);
      43           0 : }
      44             : 
      45           0 : FineAudioBuffer::~FineAudioBuffer() {}
      46             : 
      47           0 : size_t FineAudioBuffer::RequiredPlayoutBufferSizeBytes() {
      48             :   // It is possible that we store the desired frame size - 1 samples. Since new
      49             :   // audio frames are pulled in chunks of 10ms we will need a buffer that can
      50             :   // hold desired_frame_size - 1 + 10ms of data. We omit the - 1.
      51           0 :   return desired_frame_size_bytes_ + bytes_per_10_ms_;
      52             : }
      53             : 
      54           0 : void FineAudioBuffer::ResetPlayout() {
      55           0 :   playout_cached_buffer_start_ = 0;
      56           0 :   playout_cached_bytes_ = 0;
      57           0 :   memset(playout_cache_buffer_.get(), 0, bytes_per_10_ms_);
      58           0 : }
      59             : 
      60           0 : void FineAudioBuffer::ResetRecord() {
      61           0 :   record_cached_bytes_ = 0;
      62           0 :   record_read_pos_ = 0;
      63           0 :   record_write_pos_ = 0;
      64           0 :   memset(record_cache_buffer_.get(), 0, required_record_buffer_size_bytes_);
      65           0 : }
      66             : 
      67           0 : void FineAudioBuffer::GetPlayoutData(int8_t* buffer) {
      68           0 :   if (desired_frame_size_bytes_ <= playout_cached_bytes_) {
      69           0 :     memcpy(buffer, &playout_cache_buffer_.get()[playout_cached_buffer_start_],
      70           0 :            desired_frame_size_bytes_);
      71           0 :     playout_cached_buffer_start_ += desired_frame_size_bytes_;
      72           0 :     playout_cached_bytes_ -= desired_frame_size_bytes_;
      73           0 :     RTC_CHECK_LT(playout_cached_buffer_start_ + playout_cached_bytes_,
      74           0 :                  bytes_per_10_ms_);
      75           0 :     return;
      76             :   }
      77           0 :   memcpy(buffer, &playout_cache_buffer_.get()[playout_cached_buffer_start_],
      78           0 :          playout_cached_bytes_);
      79             :   // Push another n*10ms of audio to |buffer|. n > 1 if
      80             :   // |desired_frame_size_bytes_| is greater than 10ms of audio. Note that we
      81             :   // write the audio after the cached bytes copied earlier.
      82           0 :   int8_t* unwritten_buffer = &buffer[playout_cached_bytes_];
      83             :   int bytes_left =
      84           0 :       static_cast<int>(desired_frame_size_bytes_ - playout_cached_bytes_);
      85             :   // Ceiling of integer division: 1 + ((x - 1) / y)
      86           0 :   size_t number_of_requests = 1 + (bytes_left - 1) / (bytes_per_10_ms_);
      87           0 :   for (size_t i = 0; i < number_of_requests; ++i) {
      88           0 :     device_buffer_->RequestPlayoutData(samples_per_10_ms_);
      89           0 :     int num_out = device_buffer_->GetPlayoutData(unwritten_buffer);
      90           0 :     if (static_cast<size_t>(num_out) != samples_per_10_ms_) {
      91           0 :       RTC_CHECK_EQ(num_out, 0);
      92           0 :       playout_cached_bytes_ = 0;
      93           0 :       return;
      94             :     }
      95           0 :     unwritten_buffer += bytes_per_10_ms_;
      96           0 :     RTC_CHECK_GE(bytes_left, 0);
      97           0 :     bytes_left -= static_cast<int>(bytes_per_10_ms_);
      98             :   }
      99           0 :   RTC_CHECK_LE(bytes_left, 0);
     100             :   // Put the samples that were written to |buffer| but are not used in the
     101             :   // cache.
     102           0 :   size_t cache_location = desired_frame_size_bytes_;
     103           0 :   int8_t* cache_ptr = &buffer[cache_location];
     104           0 :   playout_cached_bytes_ = number_of_requests * bytes_per_10_ms_ -
     105           0 :                           (desired_frame_size_bytes_ - playout_cached_bytes_);
     106             :   // If playout_cached_bytes_ is larger than the cache buffer, uninitialized
     107             :   // memory will be read.
     108           0 :   RTC_CHECK_LE(playout_cached_bytes_, bytes_per_10_ms_);
     109           0 :   RTC_CHECK_EQ(-bytes_left, playout_cached_bytes_);
     110           0 :   playout_cached_buffer_start_ = 0;
     111           0 :   memcpy(playout_cache_buffer_.get(), cache_ptr, playout_cached_bytes_);
     112             : }
     113             : 
     114           0 : void FineAudioBuffer::DeliverRecordedData(const int8_t* buffer,
     115             :                                           size_t size_in_bytes,
     116             :                                           int playout_delay_ms,
     117             :                                           int record_delay_ms) {
     118             :   // Check if the temporary buffer can store the incoming buffer. If not,
     119             :   // move the remaining (old) bytes to the beginning of the temporary buffer
     120             :   // and start adding new samples after the old samples.
     121           0 :   if (record_write_pos_ + size_in_bytes > required_record_buffer_size_bytes_) {
     122           0 :     if (record_cached_bytes_ > 0) {
     123           0 :       memmove(record_cache_buffer_.get(),
     124           0 :               record_cache_buffer_.get() + record_read_pos_,
     125           0 :               record_cached_bytes_);
     126             :     }
     127           0 :     record_write_pos_ = record_cached_bytes_;
     128           0 :     record_read_pos_ = 0;
     129             :   }
     130             :   // Add recorded samples to a temporary buffer.
     131           0 :   memcpy(record_cache_buffer_.get() + record_write_pos_, buffer, size_in_bytes);
     132           0 :   record_write_pos_ += size_in_bytes;
     133           0 :   record_cached_bytes_ += size_in_bytes;
     134             :   // Consume samples in temporary buffer in chunks of 10ms until there is not
     135             :   // enough data left. The number of remaining bytes in the cache is given by
     136             :   // |record_cached_bytes_| after this while loop is done.
     137           0 :   while (record_cached_bytes_ >= bytes_per_10_ms_) {
     138           0 :     device_buffer_->SetRecordedBuffer(
     139           0 :         record_cache_buffer_.get() + record_read_pos_, samples_per_10_ms_);
     140           0 :     device_buffer_->SetVQEData(playout_delay_ms, record_delay_ms, 0);
     141           0 :     device_buffer_->DeliverRecordedData();
     142             :     // Read next chunk of 10ms data.
     143           0 :     record_read_pos_ += bytes_per_10_ms_;
     144             :     // Reduce number of cached bytes with the consumed amount.
     145           0 :     record_cached_bytes_ -= bytes_per_10_ms_;
     146             :   }
     147           0 : }
     148             : 
     149             : }  // namespace webrtc

Generated by: LCOV version 1.13