diff options
author | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-20 08:39:12 +0000 |
---|---|---|
committer | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-20 08:39:12 +0000 |
commit | 873b0423a17876ebfe348b906fc2222cd0005ad0 (patch) | |
tree | ea14ac3ef117998426b16a2a6effd33ecfc7334e /media/audio/linux | |
parent | cb0d6fbebbad064a6fdc51e8c22ed24aff623878 (diff) | |
download | chromium_src-873b0423a17876ebfe348b906fc2222cd0005ad0.zip chromium_src-873b0423a17876ebfe348b906fc2222cd0005ad0.tar.gz chromium_src-873b0423a17876ebfe348b906fc2222cd0005ad0.tar.bz2 |
Use ChannelMixer where applicable. Remove FoldChannels.
- Adds ChannelMixer to AudioOutputResampler.
- Switches all users of FoldChannels over to ChannelMixer.
- Removes channel mixing from WASAPIAudioOutputStream.
BUG=138762
TEST=unit tests, manual playback on all platforms.
Review URL: https://chromiumcodereview.appspot.com/11188019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163163 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/linux')
-rw-r--r-- | media/audio/linux/alsa_output.cc | 54 | ||||
-rw-r--r-- | media/audio/linux/alsa_output.h | 9 | ||||
-rw-r--r-- | media/audio/linux/alsa_output_unittest.cc | 5 |
3 files changed, 36 insertions, 32 deletions
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc index c51a27c..96be896 100644 --- a/media/audio/linux/alsa_output.cc +++ b/media/audio/linux/alsa_output.cc @@ -46,6 +46,7 @@ #include "media/audio/linux/alsa_util.h" #include "media/audio/linux/alsa_wrapper.h" #include "media/audio/linux/audio_manager_linux.h" +#include "media/base/channel_mixer.h" #include "media/base/data_buffer.h" #include "media/base/seekable_buffer.h" @@ -155,10 +156,10 @@ AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name, : requested_device_name_(device_name), pcm_format_(alsa_util::BitsToFormat(params.bits_per_sample())), channels_(params.channels()), + channel_layout_(params.channel_layout()), sample_rate_(params.sample_rate()), bytes_per_sample_(params.bits_per_sample() / 8), bytes_per_frame_(channels_ * params.bits_per_sample() / 8), - should_downmix_(false), packet_size_(params.GetBytesPerBuffer()), micros_per_packet_(FramesToMicros( params.frames_per_buffer(), sample_rate_)), @@ -242,8 +243,8 @@ bool AlsaPcmOutputStream::Open() { TransitionTo(kInError); return false; } else { - bytes_per_output_frame_ = should_downmix_ ? 2 * bytes_per_sample_ : - bytes_per_frame_; + bytes_per_output_frame_ = channel_mixer_ ? + mixed_audio_bus_->channels() * bytes_per_sample_ : bytes_per_frame_; uint32 output_packet_size = frames_per_packet_ * bytes_per_output_frame_; buffer_.reset(new media::SeekableBuffer(0, output_packet_size)); @@ -382,35 +383,31 @@ void AlsaPcmOutputStream::BufferPacket(bool* source_exhausted) { audio_bus_.get(), AudioBuffersState(buffer_delay, hardware_delay)); size_t packet_size = frames_filled * bytes_per_frame_; DCHECK_LE(packet_size, packet_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_->ToInterleaved( - frames_filled, bytes_per_sample_, packet->GetWritableData()); // Reset the |last_fill_time| to avoid back to back RunDataCallback(). last_fill_time_ = base::Time::Now(); // TODO(dalecurtis): Channel downmixing, upmixing, should be done in mixer; // volume adjust should use SSE optimized vector_fmul() prior to interleave. - if (should_downmix_) { - if (media::FoldChannels(packet->GetWritableData(), - packet_size, - channels_, - bytes_per_sample_, - volume_)) { - // Adjust packet size for downmix. - packet_size = packet_size / bytes_per_frame_ * bytes_per_output_frame_; - } else { - LOG(ERROR) << "Folding failed"; - } - } else { - media::AdjustVolume(packet->GetWritableData(), - packet_size, - channels_, - bytes_per_sample_, - volume_); + AudioBus* output_bus = audio_bus_.get(); + if (channel_mixer_) { + output_bus = mixed_audio_bus_.get(); + channel_mixer_->Transform(audio_bus_.get(), output_bus); + // Adjust packet size for downmix. + packet_size = packet_size / bytes_per_frame_ * bytes_per_output_frame_; } + // 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->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. @@ -708,12 +705,13 @@ snd_pcm_t* AlsaPcmOutputStream::AutoSelectDevice(unsigned int latency) { // output to have the correct ordering according to Lennart. For the channel // formats that we know how to downmix from (3 channel to 8 channel), setup // downmixing. - // - // TODO(ajwong): We need a SupportsFolding() function. uint32 default_channels = channels_; - if (default_channels > 2 && default_channels <= 8) { - should_downmix_ = true; + if (default_channels > 2) { + channel_mixer_.reset(new ChannelMixer( + channel_layout_, CHANNEL_LAYOUT_STEREO)); default_channels = 2; + mixed_audio_bus_ = AudioBus::Create( + default_channels, audio_bus_->frames()); } // Step 3. diff --git a/media/audio/linux/alsa_output.h b/media/audio/linux/alsa_output.h index 736015e..ffb29f4 100644 --- a/media/audio/linux/alsa_output.h +++ b/media/audio/linux/alsa_output.h @@ -39,6 +39,7 @@ namespace media { class AlsaWrapper; class AudioManagerLinux; +class ChannelMixer; class SeekableBuffer; class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream { @@ -131,7 +132,7 @@ class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream { snd_pcm_sframes_t GetCurrentDelay(); // Attempts to find the best matching linux audio device for the given number - // of channels. This function will set |device_name_| and |should_downmix_|. + // of channels. This function will set |device_name_| and |channel_mixer_|. snd_pcm_t* AutoSelectDevice(uint32 latency); // Functions to safeguard state transitions. All changes to the object state @@ -164,13 +165,13 @@ class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream { const std::string requested_device_name_; const snd_pcm_format_t pcm_format_; const uint32 channels_; + const ChannelLayout channel_layout_; const uint32 sample_rate_; const uint32 bytes_per_sample_; const uint32 bytes_per_frame_; // Device configuration data. Populated after OpenTask() completes. std::string device_name_; - bool should_downmix_; uint32 packet_size_; uint32 micros_per_packet_; uint32 latency_micros_; @@ -214,6 +215,10 @@ class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream { // Container for retrieving data from AudioSourceCallback::OnMoreData(). scoped_ptr<AudioBus> audio_bus_; + // Channel mixer and temporary bus for the final mixed channel data. + scoped_ptr<ChannelMixer> channel_mixer_; + scoped_ptr<AudioBus> mixed_audio_bus_; + DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStream); }; diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc index 69bcf4f..9d6185c 100644 --- a/media/audio/linux/alsa_output_unittest.cc +++ b/media/audio/linux/alsa_output_unittest.cc @@ -734,7 +734,8 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) { AlsaPcmOutputStream* test_stream = CreateStream(kExpectedLayouts[i]); EXPECT_TRUE(test_stream->AutoSelectDevice(i)); - EXPECT_EQ(kExpectedDownmix[i], test_stream->should_downmix_); + EXPECT_EQ(kExpectedDownmix[i], + static_cast<bool>(test_stream->channel_mixer_)); Mock::VerifyAndClearExpectations(&mock_alsa_wrapper_); Mock::VerifyAndClearExpectations(mock_manager_.get()); @@ -804,7 +805,7 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) { AlsaPcmOutputStream* test_stream = CreateStream(CHANNEL_LAYOUT_5_0); EXPECT_TRUE(test_stream->AutoSelectDevice(5)); - EXPECT_TRUE(test_stream->should_downmix_); + EXPECT_TRUE(test_stream->channel_mixer_); test_stream->Close(); } |