Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/base/audio_buffer.h" | 5 #include "media/base/audio_buffer.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "media/base/audio_bus.h" | 10 #include "media/base/audio_bus.h" |
| 11 #include "media/base/audio_sample_conversion.h" | |
| 11 #include "media/base/limits.h" | 12 #include "media/base/limits.h" |
| 12 #include "media/base/timestamp_constants.h" | 13 #include "media/base/timestamp_constants.h" |
| 13 | 14 |
| 14 namespace media { | 15 namespace media { |
| 15 | 16 |
| 16 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { | 17 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { |
| 17 DCHECK_GT(sample_rate, 0); | 18 DCHECK_GT(sample_rate, 0); |
| 18 return base::TimeDelta::FromMicroseconds( | 19 return base::TimeDelta::FromMicroseconds( |
| 19 frames * base::Time::kMicrosecondsPerSecond / sample_rate); | 20 frames * base::Time::kMicrosecondsPerSecond / sample_rate); |
| 20 } | 21 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 0, | 159 0, |
| 159 0, | 160 0, |
| 160 false, | 161 false, |
| 161 NULL, | 162 NULL, |
| 162 kNoTimestamp())); | 163 kNoTimestamp())); |
| 163 } | 164 } |
| 164 | 165 |
| 165 template <typename Target, typename Dest> | 166 template <typename Target, typename Dest> |
| 166 static inline Dest ConvertSample(Target value); | 167 static inline Dest ConvertSample(Target value); |
| 167 | 168 |
| 168 // Convert int16_t values in the range [INT16_MIN, INT16_MAX] to [-1.0, 1.0]. | |
| 169 template <> | |
| 170 inline float ConvertSample<int16_t, float>(int16_t value) { | |
| 171 return value * (value < 0 ? -1.0f / std::numeric_limits<int16_t>::min() | |
| 172 : 1.0f / std::numeric_limits<int16_t>::max()); | |
| 173 } | |
| 174 | |
| 175 // Specializations for int32_t | 169 // Specializations for int32_t |
| 176 template <> | 170 template <> |
| 177 inline int32_t ConvertSample<int16_t, int32_t>(int16_t value) { | 171 inline int32_t ConvertSample<int16_t, int32_t>(int16_t value) { |
|
DaleCurtis
2016/04/01 19:31:20
Do we still need the rest of these?
| |
| 178 return static_cast<int32_t>(value) << 16; | 172 return static_cast<int32_t>(value) << 16; |
| 179 } | 173 } |
| 180 | 174 |
| 181 template <> | 175 template <> |
| 182 inline int32_t ConvertSample<int32_t, int32_t>(int32_t value) { | 176 inline int32_t ConvertSample<int32_t, int32_t>(int32_t value) { |
| 183 return value; | 177 return value; |
| 184 } | 178 } |
| 185 | 179 |
| 186 template <> | |
| 187 inline int32_t ConvertSample<float, int32_t>(float value) { | |
| 188 return static_cast<int32_t>( | |
| 189 value < 0 ? (-value) * std::numeric_limits<int32_t>::min() | |
| 190 : value * std::numeric_limits<int32_t>::max()); | |
| 191 } | |
| 192 | |
| 193 // Specializations for int16_t | 180 // Specializations for int16_t |
| 194 template <> | 181 template <> |
| 195 inline int16_t ConvertSample<int16_t, int16_t>(int16_t sample) { | 182 inline int16_t ConvertSample<int16_t, int16_t>(int16_t sample) { |
| 196 return sample; | 183 return sample; |
| 197 } | 184 } |
| 198 | 185 |
| 199 template <> | 186 template <> |
| 200 inline int16_t ConvertSample<int32_t, int16_t>(int32_t sample) { | 187 inline int16_t ConvertSample<int32_t, int16_t>(int32_t sample) { |
| 201 return sample >> 16; | 188 return sample >> 16; |
| 202 } | 189 } |
| 203 | 190 |
| 204 template <> | |
| 205 inline int16_t ConvertSample<float, int16_t>(float sample) { | |
| 206 return static_cast<int16_t>( | |
| 207 nearbyint(sample < 0 ? (-sample) * std::numeric_limits<int16_t>::min() | |
| 208 : sample * std::numeric_limits<int16_t>::max())); | |
| 209 } | |
| 210 | |
| 211 void AudioBuffer::AdjustSampleRate(int sample_rate) { | 191 void AudioBuffer::AdjustSampleRate(int sample_rate) { |
| 212 DCHECK(!end_of_stream_); | 192 DCHECK(!end_of_stream_); |
| 213 sample_rate_ = sample_rate; | 193 sample_rate_ = sample_rate; |
| 214 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 194 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); |
| 215 } | 195 } |
| 216 | 196 |
| 217 void AudioBuffer::ReadFrames(int frames_to_copy, | 197 void AudioBuffer::ReadFrames(int frames_to_copy, |
| 218 int source_frame_offset, | 198 int source_frame_offset, |
| 219 int dest_frame_offset, | 199 int dest_frame_offset, |
| 220 AudioBus* dest) { | 200 AudioBus* dest) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 251 } | 231 } |
| 252 | 232 |
| 253 if (sample_format_ == kSampleFormatPlanarS16) { | 233 if (sample_format_ == kSampleFormatPlanarS16) { |
| 254 // Format is planar signed16. Convert each value into float and insert into | 234 // Format is planar signed16. Convert each value into float and insert into |
| 255 // output channel data. | 235 // output channel data. |
| 256 for (int ch = 0; ch < channel_count_; ++ch) { | 236 for (int ch = 0; ch < channel_count_; ++ch) { |
| 257 const int16_t* source_data = | 237 const int16_t* source_data = |
| 258 reinterpret_cast<const int16_t*>(channel_data_[ch]) + | 238 reinterpret_cast<const int16_t*>(channel_data_[ch]) + |
| 259 source_frame_offset; | 239 source_frame_offset; |
| 260 float* dest_data = dest->channel(ch) + dest_frame_offset; | 240 float* dest_data = dest->channel(ch) + dest_frame_offset; |
| 261 for (int i = 0; i < frames_to_copy; ++i) { | 241 DeinterleaveOneChannel<int16_t>(source_data, 0, frames_to_copy, dest_data, |
| 262 dest_data[i] = ConvertSample<int16_t, float>(source_data[i]); | 242 1, 0); |
| 263 } | |
| 264 } | 243 } |
| 265 return; | 244 return; |
| 266 } | 245 } |
| 267 | 246 |
| 268 if (sample_format_ == kSampleFormatF32) { | 247 if (sample_format_ == kSampleFormatF32) { |
| 269 // Format is interleaved float32. Copy the data into each channel. | 248 // Format is interleaved float32. Copy the data into each channel. |
| 270 const float* source_data = reinterpret_cast<const float*>(data_.get()) + | 249 const float* source_data = reinterpret_cast<const float*>(data_.get()) + |
| 271 source_frame_offset * channel_count_; | 250 source_frame_offset * channel_count_; |
| 272 for (int ch = 0; ch < channel_count_; ++ch) { | 251 for (int ch = 0; ch < channel_count_; ++ch) { |
| 273 float* dest_data = dest->channel(ch) + dest_frame_offset; | 252 float* dest_data = dest->channel(ch) + dest_frame_offset; |
| 274 for (int i = 0, offset = ch; i < frames_to_copy; | 253 DeinterleaveOneChannel<float>(source_data, 0, frames_to_copy, dest_data, |
| 275 ++i, offset += channel_count_) { | 254 channel_count_, ch); |
| 276 dest_data[i] = source_data[offset]; | |
| 277 } | |
| 278 } | 255 } |
| 279 return; | 256 return; |
| 280 } | 257 } |
| 281 | 258 |
| 282 // Remaining formats are integer interleaved data. Use the deinterleaving code | 259 // Remaining formats are integer interleaved data. Use the deinterleaving code |
| 283 // in AudioBus to copy the data. | 260 // in AudioBus to copy the data. |
| 284 DCHECK( | 261 DCHECK( |
| 285 sample_format_ == kSampleFormatU8 || sample_format_ == kSampleFormatS16 || | 262 sample_format_ == kSampleFormatU8 || sample_format_ == kSampleFormatS16 || |
| 286 sample_format_ == kSampleFormatS24 || sample_format_ == kSampleFormatS32); | 263 sample_format_ == kSampleFormatS24 || sample_format_ == kSampleFormatS32); |
| 287 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); | 264 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 300 const Target* source_data = | 277 const Target* source_data = |
| 301 reinterpret_cast<const Target*>(channel_data[ch]) + trim_start; | 278 reinterpret_cast<const Target*>(channel_data[ch]) + trim_start; |
| 302 for (size_t i = 0, offset = ch; i < frames_to_copy; | 279 for (size_t i = 0, offset = ch; i < frames_to_copy; |
| 303 ++i, offset += channel_data.size()) { | 280 ++i, offset += channel_data.size()) { |
| 304 dest_data[offset] = ConvertSample<Target, Dest>(source_data[i]); | 281 dest_data[offset] = ConvertSample<Target, Dest>(source_data[i]); |
| 305 } | 282 } |
| 306 } | 283 } |
| 307 } | 284 } |
| 308 | 285 |
| 309 template <typename Dest> | 286 template <typename Dest> |
| 287 void InterleaveAndConvertFloat(const std::vector<uint8_t*>& channel_data, | |
| 288 size_t frames_to_copy, | |
| 289 int trim_start, | |
| 290 Dest* dest_data) { | |
| 291 for (size_t ch = 0; ch < channel_data.size(); ++ch) { | |
| 292 const float* source_data = | |
| 293 reinterpret_cast<const float*>(channel_data[ch]) + trim_start; | |
| 294 InterleaveOneChannel<Dest>(source_data, 0, frames_to_copy, dest_data, | |
| 295 channel_data.size(), ch); | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 template <typename Dest> | |
| 310 void ReadFramesInterleaved(const std::vector<uint8_t*>& channel_data, | 300 void ReadFramesInterleaved(const std::vector<uint8_t*>& channel_data, |
| 311 int channel_count, | 301 int channel_count, |
| 312 SampleFormat sample_format, | 302 SampleFormat sample_format, |
| 313 int frames_to_copy, | 303 int frames_to_copy, |
| 314 int trim_start, | 304 int trim_start, |
| 315 Dest* dest_data) { | 305 Dest* dest_data) { |
| 316 switch (sample_format) { | 306 switch (sample_format) { |
| 317 case kSampleFormatU8: | 307 case kSampleFormatU8: |
| 318 NOTREACHED(); | 308 NOTREACHED(); |
| 319 break; | 309 break; |
| 320 case kSampleFormatS16: | 310 case kSampleFormatS16: |
| 321 InterleaveAndConvert<int16_t, Dest>( | 311 InterleaveAndConvert<int16_t, Dest>( |
| 322 channel_data, frames_to_copy * channel_count, trim_start, dest_data); | 312 channel_data, frames_to_copy * channel_count, trim_start, dest_data); |
| 323 break; | 313 break; |
| 324 case kSampleFormatS24: | 314 case kSampleFormatS24: |
| 325 case kSampleFormatS32: | 315 case kSampleFormatS32: |
| 326 InterleaveAndConvert<int32_t, Dest>( | 316 InterleaveAndConvert<int32_t, Dest>( |
| 327 channel_data, frames_to_copy * channel_count, trim_start, dest_data); | 317 channel_data, frames_to_copy * channel_count, trim_start, dest_data); |
| 328 break; | 318 break; |
| 329 case kSampleFormatF32: | 319 case kSampleFormatF32: |
| 330 InterleaveAndConvert<float, Dest>( | 320 InterleaveAndConvertFloat<Dest>( |
| 331 channel_data, frames_to_copy * channel_count, trim_start, dest_data); | 321 channel_data, frames_to_copy * channel_count, trim_start, dest_data); |
| 332 break; | 322 break; |
| 333 case kSampleFormatPlanarS16: | 323 case kSampleFormatPlanarS16: |
| 334 InterleaveAndConvert<int16_t, Dest>(channel_data, frames_to_copy, | 324 InterleaveAndConvert<int16_t, Dest>(channel_data, frames_to_copy, |
| 335 trim_start, dest_data); | 325 trim_start, dest_data); |
| 336 break; | 326 break; |
| 337 case kSampleFormatPlanarF32: | 327 case kSampleFormatPlanarF32: |
| 338 InterleaveAndConvert<float, Dest>(channel_data, frames_to_copy, | 328 InterleaveAndConvertFloat<Dest>(channel_data, frames_to_copy, trim_start, |
| 339 trim_start, dest_data); | 329 dest_data); |
| 340 break; | 330 break; |
| 341 case kSampleFormatPlanarS32: | 331 case kSampleFormatPlanarS32: |
| 342 InterleaveAndConvert<int32_t, Dest>(channel_data, frames_to_copy, | 332 InterleaveAndConvert<int32_t, Dest>(channel_data, frames_to_copy, |
| 343 trim_start, dest_data); | 333 trim_start, dest_data); |
| 344 break; | 334 break; |
| 345 case kUnknownSampleFormat: | 335 case kUnknownSampleFormat: |
| 346 NOTREACHED(); | 336 NOTREACHED(); |
| 347 break; | 337 break; |
| 348 } | 338 } |
| 349 } | 339 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 } | 414 } |
| 425 } else { | 415 } else { |
| 426 CHECK_EQ(frames_to_copy, 0); | 416 CHECK_EQ(frames_to_copy, 0); |
| 427 } | 417 } |
| 428 | 418 |
| 429 // Trim the leftover data off the end of the buffer and update duration. | 419 // Trim the leftover data off the end of the buffer and update duration. |
| 430 TrimEnd(frames_to_trim); | 420 TrimEnd(frames_to_trim); |
| 431 } | 421 } |
| 432 | 422 |
| 433 } // namespace media | 423 } // namespace media |
| OLD | NEW |