Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: media/base/audio_bus.cc

Issue 13730004: Remove static const from AudioBus interleave methods and optimize! (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | media/base/audio_bus_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "media/base/limits.h" 11 #include "media/base/limits.h"
12 #include "media/base/vector_math.h" 12 #include "media/base/vector_math.h"
13 13
14 namespace media { 14 namespace media {
15 15
16 static const uint8 kUint8Bias = 128;
17 static const int16 kUint8Min = -kUint8Bias;
18 static const int16 kUint8Max = kUint8Bias - 1;
19
16 static bool IsAligned(void* ptr) { 20 static bool IsAligned(void* ptr) {
17 return (reinterpret_cast<uintptr_t>(ptr) & 21 return (reinterpret_cast<uintptr_t>(ptr) &
18 (AudioBus::kChannelAlignment - 1)) == 0U; 22 (AudioBus::kChannelAlignment - 1)) == 0U;
19 } 23 }
20 24
21 // Calculates the required size for an AudioBus with the given params, sets 25 // Calculates the required size for an AudioBus with the given params, sets
22 // |aligned_frames| to the actual frame length of each channel array. 26 // |aligned_frames| to the actual frame length of each channel array.
23 static int CalculateMemorySizeInternal(int channels, int frames, 27 static int CalculateMemorySizeInternal(int channels, int frames,
24 int* out_aligned_frames) { 28 int* out_aligned_frames) {
25 // Choose a size such that each channel will be aligned by 29 // Choose a size such that each channel will be aligned by
26 // kChannelAlignment when stored in a contiguous block. 30 // kChannelAlignment when stored in a contiguous block.
27 int aligned_frames = 31 int aligned_frames =
28 ((frames * sizeof(float) + AudioBus::kChannelAlignment - 1) & 32 ((frames * sizeof(float) + AudioBus::kChannelAlignment - 1) &
29 ~(AudioBus::kChannelAlignment - 1)) / sizeof(float); 33 ~(AudioBus::kChannelAlignment - 1)) / sizeof(float);
30 34
31 if (out_aligned_frames) 35 if (out_aligned_frames)
32 *out_aligned_frames = aligned_frames; 36 *out_aligned_frames = aligned_frames;
33 37
34 return sizeof(float) * channels * aligned_frames; 38 return sizeof(float) * channels * aligned_frames;
35 } 39 }
36 40
37 // |Format| is the destination type, |Fixed| is a type larger than |Format| 41 // |Format| is the destination type, |Fixed| is a type larger than |Format|
38 // such that operations can be made without overflowing. 42 // such that operations can be made without overflowing.
39 template<class Format, class Fixed> 43 template<class Format, class Fixed>
40 static void FromInterleavedInternal(const void* src, int start_frame, 44 static void FromInterleavedInternal(const void* src, int start_frame,
41 int frames, AudioBus* dest) { 45 int frames, AudioBus* dest,
46 Format bias, float min, float max) {
42 const Format* source = static_cast<const Format*>(src); 47 const Format* source = static_cast<const Format*>(src);
43 48 const int channels = dest->channels();
44 static const Fixed kBias = std::numeric_limits<Format>::is_signed ? 0 :
45 std::numeric_limits<Format>::max() / 2 + 1;
46 static const float kMaxScale = 1.0f / (kBias ? kBias - 1 :
47 std::numeric_limits<Format>::max());
48 static const float kMinScale = 1.0f / (kBias ? kBias :
49 -static_cast<Fixed>(std::numeric_limits<Format>::min()));
50
51 int channels = dest->channels();
52 for (int ch = 0; ch < channels; ++ch) { 49 for (int ch = 0; ch < channels; ++ch) {
53 float* channel_data = dest->channel(ch); 50 float* channel_data = dest->channel(ch);
54 for (int i = start_frame, offset = ch; i < start_frame + frames; 51 for (int i = start_frame, offset = ch; i < start_frame + frames;
55 ++i, offset += channels) { 52 ++i, offset += channels) {
56 Fixed v = static_cast<Fixed>(source[offset]) - kBias; 53 const Fixed v = static_cast<Fixed>(source[offset]) - bias;
57 channel_data[i] = v * (v < 0 ? kMinScale : kMaxScale); 54 channel_data[i] = v * (v < 0 ? -min : max);
58 } 55 }
59 } 56 }
60 } 57 }
61 58
62 // |Format| is the destination type, |Fixed| is a type larger than |Format| 59 // |Format| is the destination type, |Fixed| is a type larger than |Format|
63 // such that operations can be made without overflowing. 60 // such that operations can be made without overflowing.
64 template<class Format, class Fixed> 61 template<class Format, class Fixed>
65 static void ToInterleavedInternal(const AudioBus* source, int start_frame, 62 static void ToInterleavedInternal(const AudioBus* source, int start_frame,
66 int frames, void* dst) { 63 int frames, void* dst,
64 Format bias, Fixed min, Fixed max) {
67 Format* dest = static_cast<Format*>(dst); 65 Format* dest = static_cast<Format*>(dst);
68 66 const int channels = source->channels();
69 static const Format kBias = std::numeric_limits<Format>::is_signed ? 0 :
70 std::numeric_limits<Format>::max() / 2 + 1;
71 static const Fixed kMaxValue = kBias ? kBias - 1 :
72 std::numeric_limits<Format>::max();
73 static const Fixed kMinValue = kBias ? -kBias :
74 std::numeric_limits<Format>::min();
75
76 int channels = source->channels();
77 for (int ch = 0; ch < channels; ++ch) { 67 for (int ch = 0; ch < channels; ++ch) {
78 const float* channel_data = source->channel(ch); 68 const float* channel_data = source->channel(ch);
79 for (int i = start_frame, offset = ch; i < start_frame + frames; 69 for (int i = start_frame, offset = ch; i < start_frame + frames;
80 ++i, offset += channels) { 70 ++i, offset += channels) {
81 float v = channel_data[i]; 71 const float v = channel_data[i];
82 Fixed sample = v * (v < 0 ? -kMinValue : kMaxValue);
83 72
84 if (sample > kMaxValue) 73 Fixed sample;
85 sample = kMaxValue; 74 if (v < 0)
86 else if (sample < kMinValue) 75 sample = v <= -1 ? -min : static_cast<Fixed>(v * -min);
87 sample = kMinValue; 76 else
77 sample = v >= 1 ? max : static_cast<Fixed>(v * max);
88 78
89 dest[offset] = static_cast<Format>(sample) + kBias; 79 dest[offset] = static_cast<Format>(sample) + bias;
90 } 80 }
91 } 81 }
92 } 82 }
93 83
94 static void ValidateConfig(size_t channels, int frames) { 84 static void ValidateConfig(size_t channels, int frames) {
95 CHECK_GT(frames, 0); 85 CHECK_GT(frames, 0);
96 CHECK_LE(channels, static_cast<size_t>(limits::kMaxChannels)); 86 CHECK_LE(channels, static_cast<size_t>(limits::kMaxChannels));
97 } 87 }
98 88
99 static void CheckOverflow(int start_frame, int frames, int total_frames) { 89 static void CheckOverflow(int start_frame, int frames, int total_frames) {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 for (int i = 0; i < channels; ++i) 229 for (int i = 0; i < channels; ++i)
240 channel_data_.push_back(data + i * aligned_frames); 230 channel_data_.push_back(data + i * aligned_frames);
241 } 231 }
242 232
243 // TODO(dalecurtis): See if intrinsic optimizations help any here. 233 // TODO(dalecurtis): See if intrinsic optimizations help any here.
244 void AudioBus::FromInterleavedPartial(const void* source, int start_frame, 234 void AudioBus::FromInterleavedPartial(const void* source, int start_frame,
245 int frames, int bytes_per_sample) { 235 int frames, int bytes_per_sample) {
246 CheckOverflow(start_frame, frames, frames_); 236 CheckOverflow(start_frame, frames, frames_);
247 switch (bytes_per_sample) { 237 switch (bytes_per_sample) {
248 case 1: 238 case 1:
249 FromInterleavedInternal<uint8, int16>(source, start_frame, frames, this); 239 FromInterleavedInternal<uint8, int16>(
240 source, start_frame, frames, this,
241 kUint8Bias, 1.0f / kUint8Min, 1.0f / kUint8Max);
250 break; 242 break;
251 case 2: 243 case 2:
252 FromInterleavedInternal<int16, int32>(source, start_frame, frames, this); 244 FromInterleavedInternal<int16, int32>(
245 source, start_frame, frames, this,
246 0, 1.0f / kint16min, 1.0f / kint16max);
253 break; 247 break;
254 case 4: 248 case 4:
255 FromInterleavedInternal<int32, int64>(source, start_frame, frames, this); 249 FromInterleavedInternal<int32, int64>(
250 source, start_frame, frames, this,
251 0, 1.0f / kint32min, 1.0f / kint32max);
256 break; 252 break;
257 default: 253 default:
258 NOTREACHED() << "Unsupported bytes per sample encountered."; 254 NOTREACHED() << "Unsupported bytes per sample encountered.";
259 ZeroFramesPartial(start_frame, frames); 255 ZeroFramesPartial(start_frame, frames);
260 return; 256 return;
261 } 257 }
262 258
263 // Don't clear remaining frames if this is a partial deinterleave. 259 // Don't clear remaining frames if this is a partial deinterleave.
264 if (!start_frame) { 260 if (!start_frame) {
265 // Zero any remaining frames. 261 // Zero any remaining frames.
(...skipping 10 matching lines...) Expand all
276 void* dest) const { 272 void* dest) const {
277 ToInterleavedPartial(0, frames, bytes_per_sample, dest); 273 ToInterleavedPartial(0, frames, bytes_per_sample, dest);
278 } 274 }
279 275
280 // TODO(dalecurtis): See if intrinsic optimizations help any here. 276 // TODO(dalecurtis): See if intrinsic optimizations help any here.
281 void AudioBus::ToInterleavedPartial(int start_frame, int frames, 277 void AudioBus::ToInterleavedPartial(int start_frame, int frames,
282 int bytes_per_sample, void* dest) const { 278 int bytes_per_sample, void* dest) const {
283 CheckOverflow(start_frame, frames, frames_); 279 CheckOverflow(start_frame, frames, frames_);
284 switch (bytes_per_sample) { 280 switch (bytes_per_sample) {
285 case 1: 281 case 1:
286 ToInterleavedInternal<uint8, int16>(this, start_frame, frames, dest); 282 ToInterleavedInternal<uint8, int16>(
283 this, start_frame, frames, dest,
284 kUint8Bias, kUint8Min, kUint8Max);
287 break; 285 break;
288 case 2: 286 case 2:
289 ToInterleavedInternal<int16, int32>(this, start_frame, frames, dest); 287 ToInterleavedInternal<int16, int32>(
288 this, start_frame, frames, dest, 0, kint16min, kint16max);
290 break; 289 break;
291 case 4: 290 case 4:
292 ToInterleavedInternal<int32, int64>(this, start_frame, frames, dest); 291 ToInterleavedInternal<int32, int64>(
292 this, start_frame, frames, dest, 0, kint32min, kint32max);
293 break; 293 break;
294 default: 294 default:
295 NOTREACHED() << "Unsupported bytes per sample encountered."; 295 NOTREACHED() << "Unsupported bytes per sample encountered.";
296 memset(dest, 0, frames * bytes_per_sample); 296 memset(dest, 0, frames * bytes_per_sample);
297 return; 297 return;
298 } 298 }
299 } 299 }
300 300
301 void AudioBus::CopyTo(AudioBus* dest) const { 301 void AudioBus::CopyTo(AudioBus* dest) const {
302 CHECK_EQ(channels(), dest->channels()); 302 CHECK_EQ(channels(), dest->channels());
303 CHECK_EQ(frames(), dest->frames()); 303 CHECK_EQ(frames(), dest->frames());
304 304
305 // Since we don't know if the other AudioBus is wrapped or not (and we don't 305 // Since we don't know if the other AudioBus is wrapped or not (and we don't
306 // want to care), just copy using the public channel() accessors. 306 // want to care), just copy using the public channel() accessors.
307 for (int i = 0; i < channels(); ++i) 307 for (int i = 0; i < channels(); ++i)
308 memcpy(dest->channel(i), channel(i), sizeof(*channel(i)) * frames()); 308 memcpy(dest->channel(i), channel(i), sizeof(*channel(i)) * frames());
309 } 309 }
310 310
311 void AudioBus::Scale(float volume) { 311 void AudioBus::Scale(float volume) {
312 if (volume > 0 && volume != 1) { 312 if (volume > 0 && volume != 1) {
313 for (int i = 0; i < channels(); ++i) 313 for (int i = 0; i < channels(); ++i)
314 vector_math::FMUL(channel(i), volume, frames(), channel(i)); 314 vector_math::FMUL(channel(i), volume, frames(), channel(i));
315 } else if (volume == 0) { 315 } else if (volume == 0) {
316 Zero(); 316 Zero();
317 } 317 }
318 } 318 }
319 319
320 } // namespace media 320 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | media/base/audio_bus_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698