summaryrefslogtreecommitdiffstats
path: root/media/audio/linux
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-20 08:39:12 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-20 08:39:12 +0000
commit873b0423a17876ebfe348b906fc2222cd0005ad0 (patch)
treeea14ac3ef117998426b16a2a6effd33ecfc7334e /media/audio/linux
parentcb0d6fbebbad064a6fdc51e8c22ed24aff623878 (diff)
downloadchromium_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.cc54
-rw-r--r--media/audio/linux/alsa_output.h9
-rw-r--r--media/audio/linux/alsa_output_unittest.cc5
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();
}