Home | History | Annotate | Download | only in base
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "media/base/audio_buffer.h"
      6 
      7 #include "base/logging.h"
      8 #include "media/base/audio_bus.h"
      9 #include "media/base/buffers.h"
     10 #include "media/base/limits.h"
     11 
     12 namespace media {
     13 
     14 static base::TimeDelta CalculateDuration(int frames, double sample_rate) {
     15   DCHECK_GT(sample_rate, 0);
     16   return base::TimeDelta::FromMicroseconds(
     17       frames * base::Time::kMicrosecondsPerSecond / sample_rate);
     18 }
     19 
     20 AudioBuffer::AudioBuffer(SampleFormat sample_format,
     21                          ChannelLayout channel_layout,
     22                          int channel_count,
     23                          int sample_rate,
     24                          int frame_count,
     25                          bool create_buffer,
     26                          const uint8* const* data,
     27                          const base::TimeDelta timestamp)
     28     : sample_format_(sample_format),
     29       channel_layout_(channel_layout),
     30       channel_count_(channel_count),
     31       sample_rate_(sample_rate),
     32       adjusted_frame_count_(frame_count),
     33       trim_start_(0),
     34       end_of_stream_(!create_buffer && data == NULL && frame_count == 0),
     35       timestamp_(timestamp),
     36       duration_(end_of_stream_
     37                     ? base::TimeDelta()
     38                     : CalculateDuration(adjusted_frame_count_, sample_rate_)) {
     39   CHECK_GE(channel_count_, 0);
     40   CHECK_LE(channel_count_, limits::kMaxChannels);
     41   CHECK_GE(frame_count, 0);
     42   DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE ||
     43          ChannelLayoutToChannelCount(channel_layout) == channel_count);
     44 
     45   int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format);
     46   DCHECK_LE(bytes_per_channel, kChannelAlignment);
     47   int data_size = frame_count * bytes_per_channel;
     48 
     49   // Empty buffer?
     50   if (!create_buffer)
     51     return;
     52 
     53   if (sample_format == kSampleFormatPlanarF32 ||
     54       sample_format == kSampleFormatPlanarS16) {
     55     // Planar data, so need to allocate buffer for each channel.
     56     // Determine per channel data size, taking into account alignment.
     57     int block_size_per_channel =
     58         (data_size + kChannelAlignment - 1) & ~(kChannelAlignment - 1);
     59     DCHECK_GE(block_size_per_channel, data_size);
     60 
     61     // Allocate a contiguous buffer for all the channel data.
     62     data_.reset(static_cast<uint8*>(base::AlignedAlloc(
     63         channel_count_ * block_size_per_channel, kChannelAlignment)));
     64     channel_data_.reserve(channel_count_);
     65 
     66     // Copy each channel's data into the appropriate spot.
     67     for (int i = 0; i < channel_count_; ++i) {
     68       channel_data_.push_back(data_.get() + i * block_size_per_channel);
     69       if (data)
     70         memcpy(channel_data_[i], data[i], data_size);
     71     }
     72     return;
     73   }
     74 
     75   // Remaining formats are interleaved data.
     76   DCHECK(sample_format_ == kSampleFormatU8 ||
     77          sample_format_ == kSampleFormatS16 ||
     78          sample_format_ == kSampleFormatS32 ||
     79          sample_format_ == kSampleFormatF32) << sample_format_;
     80   // Allocate our own buffer and copy the supplied data into it. Buffer must
     81   // contain the data for all channels.
     82   data_size *= channel_count_;
     83   data_.reset(
     84       static_cast<uint8*>(base::AlignedAlloc(data_size, kChannelAlignment)));
     85   channel_data_.reserve(1);
     86   channel_data_.push_back(data_.get());
     87   if (data)
     88     memcpy(data_.get(), data[0], data_size);
     89 }
     90 
     91 AudioBuffer::~AudioBuffer() {}
     92 
     93 // static
     94 scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom(
     95     SampleFormat sample_format,
     96     ChannelLayout channel_layout,
     97     int channel_count,
     98     int sample_rate,
     99     int frame_count,
    100     const uint8* const* data,
    101     const base::TimeDelta timestamp) {
    102   // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
    103   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
    104   CHECK(data[0]);
    105   return make_scoped_refptr(new AudioBuffer(sample_format,
    106                                             channel_layout,
    107                                             channel_count,
    108                                             sample_rate,
    109                                             frame_count,
    110                                             true,
    111                                             data,
    112                                             timestamp));
    113 }
    114 
    115 // static
    116 scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer(
    117     SampleFormat sample_format,
    118     ChannelLayout channel_layout,
    119     int channel_count,
    120     int sample_rate,
    121     int frame_count) {
    122   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
    123   return make_scoped_refptr(new AudioBuffer(sample_format,
    124                                             channel_layout,
    125                                             channel_count,
    126                                             sample_rate,
    127                                             frame_count,
    128                                             true,
    129                                             NULL,
    130                                             kNoTimestamp()));
    131 }
    132 
    133 // static
    134 scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer(
    135     ChannelLayout channel_layout,
    136     int channel_count,
    137     int sample_rate,
    138     int frame_count,
    139     const base::TimeDelta timestamp) {
    140   CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
    141   // Since data == NULL, format doesn't matter.
    142   return make_scoped_refptr(new AudioBuffer(kSampleFormatF32,
    143                                             channel_layout,
    144                                             channel_count,
    145                                             sample_rate,
    146                                             frame_count,
    147                                             false,
    148                                             NULL,
    149                                             timestamp));
    150 }
    151 
    152 // static
    153 scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() {
    154   return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat,
    155                                             CHANNEL_LAYOUT_NONE,
    156                                             0,
    157                                             0,
    158                                             0,
    159                                             false,
    160                                             NULL,
    161                                             kNoTimestamp()));
    162 }
    163 
    164 // Convert int16 values in the range [kint16min, kint16max] to [-1.0, 1.0].
    165 static inline float ConvertS16ToFloat(int16 value) {
    166   return value * (value < 0 ? -1.0f / kint16min : 1.0f / kint16max);
    167 }
    168 
    169 void AudioBuffer::ReadFrames(int frames_to_copy,
    170                              int source_frame_offset,
    171                              int dest_frame_offset,
    172                              AudioBus* dest) {
    173   // Deinterleave each channel (if necessary) and convert to 32bit
    174   // floating-point with nominal range -1.0 -> +1.0 (if necessary).
    175 
    176   // |dest| must have the same number of channels, and the number of frames
    177   // specified must be in range.
    178   DCHECK(!end_of_stream());
    179   DCHECK_EQ(dest->channels(), channel_count_);
    180   DCHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_);
    181   DCHECK_LE(dest_frame_offset + frames_to_copy, dest->frames());
    182 
    183   // Move the start past any frames that have been trimmed.
    184   source_frame_offset += trim_start_;
    185 
    186   if (!data_) {
    187     // Special case for an empty buffer.
    188     dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy);
    189     return;
    190   }
    191 
    192   if (sample_format_ == kSampleFormatPlanarF32) {
    193     // Format is planar float32. Copy the data from each channel as a block.
    194     for (int ch = 0; ch < channel_count_; ++ch) {
    195       const float* source_data =
    196           reinterpret_cast<const float*>(channel_data_[ch]) +
    197           source_frame_offset;
    198       memcpy(dest->channel(ch) + dest_frame_offset,
    199              source_data,
    200              sizeof(float) * frames_to_copy);
    201     }
    202     return;
    203   }
    204 
    205   if (sample_format_ == kSampleFormatPlanarS16) {
    206     // Format is planar signed16. Convert each value into float and insert into
    207     // output channel data.
    208     for (int ch = 0; ch < channel_count_; ++ch) {
    209       const int16* source_data =
    210           reinterpret_cast<const int16*>(channel_data_[ch]) +
    211           source_frame_offset;
    212       float* dest_data = dest->channel(ch) + dest_frame_offset;
    213       for (int i = 0; i < frames_to_copy; ++i) {
    214         dest_data[i] = ConvertS16ToFloat(source_data[i]);
    215       }
    216     }
    217     return;
    218   }
    219 
    220   if (sample_format_ == kSampleFormatF32) {
    221     // Format is interleaved float32. Copy the data into each channel.
    222     const float* source_data = reinterpret_cast<const float*>(data_.get()) +
    223                                source_frame_offset * channel_count_;
    224     for (int ch = 0; ch < channel_count_; ++ch) {
    225       float* dest_data = dest->channel(ch) + dest_frame_offset;
    226       for (int i = 0, offset = ch; i < frames_to_copy;
    227            ++i, offset += channel_count_) {
    228         dest_data[i] = source_data[offset];
    229       }
    230     }
    231     return;
    232   }
    233 
    234   // Remaining formats are integer interleaved data. Use the deinterleaving code
    235   // in AudioBus to copy the data.
    236   DCHECK(sample_format_ == kSampleFormatU8 ||
    237          sample_format_ == kSampleFormatS16 ||
    238          sample_format_ == kSampleFormatS32);
    239   int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
    240   int frame_size = channel_count_ * bytes_per_channel;
    241   const uint8* source_data = data_.get() + source_frame_offset * frame_size;
    242   dest->FromInterleavedPartial(
    243       source_data, dest_frame_offset, frames_to_copy, bytes_per_channel);
    244 }
    245 
    246 void AudioBuffer::TrimStart(int frames_to_trim) {
    247   CHECK_GE(frames_to_trim, 0);
    248   CHECK_LE(frames_to_trim, adjusted_frame_count_);
    249 
    250   // Adjust the number of frames in this buffer and where the start really is.
    251   adjusted_frame_count_ -= frames_to_trim;
    252   trim_start_ += frames_to_trim;
    253 
    254   // Adjust timestamp_ and duration_ to reflect the smaller number of frames.
    255   const base::TimeDelta old_duration = duration_;
    256   duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
    257   timestamp_ += old_duration - duration_;
    258 }
    259 
    260 void AudioBuffer::TrimEnd(int frames_to_trim) {
    261   CHECK_GE(frames_to_trim, 0);
    262   CHECK_LE(frames_to_trim, adjusted_frame_count_);
    263 
    264   // Adjust the number of frames and duration for this buffer.
    265   adjusted_frame_count_ -= frames_to_trim;
    266   duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
    267 }
    268 
    269 void AudioBuffer::TrimRange(int start, int end) {
    270   CHECK_GE(start, 0);
    271   CHECK_LE(end, adjusted_frame_count_);
    272 
    273   const int frames_to_trim = end - start;
    274   CHECK_GE(frames_to_trim, 0);
    275   CHECK_LE(frames_to_trim, adjusted_frame_count_);
    276 
    277   const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
    278   const int frames_to_copy = adjusted_frame_count_ - end;
    279   if (frames_to_copy > 0) {
    280     switch (sample_format_) {
    281       case kSampleFormatPlanarS16:
    282       case kSampleFormatPlanarF32:
    283         // Planar data must be shifted per channel.
    284         for (int ch = 0; ch < channel_count_; ++ch) {
    285           memmove(channel_data_[ch] + (trim_start_ + start) * bytes_per_channel,
    286                   channel_data_[ch] + (trim_start_ + end) * bytes_per_channel,
    287                   bytes_per_channel * frames_to_copy);
    288         }
    289         break;
    290       case kSampleFormatU8:
    291       case kSampleFormatS16:
    292       case kSampleFormatS32:
    293       case kSampleFormatF32: {
    294         // Interleaved data can be shifted all at once.
    295         const int frame_size = channel_count_ * bytes_per_channel;
    296         memmove(channel_data_[0] + (trim_start_ + start) * frame_size,
    297                 channel_data_[0] + (trim_start_ + end) * frame_size,
    298                 frame_size * frames_to_copy);
    299         break;
    300       }
    301       case kUnknownSampleFormat:
    302         NOTREACHED() << "Invalid sample format!";
    303     }
    304   } else {
    305     CHECK_EQ(frames_to_copy, 0);
    306   }
    307 
    308   // Trim the leftover data off the end of the buffer and update duration.
    309   TrimEnd(frames_to_trim);
    310 }
    311 
    312 }  // namespace media
    313