summaryrefslogtreecommitdiffstats
path: root/media/audio
diff options
context:
space:
mode:
authorxians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-21 19:36:51 +0000
committerxians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-21 19:36:51 +0000
commit18359a3aa881f0ba88edae325e3cf883f28e82d6 (patch)
tree6e5dcc2d4e1b2ea46e40fc027b8f95aca6861e20 /media/audio
parentc2693b6468dec685495c6c01f631a75d67ce40de (diff)
downloadchromium_src-18359a3aa881f0ba88edae325e3cf883f28e82d6.zip
chromium_src-18359a3aa881f0ba88edae325e3cf883f28e82d6.tar.gz
chromium_src-18359a3aa881f0ba88edae325e3cf883f28e82d6.tar.bz2
Switch the input code to use AudioBlockFifo.
It saves two memcpy and quite some intermedia AudioBus code. Also, this CL corrects a mistake in https://codereview.chromium.org/389623002/ by using FromInterleavedPartial() instead of FromInterleaved(). BUG=393199 TEST=bots and webrtc loopback test: https://apprtc.appspot.com Review URL: https://codereview.chromium.org/396263004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284477 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio')
-rw-r--r--media/audio/mac/audio_low_latency_input_mac.cc53
-rw-r--r--media/audio/mac/audio_low_latency_input_mac.h14
-rw-r--r--media/audio/pulse/pulse_input.cc30
-rw-r--r--media/audio/pulse/pulse_input.h10
4 files changed, 34 insertions, 73 deletions
diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc
index f0f6629..f1dbdf7 100644
--- a/media/audio/mac/audio_low_latency_input_mac.cc
+++ b/media/audio/mac/audio_low_latency_input_mac.cc
@@ -11,11 +11,13 @@
#include "base/mac/mac_logging.h"
#include "media/audio/mac/audio_manager_mac.h"
#include "media/base/audio_bus.h"
-#include "media/base/audio_fifo.h"
#include "media/base/data_buffer.h"
namespace media {
+// Number of blocks of buffers used in the |fifo_|.
+const int kNumberOfBlocksBufferInFifo = 2;
+
static std::ostream& operator<<(std::ostream& os,
const AudioStreamBasicDescription& format) {
os << "sample rate : " << format.mSampleRate << std::endl
@@ -44,8 +46,9 @@ AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager,
started_(false),
hardware_latency_frames_(0),
number_of_channels_in_frame_(0),
- audio_bus_(media::AudioBus::Create(input_params)),
- audio_wrapper_(media::AudioBus::Create(input_params)) {
+ fifo_(input_params.channels(),
+ number_of_frames_,
+ kNumberOfBlocksBufferInFifo) {
DCHECK(manager_);
// Set up the desired (output) format specified by the client.
@@ -494,43 +497,17 @@ OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames,
if (!audio_data)
return kAudioUnitErr_InvalidElement;
- if (number_of_frames != number_of_frames_) {
- // Create a FIFO on the fly to handle any discrepancies in callback rates.
- if (!fifo_) {
- VLOG(1) << "Audio frame size changed from " << number_of_frames_ << " to "
- << number_of_frames << "; adding FIFO to compensate.";
- fifo_.reset(new AudioFifo(
- format_.mChannelsPerFrame, number_of_frames_ + number_of_frames));
- }
-
- if (audio_wrapper_->frames() != static_cast<int>(number_of_frames)) {
- audio_wrapper_ = media::AudioBus::Create(format_.mChannelsPerFrame,
- number_of_frames);
- }
- }
-
- // Copy captured (and interleaved) data into deinterleaved audio bus.
- audio_wrapper_->FromInterleaved(
- audio_data, audio_wrapper_->frames(), format_.mBitsPerChannel / 8);
-
- // When FIFO does not kick in, data will be directly passed to the callback.
- if (!fifo_) {
- CHECK_EQ(audio_wrapper_->frames(), static_cast<int>(number_of_frames_));
- sink_->OnData(
- this, audio_wrapper_.get(), capture_delay_bytes, normalized_volume);
- return noErr;
- }
+ // Copy captured (and interleaved) data into FIFO.
+ fifo_.Push(audio_data, number_of_frames, format_.mBitsPerChannel / 8);
- // Compensate the audio delay caused by the FIFO.
- capture_delay_bytes += fifo_->frames() * format_.mBytesPerFrame;
- fifo_->Push(audio_wrapper_.get());
- if (fifo_->frames() >= static_cast<int>(number_of_frames_)) {
- // Consume the audio from the FIFO.
- fifo_->Consume(audio_bus_.get(), 0, audio_bus_->frames());
- DCHECK(fifo_->frames() < static_cast<int>(number_of_frames_));
+ // Consume and deliver the data when the FIFO has a block of available data.
+ while (fifo_.available_blocks()) {
+ const AudioBus* audio_bus = fifo_.Consume();
+ DCHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_));
- sink_->OnData(
- this, audio_bus_.get(), capture_delay_bytes, normalized_volume);
+ // Compensate the audio delay caused by the FIFO.
+ capture_delay_bytes += fifo_.GetAvailableFrames() * format_.mBytesPerFrame;
+ sink_->OnData(this, audio_bus, capture_delay_bytes, normalized_volume);
}
return noErr;
diff --git a/media/audio/mac/audio_low_latency_input_mac.h b/media/audio/mac/audio_low_latency_input_mac.h
index 059cf1f..c8e43fa 100644
--- a/media/audio/mac/audio_low_latency_input_mac.h
+++ b/media/audio/mac/audio_low_latency_input_mac.h
@@ -45,11 +45,11 @@
#include "media/audio/agc_audio_stream.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_parameters.h"
+#include "media/base/audio_block_fifo.h"
namespace media {
class AudioBus;
-class AudioFifo;
class AudioManagerMac;
class DataBuffer;
@@ -148,20 +148,12 @@ class AUAudioInputStream : public AgcAudioStream<AudioInputStream> {
// when querying the volume of each channel.
int number_of_channels_in_frame_;
- // Dynamically allocated FIFO used to accumulates recorded data when
- // CoreAudio delivers non-requested frame size of data.
- scoped_ptr<media::AudioFifo> fifo_;
+ // FIFO used to accumulates recorded data.
+ media::AudioBlockFifo fifo_;
// Used to defer Start() to workaround http://crbug.com/160920.
base::CancelableClosure deferred_start_cb_;
- // Audio bus used for storage of deinterleaved data for the OnData callback.
- scoped_ptr<media::AudioBus> audio_bus_;
-
- // Audio bus used to convert interleaved data to deinterleaved data before
- // storing data to FIFO or delivering data via OnData callback.
- scoped_ptr<media::AudioBus> audio_wrapper_;
-
DISALLOW_COPY_AND_ASSIGN(AUAudioInputStream);
};
diff --git a/media/audio/pulse/pulse_input.cc b/media/audio/pulse/pulse_input.cc
index d5cb94ec..3509d27 100644
--- a/media/audio/pulse/pulse_input.cc
+++ b/media/audio/pulse/pulse_input.cc
@@ -9,13 +9,15 @@
#include "base/logging.h"
#include "media/audio/pulse/audio_manager_pulse.h"
#include "media/audio/pulse/pulse_util.h"
-#include "media/base/seekable_buffer.h"
namespace media {
using pulse::AutoPulseLock;
using pulse::WaitForOperationCompletion;
+// Number of blocks of buffers used in the |fifo_|.
+const int kNumberOfBlocksBufferInFifo = 2;
+
PulseAudioInputStream::PulseAudioInputStream(AudioManagerPulse* audio_manager,
const std::string& device_name,
const AudioParameters& params,
@@ -28,6 +30,9 @@ PulseAudioInputStream::PulseAudioInputStream(AudioManagerPulse* audio_manager,
channels_(0),
volume_(0.0),
stream_started_(false),
+ fifo_(params.channels(),
+ params.frames_per_buffer(),
+ kNumberOfBlocksBufferInFifo),
pa_mainloop_(mainloop),
pa_context_(context),
handle_(NULL),
@@ -35,7 +40,6 @@ PulseAudioInputStream::PulseAudioInputStream(AudioManagerPulse* audio_manager,
DCHECK(mainloop);
DCHECK(context);
CHECK(params_.IsValid());
- audio_bus_ = AudioBus::Create(params_);
}
PulseAudioInputStream::~PulseAudioInputStream() {
@@ -54,8 +58,6 @@ bool PulseAudioInputStream::Open() {
DCHECK(handle_);
- buffer_.reset(new media::SeekableBuffer(0, 2 * params_.GetBytesPerBuffer()));
- audio_data_buffer_.reset(new uint8[params_.GetBytesPerBuffer()]);
return true;
}
@@ -74,7 +76,7 @@ void PulseAudioInputStream::Start(AudioInputCallback* callback) {
// Clean up the old buffer.
pa_stream_drop(handle_);
- buffer_->Clear();
+ fifo_.Clear();
// Start the streaming.
callback_ = callback;
@@ -265,23 +267,19 @@ void PulseAudioInputStream::ReadData() {
if (!data || length == 0)
break;
- buffer_->Append(reinterpret_cast<const uint8*>(data), length);
+ const int number_of_frames = length / params_.GetBytesPerFrame();
+ fifo_.Push(data, number_of_frames, params_.bits_per_sample() / 8);
// Checks if we still have data.
pa_stream_drop(handle_);
} while (pa_stream_readable_size(handle_) > 0);
- int packet_size = params_.GetBytesPerBuffer();
- while (buffer_->forward_bytes() >= packet_size) {
- buffer_->Read(audio_data_buffer_.get(), packet_size);
- audio_bus_->FromInterleaved(audio_data_buffer_.get(),
- audio_bus_->frames(),
- params_.bits_per_sample() / 8);
- callback_->OnData(
- this, audio_bus_.get(), hardware_delay, normalized_volume);
+ while (fifo_.available_blocks()) {
+ const AudioBus* audio_bus = fifo_.Consume();
- if (buffer_->forward_bytes() < packet_size)
- break;
+ // Compensate the audio delay caused by the FIFO.
+ hardware_delay += fifo_.GetAvailableFrames() * params_.GetBytesPerFrame();
+ callback_->OnData(this, audio_bus, hardware_delay, normalized_volume);
// TODO(xians): Remove once PPAPI is using circular buffers.
DVLOG(1) << "OnData is being called consecutively, sleep 5ms to "
diff --git a/media/audio/pulse/pulse_input.h b/media/audio/pulse/pulse_input.h
index 7e64bb2..9f08379 100644
--- a/media/audio/pulse/pulse_input.h
+++ b/media/audio/pulse/pulse_input.h
@@ -12,6 +12,7 @@
#include "media/audio/audio_device_name.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_parameters.h"
+#include "media/base/audio_block_fifo.h"
struct pa_context;
struct pa_source_info;
@@ -21,7 +22,6 @@ struct pa_threaded_mainloop;
namespace media {
class AudioManagerPulse;
-class SeekableBuffer;
class PulseAudioInputStream : public AgcAudioStream<AudioInputStream> {
public:
@@ -61,11 +61,7 @@ class PulseAudioInputStream : public AgcAudioStream<AudioInputStream> {
bool stream_started_;
// Holds the data from the OS.
- scoped_ptr<media::SeekableBuffer> buffer_;
-
- // Temporary storage for recorded data. It gets a packet of data from
- // |buffer_| and deliver the data to OnData() callback.
- scoped_ptr<uint8[]> audio_data_buffer_;
+ AudioBlockFifo fifo_;
// PulseAudio API structs.
pa_threaded_mainloop* pa_mainloop_; // Weak.
@@ -75,8 +71,6 @@ class PulseAudioInputStream : public AgcAudioStream<AudioInputStream> {
// Flag indicating the state of the context has been changed.
bool context_state_changed_;
- scoped_ptr<AudioBus> audio_bus_;
-
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(PulseAudioInputStream);