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