OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_bus.h" | 5 #include "media/base/audio_bus.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "media/audio/audio_parameters.h" | 10 #include "media/audio/audio_parameters.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 ++i, offset += channels) { | 54 ++i, offset += channels) { |
55 Fixed v = static_cast<Fixed>(source[offset]) - kBias; | 55 Fixed v = static_cast<Fixed>(source[offset]) - kBias; |
56 channel_data[i] = v * (v < 0 ? kMinScale : kMaxScale); | 56 channel_data[i] = v * (v < 0 ? kMinScale : kMaxScale); |
57 } | 57 } |
58 } | 58 } |
59 } | 59 } |
60 | 60 |
61 // |Format| is the destination type, |Fixed| is a type larger than |Format| | 61 // |Format| is the destination type, |Fixed| is a type larger than |Format| |
62 // such that operations can be made without overflowing. | 62 // such that operations can be made without overflowing. |
63 template<class Format, class Fixed> | 63 template<class Format, class Fixed> |
64 static void ToInterleavedInternal(const AudioBus* source, int frames, | 64 static void ToInterleavedInternal(const AudioBus* source, int start_frame, |
65 void* dst) { | 65 int frames, void* dst) { |
66 Format* dest = static_cast<Format*>(dst); | 66 Format* dest = static_cast<Format*>(dst); |
67 | 67 |
68 static const Format kBias = std::numeric_limits<Format>::is_signed ? 0 : | 68 static const Format kBias = std::numeric_limits<Format>::is_signed ? 0 : |
69 std::numeric_limits<Format>::max() / 2 + 1; | 69 std::numeric_limits<Format>::max() / 2 + 1; |
70 static const Fixed kMaxValue = kBias ? kBias - 1 : | 70 static const Fixed kMaxValue = kBias ? kBias - 1 : |
71 std::numeric_limits<Format>::max(); | 71 std::numeric_limits<Format>::max(); |
72 static const Fixed kMinValue = kBias ? -kBias : | 72 static const Fixed kMinValue = kBias ? -kBias : |
73 std::numeric_limits<Format>::min(); | 73 std::numeric_limits<Format>::min(); |
74 | 74 |
75 int channels = source->channels(); | 75 int channels = source->channels(); |
76 for (int ch = 0; ch < channels; ++ch) { | 76 for (int ch = 0; ch < channels; ++ch) { |
77 const float* channel_data = source->channel(ch); | 77 const float* channel_data = source->channel(ch); |
78 for (int i = 0, offset = ch; i < frames; ++i, offset += channels) { | 78 for (int i = start_frame, offset = ch; i < frames; |
| 79 ++i, offset += channels) { |
79 float v = channel_data[i]; | 80 float v = channel_data[i]; |
80 Fixed sample = v * (v < 0 ? -kMinValue : kMaxValue); | 81 Fixed sample = v * (v < 0 ? -kMinValue : kMaxValue); |
81 | 82 |
82 if (sample > kMaxValue) | 83 if (sample > kMaxValue) |
83 sample = kMaxValue; | 84 sample = kMaxValue; |
84 else if (sample < kMinValue) | 85 else if (sample < kMinValue) |
85 sample = kMinValue; | 86 sample = kMinValue; |
86 | 87 |
87 dest[offset] = static_cast<Format>(sample) + kBias; | 88 dest[offset] = static_cast<Format>(sample) + kBias; |
88 } | 89 } |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 // Zero any remaining frames. | 262 // Zero any remaining frames. |
262 ZeroFramesPartial(frames, frames_ - frames); | 263 ZeroFramesPartial(frames, frames_ - frames); |
263 } | 264 } |
264 } | 265 } |
265 | 266 |
266 void AudioBus::FromInterleaved(const void* source, int frames, | 267 void AudioBus::FromInterleaved(const void* source, int frames, |
267 int bytes_per_sample) { | 268 int bytes_per_sample) { |
268 FromInterleavedPartial(source, 0, frames, bytes_per_sample); | 269 FromInterleavedPartial(source, 0, frames, bytes_per_sample); |
269 } | 270 } |
270 | 271 |
271 // TODO(dalecurtis): See if intrinsic optimizations help any here. | |
272 void AudioBus::ToInterleaved(int frames, int bytes_per_sample, | 272 void AudioBus::ToInterleaved(int frames, int bytes_per_sample, |
273 void* dest) const { | 273 void* dest) const { |
274 CheckOverflow(0, frames, frames_); | 274 ToInterleavedPartial(0, frames, bytes_per_sample, dest); |
| 275 } |
| 276 |
| 277 // TODO(dalecurtis): See if intrinsic optimizations help any here. |
| 278 void AudioBus::ToInterleavedPartial(int start_frame, int frames, |
| 279 int bytes_per_sample, void* dest) const { |
| 280 CheckOverflow(start_frame, frames, frames_); |
275 switch (bytes_per_sample) { | 281 switch (bytes_per_sample) { |
276 case 1: | 282 case 1: |
277 ToInterleavedInternal<uint8, int16>(this, frames, dest); | 283 ToInterleavedInternal<uint8, int16>(this, start_frame, frames, dest); |
278 break; | 284 break; |
279 case 2: | 285 case 2: |
280 ToInterleavedInternal<int16, int32>(this, frames, dest); | 286 ToInterleavedInternal<int16, int32>(this, start_frame, frames, dest); |
281 break; | 287 break; |
282 case 4: | 288 case 4: |
283 ToInterleavedInternal<int32, int64>(this, frames, dest); | 289 ToInterleavedInternal<int32, int64>(this, start_frame, frames, dest); |
284 break; | 290 break; |
285 default: | 291 default: |
286 NOTREACHED() << "Unsupported bytes per sample encountered."; | 292 NOTREACHED() << "Unsupported bytes per sample encountered."; |
287 memset(dest, 0, frames * bytes_per_sample); | 293 memset(dest, 0, frames * bytes_per_sample); |
288 return; | 294 return; |
289 } | 295 } |
290 } | 296 } |
291 | 297 |
292 void AudioBus::CopyTo(AudioBus* dest) const { | 298 void AudioBus::CopyTo(AudioBus* dest) const { |
293 CHECK_EQ(channels(), dest->channels()); | 299 CHECK_EQ(channels(), dest->channels()); |
294 CHECK_EQ(frames(), dest->frames()); | 300 CHECK_EQ(frames(), dest->frames()); |
295 | 301 |
296 // Since we don't know if the other AudioBus is wrapped or not (and we don't | 302 // Since we don't know if the other AudioBus is wrapped or not (and we don't |
297 // want to care), just copy using the public channel() accessors. | 303 // want to care), just copy using the public channel() accessors. |
298 for (int i = 0; i < channels(); ++i) | 304 for (int i = 0; i < channels(); ++i) |
299 memcpy(dest->channel(i), channel(i), sizeof(*channel(i)) * frames()); | 305 memcpy(dest->channel(i), channel(i), sizeof(*channel(i)) * frames()); |
300 } | 306 } |
301 | 307 |
302 } // namespace media | 308 } // namespace media |
OLD | NEW |