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

Unified Diff: media/audio/audio_output_device.cc

Issue 10830268: Allow audio system to handle synchronized low-latency audio I/O (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/audio/audio_output_device.h ('k') | media/audio/audio_output_device_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/audio/audio_output_device.cc
===================================================================
--- media/audio/audio_output_device.cc (revision 156123)
+++ media/audio/audio_output_device.cc (working copy)
@@ -11,6 +11,7 @@
#include "media/audio/audio_output_controller.h"
#include "media/audio/audio_util.h"
#include "media/audio/shared_memory_util.h"
+#include "media/base/limits.h"
namespace media {
@@ -21,6 +22,7 @@
: public AudioDeviceThread::Callback {
public:
AudioThreadCallback(const AudioParameters& audio_parameters,
+ int input_channels,
base::SharedMemoryHandle memory,
int memory_length,
AudioRendererSink::RenderCallback* render_callback);
@@ -33,7 +35,8 @@
private:
AudioRendererSink::RenderCallback* render_callback_;
- scoped_ptr<AudioBus> audio_bus_;
+ scoped_ptr<AudioBus> input_bus_;
+ scoped_ptr<AudioBus> output_bus_;
DISALLOW_COPY_AND_ASSIGN(AudioThreadCallback);
};
@@ -41,6 +44,7 @@
AudioOutputIPC* ipc,
const scoped_refptr<base::MessageLoopProxy>& io_loop)
: ScopedLoopObserver(io_loop),
+ input_channels_(0),
callback_(NULL),
ipc_(ipc),
stream_id_(0),
@@ -60,6 +64,15 @@
callback_ = callback;
}
+void AudioOutputDevice::InitializeIO(const AudioParameters& params,
+ int input_channels,
+ RenderCallback* callback) {
+ DCHECK_GE(input_channels, 0);
+ DCHECK_LT(input_channels, limits::kMaxChannels);
+ input_channels_ = input_channels;
+ Initialize(params, callback);
+}
+
AudioOutputDevice::~AudioOutputDevice() {
// The current design requires that the user calls Stop() before deleting
// this class.
@@ -70,7 +83,7 @@
DCHECK(callback_) << "Initialize hasn't been called";
message_loop()->PostTask(FROM_HERE,
base::Bind(&AudioOutputDevice::CreateStreamOnIOThread, this,
- audio_parameters_));
+ audio_parameters_, input_channels_));
}
void AudioOutputDevice::Stop() {
@@ -105,7 +118,8 @@
return true;
}
-void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params) {
+void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params,
+ int input_channels) {
DCHECK(message_loop()->BelongsToCurrentThread());
// Make sure we don't create the stream more than once.
DCHECK_EQ(0, stream_id_);
@@ -113,7 +127,7 @@
return;
stream_id_ = ipc_->AddDelegate(this);
- ipc_->CreateStream(stream_id_, params);
+ ipc_->CreateStream(stream_id_, params, input_channels);
}
void AudioOutputDevice::PlayOnIOThread() {
@@ -214,7 +228,7 @@
DCHECK(audio_thread_.IsStopped());
audio_callback_.reset(new AudioOutputDevice::AudioThreadCallback(
- audio_parameters_, handle, length, callback_));
+ audio_parameters_, input_channels_, handle, length, callback_));
audio_thread_.Start(audio_callback_.get(), socket_handle,
"AudioOutputDevice");
@@ -238,10 +252,14 @@
AudioOutputDevice::AudioThreadCallback::AudioThreadCallback(
const AudioParameters& audio_parameters,
+ int input_channels,
base::SharedMemoryHandle memory,
int memory_length,
AudioRendererSink::RenderCallback* render_callback)
- : AudioDeviceThread::Callback(audio_parameters, memory, memory_length),
+ : AudioDeviceThread::Callback(audio_parameters,
+ input_channels,
+ memory,
+ memory_length),
render_callback_(render_callback) {
}
@@ -250,8 +268,27 @@
void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() {
shared_memory_.Map(TotalSharedMemorySizeInBytes(memory_length_));
- DCHECK_EQ(memory_length_, AudioBus::CalculateMemorySize(audio_parameters_));
- audio_bus_ = AudioBus::WrapMemory(audio_parameters_, shared_memory_.memory());
+
+ // Calculate output and input memory size.
+ int output_memory_size = AudioBus::CalculateMemorySize(audio_parameters_);
+ int frames = audio_parameters_.frames_per_buffer();
+ int input_memory_size =
+ AudioBus::CalculateMemorySize(input_channels_, frames);
+
+ int io_size = output_memory_size + input_memory_size;
+
+ DCHECK_EQ(memory_length_, io_size);
+
+ output_bus_ =
+ AudioBus::WrapMemory(audio_parameters_, shared_memory_.memory());
+
+ if (input_channels_ > 0) {
+ // The input data is after the output data.
+ char* input_data =
+ static_cast<char*>(shared_memory_.memory()) + output_memory_size;
+ input_bus_ =
+ AudioBus::WrapMemory(input_channels_, frames, input_data);
+ }
}
// Called whenever we receive notifications about pending data.
@@ -269,11 +306,19 @@
TRACE_EVENT0("audio", "AudioOutputDevice::FireRenderCallback");
// Update the audio-delay measurement then ask client to render audio. Since
- // |audio_bus_| is wrapping the shared memory the Render() call is writing
+ // |output_bus_| is wrapping the shared memory the Render() call is writing
// directly into the shared memory.
- size_t num_frames = render_callback_->Render(
- audio_bus_.get(), audio_delay_milliseconds);
+ size_t num_frames = audio_parameters_.frames_per_buffer();
+ if (input_bus_.get() && input_channels_ > 0) {
+ render_callback_->RenderIO(input_bus_.get(),
+ output_bus_.get(),
+ audio_delay_milliseconds);
+ } else {
+ num_frames = render_callback_->Render(output_bus_.get(),
+ audio_delay_milliseconds);
+ }
+
// Let the host know we are done.
// TODO(dalecurtis): Technically this is not always correct. Due to channel
// padding for alignment, there may be more data available than this. We're
@@ -281,7 +326,7 @@
// these methods to Set/GetActualFrameCount().
SetActualDataSizeInBytes(
&shared_memory_, memory_length_,
- num_frames * sizeof(*audio_bus_->channel(0)) * audio_bus_->channels());
+ num_frames * sizeof(*output_bus_->channel(0)) * output_bus_->channels());
}
} // namespace media.
« no previous file with comments | « media/audio/audio_output_device.h ('k') | media/audio/audio_output_device_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698