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

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
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 specialization and intrinsics.
vrk (LEFT CHROMIUM) 2012/03/12 18:40:24 What sort of specialization? Are intrinsics really
enal1 2012/03/12 21:20:53 Updated comment.
245 template<class Format, class Fixed, int min_value, int max_value, int bias>
246 static void MixStreams(Format* dst, Format* src, int count, float volume) {
247 if (volume == 1.0f) {
248 // Most common case -- no need to adjust volume.
249 for (int i = 0; i < count; ++i) {
250 Fixed value = AddSaturated<Fixed, min_value, max_value>(dst[i] - bias,
251 src[i] - bias);
252 dst[i] = static_cast<Format>(value + bias);
253 }
254 } else {
255 // General case -- have to adjust volume before mixing.
256 const int fixed_volume = static_cast<int>(volume * 65536);
vrk (LEFT CHROMIUM) 2012/03/12 18:40:24 why 65536/maxval of uint16?
enal1 2012/03/12 21:20:53 We are replacing FP multiplication by integer one.
vrk (LEFT CHROMIUM) 2012/03/20 00:27:53 OK... well, it's not code that you wrote, but it'd
257 for (int i = 0; i < count; ++i) {
258 Fixed adjusted_src = ScaleChannel<Fixed>(src[i] - bias, fixed_volume);
259 Fixed value = AddSaturated<Fixed, min_value, max_value>(dst[i] - bias,
260 adjusted_src);
261 dst[i] = static_cast<Format>(value + bias);
262 }
263 }
264 }
265
266 void MixStreams(void* dst,
267 void* src,
268 size_t buflen,
269 int bytes_per_sample,
270 float volume) {
271 DCHECK(dst);
272 DCHECK(src);
273 DCHECK(volume >= 0.0f && volume <= 1.0f);
274 switch (bytes_per_sample) {
275 case 1:
276 MixStreams<uint8, int32, -128, 127, 128>(static_cast<uint8*>(dst),
vrk (LEFT CHROMIUM) 2012/03/12 18:40:24 Why is the bias 128 here and 0 elsewhere?
enal1 2012/03/12 21:20:53 Because we have "unsigned char" for 8 bits and "si
enal1 2012/03/12 21:20:53 Because we have "unsigned char" for 8 bits and "si
277 static_cast<uint8*>(src),
278 buflen,
279 volume);
280 break;
281 case 2:
282 DCHECK_EQ(0u, buflen % 2);
283 MixStreams<int16, int32, -32768, 32767, 0>(static_cast<int16*>(dst),
284 static_cast<int16*>(src),
285 buflen / 2,
286 volume);
287 break;
288 case 4:
289 DCHECK_EQ(0u, buflen % 4);
290 MixStreams<int32, int64, 0x80000000, 0x7fffffff, 0>(
291 static_cast<int32*>(dst),
292 static_cast<int32*>(src),
293 buflen / 4,
294 volume);
295 break;
296 default:
297 NOTREACHED() << "Illegal bytes per sample";
298 break;
299 }
300 }
301
244 double GetAudioHardwareSampleRate() { 302 double GetAudioHardwareSampleRate() {
245 #if defined(OS_MACOSX) 303 #if defined(OS_MACOSX)
246 // Hardware sample-rate on the Mac can be configured, so we must query. 304 // Hardware sample-rate on the Mac can be configured, so we must query.
247 return AUAudioOutputStream::HardwareSampleRate(); 305 return AUAudioOutputStream::HardwareSampleRate();
248 #elif defined(OS_WIN) 306 #elif defined(OS_WIN)
249 if (!IsWASAPISupported()) { 307 if (!IsWASAPISupported()) {
250 // Fall back to Windows Wave implementation on Windows XP or lower 308 // Fall back to Windows Wave implementation on Windows XP or lower
251 // and use 48kHz as default input sample rate. 309 // and use 48kHz as default input sample rate.
252 return 48000.0; 310 return 48000.0;
253 } 311 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 439
382 bool IsWASAPISupported() { 440 bool IsWASAPISupported() {
383 // Note: that function correctly returns that Windows Server 2003 does not 441 // Note: that function correctly returns that Windows Server 2003 does not
384 // support WASAPI. 442 // support WASAPI.
385 return base::win::GetVersion() >= base::win::VERSION_VISTA; 443 return base::win::GetVersion() >= base::win::VERSION_VISTA;
386 } 444 }
387 445
388 #endif 446 #endif
389 447
390 } // namespace media 448 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698