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