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

Side by Side Diff: media/audio/audio_util.cc

Issue 9641026: Add software audio mixing to the audio utils. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 9 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 | « media/audio/audio_util.h ('k') | media/audio/audio_util_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 // Software adjust volume of samples, allows each audio stream its own 5 // Software adjust volume of samples, allows each audio stream its own
6 // volume without impacting master volume for chrome and other applications. 6 // volume without impacting master volume for chrome and other applications.
7 7
8 // Implemented as templates to allow 8, 16 and 32 bit implementations. 8 // Implemented as templates to allow 8, 16 and 32 bit implementations.
9 // 8 bit is unsigned and biased by 128. 9 // 8 bit is unsigned and biased by 128.
10 10
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 buf_out[i] = static_cast<Format>(ScaleChannel<Fixed>(buf_out[i] - bias, 50 buf_out[i] = static_cast<Format>(ScaleChannel<Fixed>(buf_out[i] - bias,
51 fixed_volume) + bias); 51 fixed_volume) + bias);
52 } 52 }
53 } 53 }
54 54
55 static const int kChannel_L = 0; 55 static const int kChannel_L = 0;
56 static const int kChannel_R = 1; 56 static const int kChannel_R = 1;
57 static const int kChannel_C = 2; 57 static const int kChannel_C = 2;
58 58
59 template<class Fixed, int min_value, int max_value> 59 template<class Fixed, int min_value, int max_value>
60 static int AddChannel(int val, int adder) { 60 static int AddSaturated(int val, int adder) {
61 Fixed sum = static_cast<Fixed>(val) + static_cast<Fixed>(adder); 61 Fixed sum = static_cast<Fixed>(val) + static_cast<Fixed>(adder);
62 if (sum > max_value) 62 if (sum > max_value)
63 return max_value; 63 return max_value;
64 if (sum < min_value) 64 if (sum < min_value)
65 return min_value; 65 return min_value;
66 return static_cast<int>(sum); 66 return static_cast<int>(sum);
67 } 67 }
68 68
69 // FoldChannels() downmixes multichannel (ie 5.1 Surround Sound) to Stereo. 69 // FoldChannels() downmixes multichannel (ie 5.1 Surround Sound) to Stereo.
70 // Left and Right channels are preserved asis, and Center channel is 70 // Left and Right channels are preserved asis, and Center channel is
(...skipping 15 matching lines...) Expand all
86 for (int i = 0; i < sample_count; ++i) { 86 for (int i = 0; i < sample_count; ++i) {
87 int center = static_cast<int>(buf_in[kChannel_C] - bias); 87 int center = static_cast<int>(buf_in[kChannel_C] - bias);
88 int left = static_cast<int>(buf_in[kChannel_L] - bias); 88 int left = static_cast<int>(buf_in[kChannel_L] - bias);
89 int right = static_cast<int>(buf_in[kChannel_R] - bias); 89 int right = static_cast<int>(buf_in[kChannel_R] - bias);
90 90
91 center = ScaleChannel<Fixed>(center, center_volume); 91 center = ScaleChannel<Fixed>(center, center_volume);
92 left = ScaleChannel<Fixed>(left, fixed_volume); 92 left = ScaleChannel<Fixed>(left, fixed_volume);
93 right = ScaleChannel<Fixed>(right, fixed_volume); 93 right = ScaleChannel<Fixed>(right, fixed_volume);
94 94
95 buf_out[0] = static_cast<Format>( 95 buf_out[0] = static_cast<Format>(
96 AddChannel<Fixed, min_value, max_value>(left, center) + bias); 96 AddSaturated<Fixed, min_value, max_value>(left, center) + bias);
97 buf_out[1] = static_cast<Format>( 97 buf_out[1] = static_cast<Format>(
98 AddChannel<Fixed, min_value, max_value>(right, center) + bias); 98 AddSaturated<Fixed, min_value, max_value>(right, center) + bias);
99 99
100 buf_out += 2; 100 buf_out += 2;
101 buf_in += channels; 101 buf_in += channels;
102 } 102 }
103 } 103 }
104 104
105 // AdjustVolume() does an in place audio sample change. 105 // AdjustVolume() does an in place audio sample change.
106 bool AdjustVolume(void* buf, 106 bool AdjustVolume(void* buf,
107 size_t buflen, 107 size_t buflen,
108 int channels, 108 int channels,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 if (sample < -32768.0) 234 if (sample < -32768.0)
235 sample = -32768.0; 235 sample = -32768.0;
236 else if (sample > 32767.0) 236 else if (sample > 32767.0)
237 sample = 32767.0; 237 sample = 32767.0;
238 238
239 destination[j * channels + i] = static_cast<int16>(sample); 239 destination[j * channels + i] = static_cast<int16>(sample);
240 } 240 }
241 } 241 }
242 } 242 }
243 243
244 // TODO(enal): use template specialization and size-specific intrinsics.
245 // Call is on the time-critical path, and by using SSE/AVX
246 // instructions we can speed things up by ~4-8x, more for the case
247 // when we have to adjust volume as well.
248 template<class Format, class Fixed, int min_value, int max_value, int bias>
249 static void MixStreams(Format* dst, Format* src, int count, float volume) {
vrk (LEFT CHROMIUM) 2012/03/20 00:27:54 Return early for muted src? if (volume == 0.0f)
250 if (volume == 1.0f) {
vrk (LEFT CHROMIUM) 2012/03/20 00:27:54 nit: It's cleaner/more concise if you push the if
251 // Most common case -- no need to adjust volume.
252 for (int i = 0; i < count; ++i) {
253 Fixed value = AddSaturated<Fixed, min_value, max_value>(dst[i] - bias,
254 src[i] - bias);
255 dst[i] = static_cast<Format>(value + bias);
256 }
257 } else {
258 // General case -- have to adjust volume before mixing.
259 const int fixed_volume = static_cast<int>(volume * 65536);
260 for (int i = 0; i < count; ++i) {
261 Fixed adjusted_src = ScaleChannel<Fixed>(src[i] - bias, fixed_volume);
262 Fixed value = AddSaturated<Fixed, min_value, max_value>(dst[i] - bias,
263 adjusted_src);
264 dst[i] = static_cast<Format>(value + bias);
265 }
266 }
267 }
268
269 void MixStreams(void* dst,
270 void* src,
271 size_t buflen,
272 int bytes_per_sample,
273 float volume) {
274 DCHECK(dst);
275 DCHECK(src);
276 DCHECK(volume >= 0.0f && volume <= 1.0f);
vrk (LEFT CHROMIUM) 2012/03/20 00:27:54 nit: two separate DCHECKs, DCHECK_GE(volume, 0.0f)
277 switch (bytes_per_sample) {
278 case 1:
279 MixStreams<uint8, int32, -128, 127, 128>(static_cast<uint8*>(dst),
280 static_cast<uint8*>(src),
281 buflen,
282 volume);
283 break;
284 case 2:
285 DCHECK_EQ(0u, buflen % 2);
286 MixStreams<int16, int32, -32768, 32767, 0>(static_cast<int16*>(dst),
287 static_cast<int16*>(src),
288 buflen / 2,
289 volume);
290 break;
291 case 4:
292 DCHECK_EQ(0u, buflen % 4);
293 MixStreams<int32, int64, 0x80000000, 0x7fffffff, 0>(
294 static_cast<int32*>(dst),
295 static_cast<int32*>(src),
296 buflen / 4,
297 volume);
298 break;
299 default:
300 NOTREACHED() << "Illegal bytes per sample";
301 break;
302 }
303 }
304
244 double GetAudioHardwareSampleRate() { 305 double GetAudioHardwareSampleRate() {
245 #if defined(OS_MACOSX) 306 #if defined(OS_MACOSX)
246 // Hardware sample-rate on the Mac can be configured, so we must query. 307 // Hardware sample-rate on the Mac can be configured, so we must query.
247 return AUAudioOutputStream::HardwareSampleRate(); 308 return AUAudioOutputStream::HardwareSampleRate();
248 #elif defined(OS_WIN) 309 #elif defined(OS_WIN)
249 if (!IsWASAPISupported()) { 310 if (!IsWASAPISupported()) {
250 // Fall back to Windows Wave implementation on Windows XP or lower 311 // Fall back to Windows Wave implementation on Windows XP or lower
251 // and use 48kHz as default input sample rate. 312 // and use 48kHz as default input sample rate.
252 return 48000.0; 313 return 48000.0;
253 } 314 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 442
382 bool IsWASAPISupported() { 443 bool IsWASAPISupported() {
383 // Note: that function correctly returns that Windows Server 2003 does not 444 // Note: that function correctly returns that Windows Server 2003 does not
384 // support WASAPI. 445 // support WASAPI.
385 return base::win::GetVersion() >= base::win::VERSION_VISTA; 446 return base::win::GetVersion() >= base::win::VERSION_VISTA;
386 } 447 }
387 448
388 #endif 449 #endif
389 450
390 } // namespace media 451 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_util.h ('k') | media/audio/audio_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698