| Index: content/renderer/media/audio_device.cc
|
| ===================================================================
|
| --- content/renderer/media/audio_device.cc (revision 108907)
|
| +++ content/renderer/media/audio_device.cc (working copy)
|
| @@ -14,6 +14,19 @@
|
| #include "content/renderer/render_thread_impl.h"
|
| #include "media/audio/audio_util.h"
|
|
|
| +AudioDevice::AudioDevice()
|
| + : buffer_size_(0),
|
| + channels_(0),
|
| + bits_per_sample_(16),
|
| + sample_rate_(0),
|
| + latency_format_(AudioParameters::AUDIO_PCM_LOW_LATENCY),
|
| + callback_(0),
|
| + audio_delay_milliseconds_(0),
|
| + volume_(1.0),
|
| + stream_id_(0) {
|
| + filter_ = RenderThreadImpl::current()->audio_message_filter();
|
| +}
|
| +
|
| AudioDevice::AudioDevice(size_t buffer_size,
|
| int channels,
|
| double sample_rate,
|
| @@ -27,6 +40,31 @@
|
| volume_(1.0),
|
| stream_id_(0) {
|
| filter_ = RenderThreadImpl::current()->audio_message_filter();
|
| + Initialize(buffer_size,
|
| + channels,
|
| + sample_rate,
|
| + AudioParameters::AUDIO_PCM_LOW_LATENCY,
|
| + callback);
|
| +}
|
| +
|
| +void AudioDevice::Initialize(size_t buffer_size,
|
| + int channels,
|
| + double sample_rate,
|
| + AudioParameters::Format latency_format,
|
| + RenderCallback* callback) {
|
| + CHECK_EQ(0, stream_id_) <<
|
| + "AudioDevice::Initialize() must be called before Start()";
|
| +
|
| + buffer_size_ = buffer_size;
|
| + channels_ = channels;
|
| + sample_rate_ = sample_rate;
|
| + latency_format_ = latency_format;
|
| + callback_ = callback;
|
| +
|
| + // Cleanup from any previous initialization.
|
| + for (size_t i = 0; i < audio_data_.size(); ++i)
|
| + delete [] audio_data_[i];
|
| +
|
| audio_data_.reserve(channels);
|
| for (int i = 0; i < channels; ++i) {
|
| float* channel_data = new float[buffer_size];
|
| @@ -34,6 +72,10 @@
|
| }
|
| }
|
|
|
| +bool AudioDevice::IsInitialized() {
|
| + return audio_data_.size() > 0;
|
| +}
|
| +
|
| AudioDevice::~AudioDevice() {
|
| // The current design requires that the user calls Stop() before deleting
|
| // this class.
|
| @@ -44,7 +86,7 @@
|
|
|
| void AudioDevice::Start() {
|
| AudioParameters params;
|
| - params.format = AudioParameters::AUDIO_PCM_LOW_LATENCY;
|
| + params.format = latency_format_;
|
| params.channels = channels_;
|
| params.sample_rate = static_cast<int>(sample_rate_);
|
| params.bits_per_sample = bits_per_sample_;
|
| @@ -84,6 +126,18 @@
|
| return true;
|
| }
|
|
|
| +void AudioDevice::Play() {
|
| + ChildProcess::current()->io_message_loop()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&AudioDevice::PlayOnIOThread, this));
|
| +}
|
| +
|
| +void AudioDevice::Pause(bool flush) {
|
| + ChildProcess::current()->io_message_loop()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&AudioDevice::PauseOnIOThread, this, flush));
|
| +}
|
| +
|
| bool AudioDevice::SetVolume(double volume) {
|
| if (volume < 0 || volume > 1.0)
|
| return false;
|
| @@ -103,7 +157,7 @@
|
| }
|
|
|
| void AudioDevice::InitializeOnIOThread(const AudioParameters& params) {
|
| - // Make sure we don't call Start() more than once.
|
| + // Make sure we don't create the stream more than once.
|
| DCHECK_EQ(0, stream_id_);
|
| if (stream_id_)
|
| return;
|
| @@ -112,11 +166,19 @@
|
| Send(new AudioHostMsg_CreateStream(stream_id_, params, true));
|
| }
|
|
|
| -void AudioDevice::StartOnIOThread() {
|
| +void AudioDevice::PlayOnIOThread() {
|
| if (stream_id_)
|
| Send(new AudioHostMsg_PlayStream(stream_id_));
|
| }
|
|
|
| +void AudioDevice::PauseOnIOThread(bool flush) {
|
| + if (stream_id_) {
|
| + Send(new AudioHostMsg_PauseStream(stream_id_));
|
| + if (flush)
|
| + Send(new AudioHostMsg_FlushStream(stream_id_));
|
| + }
|
| +}
|
| +
|
| void AudioDevice::ShutDownOnIOThread(base::WaitableEvent* completion) {
|
| // Make sure we don't call shutdown more than once.
|
| if (!stream_id_) {
|
| @@ -138,20 +200,17 @@
|
|
|
| void AudioDevice::OnRequestPacket(AudioBuffersState buffers_state) {
|
| // This method does not apply to the low-latency system.
|
| - NOTIMPLEMENTED();
|
| }
|
|
|
| void AudioDevice::OnStateChanged(AudioStreamState state) {
|
| if (state == kAudioStreamError) {
|
| DLOG(WARNING) << "AudioDevice::OnStateChanged(kError)";
|
| }
|
| - NOTIMPLEMENTED();
|
| }
|
|
|
| void AudioDevice::OnCreated(
|
| base::SharedMemoryHandle handle, uint32 length) {
|
| // Not needed in this simple implementation.
|
| - NOTIMPLEMENTED();
|
| }
|
|
|
| void AudioDevice::OnLowLatencyCreated(
|
| @@ -191,7 +250,7 @@
|
|
|
| MessageLoop::current()->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&AudioDevice::StartOnIOThread, this));
|
| + base::Bind(&AudioDevice::PlayOnIOThread, this));
|
| }
|
|
|
| void AudioDevice::OnVolume(double volume) {
|
| @@ -210,10 +269,8 @@
|
| const int samples_per_ms = static_cast<int>(sample_rate_) / 1000;
|
| const int bytes_per_ms = channels_ * (bits_per_sample_ / 8) * samples_per_ms;
|
|
|
| - while ((sizeof(pending_data) == socket_->Receive(&pending_data,
|
| - sizeof(pending_data))) &&
|
| - (pending_data >= 0)) {
|
| -
|
| + while (sizeof(pending_data) ==
|
| + socket_->Receive(&pending_data, sizeof(pending_data))) {
|
| // Convert the number of pending bytes in the render buffer
|
| // into milliseconds.
|
| audio_delay_milliseconds_ = pending_data / bytes_per_ms;
|
|
|