diff options
author | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-08 21:30:37 +0000 |
---|---|---|
committer | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-08 21:30:37 +0000 |
commit | 7ed91e9093602872c62eba397fc1be8741089157 (patch) | |
tree | 6c4c2c6878ed51ca2e90586f11ea3887835c5e8c /media/audio | |
parent | 13bfbc41308953ebea4952ff504037a261cfdd3c (diff) | |
download | chromium_src-7ed91e9093602872c62eba397fc1be8741089157.zip chromium_src-7ed91e9093602872c62eba397fc1be8741089157.tar.gz chromium_src-7ed91e9093602872c62eba397fc1be8741089157.tar.bz2 |
Add vector_math::FMUL. Replace audio_util::AdjustVolume.
Removes the integer based volume adjustment code from the
melting pot that is audio_util in favor of an
AudioBus::AdjustVolume() method which works on float.
The driver behind the method is a new vector_math::FMUL
method which is SSE optimized. Benchmarks put it in line
with the vector_math::FMAC() method.
Benchmarking 200000 iterations:
FMUL_C took 1962.52ms.
FMUL_SSE (unaligned size) took 493.03ms; which is 3.98x faster than FMUL_C.
FMUL_SSE (aligned size) took 491.79ms; which is 3.99x faster than FMUL_C and 1.00x faster than FMUL_SSE (unaligned size).
BUG=120319, 171540, 226447
TEST=new media_unittests.
Review URL: https://chromiumcodereview.appspot.com/13726011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192905 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio')
-rw-r--r-- | media/audio/android/opensles_output.cc | 9 | ||||
-rw-r--r-- | media/audio/audio_util.cc | 71 | ||||
-rw-r--r-- | media/audio/audio_util.h | 30 | ||||
-rw-r--r-- | media/audio/audio_util_unittest.cc | 82 | ||||
-rw-r--r-- | media/audio/linux/alsa_output.cc | 8 | ||||
-rw-r--r-- | media/audio/mac/audio_auhal_mac.cc | 3 | ||||
-rw-r--r-- | media/audio/mac/audio_low_latency_output_mac.cc | 10 | ||||
-rw-r--r-- | media/audio/pulse/pulse_output.cc | 4 | ||||
-rw-r--r-- | media/audio/pulse/pulse_unified.cc | 4 | ||||
-rw-r--r-- | media/audio/win/audio_low_latency_output_win.cc | 8 | ||||
-rw-r--r-- | media/audio/win/audio_unified_win.cc | 9 | ||||
-rw-r--r-- | media/audio/win/waveout_output_win.cc | 6 |
12 files changed, 11 insertions, 233 deletions
diff --git a/media/audio/android/opensles_output.cc b/media/audio/android/opensles_output.cc index f98baaf..36a1408 100644 --- a/media/audio/android/opensles_output.cc +++ b/media/audio/android/opensles_output.cc @@ -5,7 +5,6 @@ #include "media/audio/android/opensles_output.h" #include "base/logging.h" -#include "media/audio/audio_util.h" #include "media/audio/android/audio_manager_android.h" namespace media { @@ -267,16 +266,10 @@ void OpenSLESOutputStream::FillBufferQueue() { DCHECK_LE(static_cast<size_t>(num_filled_bytes), buffer_size_bytes_); // Note: If this ever changes to output raw float the data must be clipped and // sanitized since it may come from an untrusted source such as NaCl. + audio_bus_->Scale(volume_); audio_bus_->ToInterleaved( frames_filled, format_.bitsPerSample / 8, audio_data_[active_queue_]); - // Perform in-place, software-volume adjustments. - media::AdjustVolume(audio_data_[active_queue_], - num_filled_bytes, - format_.numChannels, - format_.bitsPerSample / 8, - volume_); - // Enqueue the buffer for playback. SLresult err = (*simple_buffer_queue_)->Enqueue( simple_buffer_queue_, diff --git a/media/audio/audio_util.cc b/media/audio/audio_util.cc index 351937e..8758fdc 100644 --- a/media/audio/audio_util.cc +++ b/media/audio/audio_util.cc @@ -14,86 +14,17 @@ #include "media/audio/audio_util.h" -#include <algorithm> -#include <limits> - -#include "base/basictypes.h" #include "base/command_line.h" -#include "base/logging.h" #include "base/string_number_conversions.h" #include "base/time.h" -#include "media/audio/audio_parameters.h" -#include "media/base/audio_bus.h" #include "media/base/media_switches.h" -#if defined(OS_MACOSX) -#include "media/audio/mac/audio_low_latency_input_mac.h" -#include "media/audio/mac/audio_low_latency_output_mac.h" -#elif defined(OS_WIN) +#if defined(OS_WIN) #include "base/win/windows_version.h" -#include "media/audio/audio_manager_base.h" -#include "media/audio/win/audio_low_latency_input_win.h" -#include "media/audio/win/audio_low_latency_output_win.h" -#include "media/audio/win/core_audio_util_win.h" -#include "media/base/limits.h" #endif namespace media { -// TODO(fbarchard): Convert to intrinsics for better efficiency. -template<class Fixed> -static int ScaleChannel(int channel, int volume) { - return static_cast<int>((static_cast<Fixed>(channel) * volume) >> 16); -} - -template<class Format, class Fixed, int bias> -static void AdjustVolume(Format* buf_out, - int sample_count, - int fixed_volume) { - for (int i = 0; i < sample_count; ++i) { - buf_out[i] = static_cast<Format>(ScaleChannel<Fixed>(buf_out[i] - bias, - fixed_volume) + bias); - } -} - -// AdjustVolume() does an in place audio sample change. -bool AdjustVolume(void* buf, - size_t buflen, - int channels, - int bytes_per_sample, - float volume) { - DCHECK(buf); - if (volume < 0.0f || volume > 1.0f) - return false; - if (volume == 1.0f) { - return true; - } else if (volume == 0.0f) { - memset(buf, 0, buflen); - return true; - } - if (channels > 0 && channels <= 8 && bytes_per_sample > 0) { - int sample_count = buflen / bytes_per_sample; - const int fixed_volume = static_cast<int>(volume * 65536); - if (bytes_per_sample == 1) { - AdjustVolume<uint8, int32, 128>(reinterpret_cast<uint8*>(buf), - sample_count, - fixed_volume); - return true; - } else if (bytes_per_sample == 2) { - AdjustVolume<int16, int32, 0>(reinterpret_cast<int16*>(buf), - sample_count, - fixed_volume); - return true; - } else if (bytes_per_sample == 4) { - AdjustVolume<int32, int64, 0>(reinterpret_cast<int32*>(buf), - sample_count, - fixed_volume); - return true; - } - } - return false; -} - // Returns user buffer size as specified on the command line or 0 if no buffer // size has been specified. int GetUserBufferSize() { diff --git a/media/audio/audio_util.h b/media/audio/audio_util.h index 9fdbde8..a11c327 100644 --- a/media/audio/audio_util.h +++ b/media/audio/audio_util.h @@ -5,39 +5,11 @@ #ifndef MEDIA_AUDIO_AUDIO_UTIL_H_ #define MEDIA_AUDIO_AUDIO_UTIL_H_ -#include <string> - #include "base/basictypes.h" -#include "media/base/channel_layout.h" +#include "build/build_config.h" #include "media/base/media_export.h" -namespace base { -class SharedMemory; -} - namespace media { -class AudioBus; - -// For all audio functions 3 audio formats are supported: -// 8 bits unsigned 0 to 255. -// 16 bit signed (little endian). -// 32 bit signed (little endian) - -// AdjustVolume() does a software volume adjustment of a sample buffer. -// The samples are multiplied by the volume, which should range from -// 0.0 (mute) to 1.0 (full volume). -// Using software allows each audio and video to have its own volume without -// affecting the master volume. -// In the future the function may be used to adjust the sample format to -// simplify hardware requirements and to support a wider variety of input -// formats. -// The buffer is modified in-place to avoid memory management, as this -// function may be called in performance critical code. -MEDIA_EXPORT bool AdjustVolume(void* buf, - size_t buflen, - int channels, - int bytes_per_sample, - float volume); // Returns user buffer size as specified on the command line or 0 if no buffer // size has been specified. diff --git a/media/audio/audio_util_unittest.cc b/media/audio/audio_util_unittest.cc deleted file mode 100644 index 679243c..0000000 --- a/media/audio/audio_util_unittest.cc +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/basictypes.h" -#include "media/audio/audio_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -// Number of samples in each audio array. -static const size_t kNumberOfSamples = 4; - -namespace media { - -TEST(AudioUtilTest, AdjustVolume_u8) { - // Test AdjustVolume() on 8 bit samples. - uint8 samples_u8[kNumberOfSamples] = { 4, 0x40, 0x80, 0xff }; - uint8 expected_u8[kNumberOfSamples] = { (4 - 128) / 2 + 128, - (0x40 - 128) / 2 + 128, - (0x80 - 128) / 2 + 128, - (0xff - 128) / 2 + 128 }; - bool result_u8 = media::AdjustVolume(samples_u8, sizeof(samples_u8), - 1, // channels. - sizeof(samples_u8[0]), - 0.5f); - EXPECT_TRUE(result_u8); - int expected_test = memcmp(samples_u8, expected_u8, sizeof(expected_u8)); - EXPECT_EQ(0, expected_test); -} - -TEST(AudioUtilTest, AdjustVolume_s16) { - // Test AdjustVolume() on 16 bit samples. - int16 samples_s16[kNumberOfSamples] = { -4, 0x40, -32768, 123 }; - int16 expected_s16[kNumberOfSamples] = { -1, 0x10, -8192, 30 }; - bool result_s16 = media::AdjustVolume(samples_s16, sizeof(samples_s16), - 2, // channels. - sizeof(samples_s16[0]), - 0.25f); - EXPECT_TRUE(result_s16); - int expected_test = memcmp(samples_s16, expected_s16, sizeof(expected_s16)); - EXPECT_EQ(0, expected_test); -} - -TEST(AudioUtilTest, AdjustVolume_s16_zero) { - // Test AdjustVolume() on 16 bit samples. - int16 samples_s16[kNumberOfSamples] = { -4, 0x40, -32768, 123 }; - int16 expected_s16[kNumberOfSamples] = { 0, 0, 0, 0 }; - bool result_s16 = media::AdjustVolume(samples_s16, sizeof(samples_s16), - 2, // channels. - sizeof(samples_s16[0]), - 0.0f); - EXPECT_TRUE(result_s16); - int expected_test = memcmp(samples_s16, expected_s16, sizeof(expected_s16)); - EXPECT_EQ(0, expected_test); -} - -TEST(AudioUtilTest, AdjustVolume_s16_one) { - // Test AdjustVolume() on 16 bit samples. - int16 samples_s16[kNumberOfSamples] = { -4, 0x40, -32768, 123 }; - int16 expected_s16[kNumberOfSamples] = { -4, 0x40, -32768, 123 }; - bool result_s16 = media::AdjustVolume(samples_s16, sizeof(samples_s16), - 2, // channels. - sizeof(samples_s16[0]), - 1.0f); - EXPECT_TRUE(result_s16); - int expected_test = memcmp(samples_s16, expected_s16, sizeof(expected_s16)); - EXPECT_EQ(0, expected_test); -} - -TEST(AudioUtilTest, AdjustVolume_s32) { - // Test AdjustVolume() on 32 bit samples. - int32 samples_s32[kNumberOfSamples] = { -4, 0x40, -32768, 123 }; - int32 expected_s32[kNumberOfSamples] = { -1, 0x10, -8192, 30 }; - bool result_s32 = media::AdjustVolume(samples_s32, sizeof(samples_s32), - 4, // channels. - sizeof(samples_s32[0]), - 0.25f); - EXPECT_TRUE(result_s32); - int expected_test = memcmp(samples_s32, expected_s32, sizeof(expected_s32)); - EXPECT_EQ(0, expected_test); -} - -} // namespace media diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc index ea3d1b6..4615d01 100644 --- a/media/audio/linux/alsa_output.cc +++ b/media/audio/linux/alsa_output.cc @@ -42,7 +42,6 @@ #include "base/message_loop.h" #include "base/stl_util.h" #include "base/time.h" -#include "media/audio/audio_util.h" #include "media/audio/linux/alsa_util.h" #include "media/audio/linux/alsa_wrapper.h" #include "media/audio/linux/audio_manager_linux.h" @@ -379,15 +378,10 @@ void AlsaPcmOutputStream::BufferPacket(bool* source_exhausted) { // Note: If this ever changes to output raw float the data must be clipped // and sanitized since it may come from an untrusted source such as NaCl. + output_bus->Scale(volume_); output_bus->ToInterleaved( frames_filled, bytes_per_sample_, packet->GetWritableData()); - media::AdjustVolume(packet->GetWritableData(), - packet_size, - output_bus->channels(), - bytes_per_sample_, - volume_); - if (packet_size > 0) { packet->SetDataSize(packet_size); // Add the packet to the buffer. diff --git a/media/audio/mac/audio_auhal_mac.cc b/media/audio/mac/audio_auhal_mac.cc index 20df6f5..b2a8828 100644 --- a/media/audio/mac/audio_auhal_mac.cc +++ b/media/audio/mac/audio_auhal_mac.cc @@ -178,8 +178,6 @@ void AUHALStream::Stop() { void AUHALStream::SetVolume(double volume) { volume_ = static_cast<float>(volume); - - // TODO(crogers): set volume property } void AUHALStream::GetVolume(double* volume) { @@ -251,6 +249,7 @@ OSStatus AUHALStream::Render( input_bus_.get(), output_bus_.get(), AudioBuffersState(0, hardware_pending_bytes)); + output_bus_->Scale(volume_); } return noErr; diff --git a/media/audio/mac/audio_low_latency_output_mac.cc b/media/audio/mac/audio_low_latency_output_mac.cc index 4b82bef..592a6a1 100644 --- a/media/audio/mac/audio_low_latency_output_mac.cc +++ b/media/audio/mac/audio_low_latency_output_mac.cc @@ -10,7 +10,6 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/mac/mac_logging.h" -#include "media/audio/audio_util.h" #include "media/audio/mac/audio_manager_mac.h" #include "media/base/media_switches.h" @@ -284,16 +283,9 @@ OSStatus AUAudioOutputStream::Render(UInt32 number_of_frames, // Note: If this ever changes to output raw float the data must be clipped and // sanitized since it may come from an untrusted source such as NaCl. + audio_bus_->Scale(volume_); audio_bus_->ToInterleaved( frames_filled, format_.mBitsPerChannel / 8, audio_data); - uint32 filled = frames_filled * format_.mBytesPerFrame; - - // Perform in-place, software-volume adjustments. - media::AdjustVolume(audio_data, - filled, - audio_bus_->channels(), - format_.mBitsPerChannel / 8, - volume_); return noErr; } diff --git a/media/audio/pulse/pulse_output.cc b/media/audio/pulse/pulse_output.cc index eccf463..1734954 100644 --- a/media/audio/pulse/pulse_output.cc +++ b/media/audio/pulse/pulse_output.cc @@ -9,7 +9,6 @@ #include "base/message_loop.h" #include "media/audio/audio_manager_base.h" #include "media/audio/audio_parameters.h" -#include "media/audio/audio_util.h" #include "media/audio/pulse/pulse_util.h" namespace media { @@ -143,10 +142,9 @@ void PulseAudioOutputStream::FulfillWriteRequest(size_t requested_bytes) { // Note: If this ever changes to output raw float the data must be clipped // and sanitized since it may come from an untrusted source such as NaCl. + audio_bus_->Scale(volume_); audio_bus_->ToInterleaved( audio_bus_->frames(), params_.bits_per_sample() / 8, buffer); - media::AdjustVolume(buffer, bytes_to_fill, params_.channels(), - params_.bits_per_sample() / 8, volume_); if (pa_stream_write(pa_stream_, buffer, bytes_to_fill, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { diff --git a/media/audio/pulse/pulse_unified.cc b/media/audio/pulse/pulse_unified.cc index 791a3a8..87bb6ae 100644 --- a/media/audio/pulse/pulse_unified.cc +++ b/media/audio/pulse/pulse_unified.cc @@ -8,7 +8,6 @@ #include "base/time.h" #include "media/audio/audio_manager_base.h" #include "media/audio/audio_parameters.h" -#include "media/audio/audio_util.h" #include "media/audio/pulse/pulse_util.h" #include "media/base/seekable_buffer.h" @@ -175,10 +174,9 @@ void PulseAudioUnifiedStream::WriteData(size_t requested_bytes) { // Note: If this ever changes to output raw float the data must be clipped // and sanitized since it may come from an untrusted source such as NaCl. + output_bus_->Scale(volume_); output_bus_->ToInterleaved( output_bus_->frames(), params_.bits_per_sample() / 8, buffer); - media::AdjustVolume(buffer, requested_bytes, params_.channels(), - params_.bits_per_sample() / 8, volume_); if (pa_stream_write(output_stream_, buffer, requested_bytes, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { diff --git a/media/audio/win/audio_low_latency_output_win.cc b/media/audio/win/audio_low_latency_output_win.cc index b5a4c47..04b5dd2 100644 --- a/media/audio/win/audio_low_latency_output_win.cc +++ b/media/audio/win/audio_low_latency_output_win.cc @@ -13,7 +13,6 @@ #include "base/metrics/histogram.h" #include "base/utf_string_conversions.h" #include "base/win/scoped_propvariant.h" -#include "media/audio/audio_util.h" #include "media/audio/win/audio_manager_win.h" #include "media/audio/win/avrt_wrapper_win.h" #include "media/audio/win/core_audio_util_win.h" @@ -581,15 +580,10 @@ void WASAPIAudioOutputStream::RenderAudioFromSource( // clipped and sanitized since it may come from an untrusted // source such as NaCl. const int bytes_per_sample = format_.Format.wBitsPerSample >> 3; + audio_bus_->Scale(volume_); audio_bus_->ToInterleaved( frames_filled, bytes_per_sample, audio_data); - // Perform in-place, software-volume adjustments. - media::AdjustVolume(audio_data, - num_filled_bytes, - audio_bus_->channels(), - bytes_per_sample, - volume_); // Release the buffer space acquired in the GetBuffer() call. // Render silence if we were not able to fill up the buffer totally. diff --git a/media/audio/win/audio_unified_win.cc b/media/audio/win/audio_unified_win.cc index e7877f5..59b98d0 100644 --- a/media/audio/win/audio_unified_win.cc +++ b/media/audio/win/audio_unified_win.cc @@ -9,7 +9,6 @@ #include "base/debug/trace_event.h" #include "base/time.h" #include "base/win/scoped_com_initializer.h" -#include "media/audio/audio_util.h" #include "media/audio/win/audio_manager_win.h" #include "media/audio/win/avrt_wrapper_win.h" #include "media/audio/win/core_audio_util_win.h" @@ -529,16 +528,10 @@ void WASAPIUnifiedStream::Run() { // Convert the audio bus content to interleaved integer data using // |audio_data| as destination. + render_bus_->Scale(volume_); render_bus_->ToInterleaved( packet_size_frames_, bytes_per_sample, audio_data); - // Perform in-place, software-volume adjustments. - media::AdjustVolume(audio_data, - frames_filled * format_.Format.nBlockAlign, - render_bus_->channels(), - bytes_per_sample, - volume_); - // Release the buffer space acquired in the GetBuffer() call. audio_render_client_->ReleaseBuffer(packet_size_frames_, 0); DLOG_IF(ERROR, FAILED(hr)) << "Failed to release render buffer"; diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc index f42d948..9b03c31 100644 --- a/media/audio/win/waveout_output_win.cc +++ b/media/audio/win/waveout_output_win.cc @@ -13,7 +13,6 @@ #include "base/debug/trace_event.h" #include "base/logging.h" #include "media/audio/audio_io.h" -#include "media/audio/audio_util.h" #include "media/audio/win/audio_manager_win.h" namespace media { @@ -360,14 +359,11 @@ void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) { if (used <= buffer_size_) { // Note: If this ever changes to output raw float the data must be clipped // and sanitized since it may come from an untrusted source such as NaCl. + audio_bus_->Scale(volume_); audio_bus_->ToInterleaved( frames_filled, format_.Format.wBitsPerSample / 8, buffer->lpData); buffer->dwBufferLength = used * format_.Format.nChannels / channels_; - media::AdjustVolume(buffer->lpData, used, - format_.Format.nChannels, - format_.Format.wBitsPerSample >> 3, - volume_); } else { HandleError(0); return; |