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 <algorithm> |
7 #include <cmath> | 8 #include <cmath> |
8 | 9 |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "media/base/audio_bus.h" | 11 #include "media/base/audio_bus.h" |
| 12 #include "media/base/audio_sample_conversion.h" |
11 #include "media/base/limits.h" | 13 #include "media/base/limits.h" |
12 #include "media/base/timestamp_constants.h" | 14 #include "media/base/timestamp_constants.h" |
13 | 15 |
14 namespace media { | 16 namespace media { |
15 | 17 |
16 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { | 18 static base::TimeDelta CalculateDuration(int frames, double sample_rate) { |
17 DCHECK_GT(sample_rate, 0); | 19 DCHECK_GT(sample_rate, 0); |
18 return base::TimeDelta::FromMicroseconds( | 20 return base::TimeDelta::FromMicroseconds( |
19 frames * base::Time::kMicrosecondsPerSecond / sample_rate); | 21 frames * base::Time::kMicrosecondsPerSecond / sample_rate); |
20 } | 22 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, | 157 return make_scoped_refptr(new AudioBuffer(kUnknownSampleFormat, |
156 CHANNEL_LAYOUT_NONE, | 158 CHANNEL_LAYOUT_NONE, |
157 0, | 159 0, |
158 0, | 160 0, |
159 0, | 161 0, |
160 false, | 162 false, |
161 NULL, | 163 NULL, |
162 kNoTimestamp())); | 164 kNoTimestamp())); |
163 } | 165 } |
164 | 166 |
165 template <typename Target, typename Dest> | |
166 static inline Dest ConvertSample(Target value); | |
167 | |
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 | |
176 template <> | |
177 inline int32_t ConvertSample<int16_t, int32_t>(int16_t value) { | |
178 return static_cast<int32_t>(value) << 16; | |
179 } | |
180 | |
181 template <> | |
182 inline int32_t ConvertSample<int32_t, int32_t>(int32_t value) { | |
183 return value; | |
184 } | |
185 | |
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 | |
194 template <> | |
195 inline int16_t ConvertSample<int16_t, int16_t>(int16_t sample) { | |
196 return sample; | |
197 } | |
198 | |
199 template <> | |
200 inline int16_t ConvertSample<int32_t, int16_t>(int32_t sample) { | |
201 return sample >> 16; | |
202 } | |
203 | |
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) { | 167 void AudioBuffer::AdjustSampleRate(int sample_rate) { |
212 DCHECK(!end_of_stream_); | 168 DCHECK(!end_of_stream_); |
213 sample_rate_ = sample_rate; | 169 sample_rate_ = sample_rate; |
214 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); | 170 duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_); |
215 } | 171 } |
216 | 172 |
217 void AudioBuffer::ReadFrames(int frames_to_copy, | 173 void AudioBuffer::ReadFrames(int frames_to_copy, |
218 int source_frame_offset, | 174 int source_frame_offset, |
219 int dest_frame_offset, | 175 int dest_frame_offset, |
220 AudioBus* dest) { | 176 AudioBus* dest) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 DCHECK( | 240 DCHECK( |
285 sample_format_ == kSampleFormatU8 || sample_format_ == kSampleFormatS16 || | 241 sample_format_ == kSampleFormatU8 || sample_format_ == kSampleFormatS16 || |
286 sample_format_ == kSampleFormatS24 || sample_format_ == kSampleFormatS32); | 242 sample_format_ == kSampleFormatS24 || sample_format_ == kSampleFormatS32); |
287 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); | 243 int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_); |
288 int frame_size = channel_count_ * bytes_per_channel; | 244 int frame_size = channel_count_ * bytes_per_channel; |
289 const uint8_t* source_data = data_.get() + source_frame_offset * frame_size; | 245 const uint8_t* source_data = data_.get() + source_frame_offset * frame_size; |
290 dest->FromInterleavedPartial( | 246 dest->FromInterleavedPartial( |
291 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); | 247 source_data, dest_frame_offset, frames_to_copy, bytes_per_channel); |
292 } | 248 } |
293 | 249 |
294 template <class Target, typename Dest> | |
295 void InterleaveAndConvert(const std::vector<uint8_t*>& channel_data, | |
296 size_t frames_to_copy, | |
297 int trim_start, | |
298 Dest* dest_data) { | |
299 for (size_t ch = 0; ch < channel_data.size(); ++ch) { | |
300 const Target* source_data = | |
301 reinterpret_cast<const Target*>(channel_data[ch]) + trim_start; | |
302 for (size_t i = 0, offset = ch; i < frames_to_copy; | |
303 ++i, offset += channel_data.size()) { | |
304 dest_data[offset] = ConvertSample<Target, Dest>(source_data[i]); | |
305 } | |
306 } | |
307 } | |
308 | |
309 template <typename Dest> | 250 template <typename Dest> |
310 void ReadFramesInterleaved(const std::vector<uint8_t*>& channel_data, | 251 void ReadFramesInterleaved(const std::vector<uint8_t*>& channel_data, |
311 int channel_count, | 252 int channel_count, |
312 SampleFormat sample_format, | 253 SampleFormat sample_format, |
313 int frames_to_copy, | 254 int frames_to_copy, |
314 int trim_start, | 255 int trim_start, |
315 Dest* dest_data) { | 256 Dest* dest_data) { |
316 switch (sample_format) { | 257 switch (sample_format) { |
317 case kSampleFormatU8: | 258 case kSampleFormatU8: |
318 NOTREACHED(); | 259 NOTREACHED(); |
319 break; | 260 break; |
320 case kSampleFormatS16: | 261 case kSampleFormatS16: |
321 InterleaveAndConvert<int16_t, Dest>( | 262 PlanarToInterleaved<int16_t, Dest>( |
322 channel_data, frames_to_copy * channel_count, trim_start, dest_data); | 263 channel_data, frames_to_copy * channel_count, trim_start, dest_data); |
323 break; | 264 break; |
324 case kSampleFormatS24: | 265 case kSampleFormatS24: |
325 case kSampleFormatS32: | 266 case kSampleFormatS32: |
326 InterleaveAndConvert<int32_t, Dest>( | 267 PlanarToInterleaved<int32_t, Dest>( |
327 channel_data, frames_to_copy * channel_count, trim_start, dest_data); | 268 channel_data, frames_to_copy * channel_count, trim_start, dest_data); |
328 break; | 269 break; |
329 case kSampleFormatF32: | 270 case kSampleFormatF32: |
330 InterleaveAndConvert<float, Dest>( | 271 PlanarToInterleaved<float, Dest>( |
331 channel_data, frames_to_copy * channel_count, trim_start, dest_data); | 272 channel_data, frames_to_copy * channel_count, trim_start, dest_data); |
332 break; | 273 break; |
333 case kSampleFormatPlanarS16: | 274 case kSampleFormatPlanarS16: |
334 InterleaveAndConvert<int16_t, Dest>(channel_data, frames_to_copy, | 275 PlanarToInterleaved<int16_t, Dest>(channel_data, frames_to_copy, |
335 trim_start, dest_data); | 276 trim_start, dest_data); |
336 break; | 277 break; |
337 case kSampleFormatPlanarF32: | 278 case kSampleFormatPlanarF32: |
338 InterleaveAndConvert<float, Dest>(channel_data, frames_to_copy, | 279 PlanarToInterleaved<float, Dest>(channel_data, frames_to_copy, trim_start, |
339 trim_start, dest_data); | 280 dest_data); |
340 break; | 281 break; |
341 case kSampleFormatPlanarS32: | 282 case kSampleFormatPlanarS32: |
342 InterleaveAndConvert<int32_t, Dest>(channel_data, frames_to_copy, | 283 PlanarToInterleaved<int32_t, Dest>(channel_data, frames_to_copy, |
343 trim_start, dest_data); | 284 trim_start, dest_data); |
344 break; | 285 break; |
345 case kUnknownSampleFormat: | 286 case kUnknownSampleFormat: |
346 NOTREACHED(); | 287 NOTREACHED(); |
347 break; | 288 break; |
348 } | 289 } |
349 } | 290 } |
350 | 291 |
351 void AudioBuffer::ReadFramesInterleavedS32(int frames_to_copy, | 292 void AudioBuffer::ReadFramesInterleavedS32(int frames_to_copy, |
352 int32_t* dest_data) { | 293 int32_t* dest_data) { |
353 DCHECK_LE(frames_to_copy, adjusted_frame_count_); | 294 DCHECK_LE(frames_to_copy, adjusted_frame_count_); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 } | 365 } |
425 } else { | 366 } else { |
426 CHECK_EQ(frames_to_copy, 0); | 367 CHECK_EQ(frames_to_copy, 0); |
427 } | 368 } |
428 | 369 |
429 // Trim the leftover data off the end of the buffer and update duration. | 370 // Trim the leftover data off the end of the buffer and update duration. |
430 TrimEnd(frames_to_trim); | 371 TrimEnd(frames_to_trim); |
431 } | 372 } |
432 | 373 |
433 } // namespace media | 374 } // namespace media |
OLD | NEW |