summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/audio/audio_input_controller.cc4
-rw-r--r--media/audio/audio_input_controller.h5
-rw-r--r--media/audio/audio_input_unittest.cc6
-rw-r--r--media/audio/audio_io.h2
-rw-r--r--media/audio/fake_audio_input_stream.cc2
-rw-r--r--media/audio/linux/alsa_input.cc21
-rw-r--r--media/audio/linux/alsa_input.h3
-rw-r--r--media/audio/mac/audio_input_mac.cc3
-rw-r--r--media/audio/win/wavein_input_win.cc3
9 files changed, 38 insertions, 11 deletions
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc
index b370612..1e264e6 100644
--- a/media/audio/audio_input_controller.cc
+++ b/media/audio/audio_input_controller.cc
@@ -183,7 +183,7 @@ void AudioInputController::DoResetNoDataTimer() {
}
void AudioInputController::OnData(AudioInputStream* stream, const uint8* data,
- uint32 size) {
+ uint32 size, uint32 hardware_delay_bytes) {
{
base::AutoLock auto_lock(lock_);
if (state_ != kRecording)
@@ -196,7 +196,7 @@ void AudioInputController::OnData(AudioInputStream* stream, const uint8* data,
// Use SyncSocket if we are in a low-latency mode.
if (LowLatencyMode()) {
sync_writer_->Write(data, size);
- sync_writer_->UpdateRecordedBytes(size);
+ sync_writer_->UpdateRecordedBytes(hardware_delay_bytes);
return;
}
diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h
index dd29001..fdc29cf 100644
--- a/media/audio/audio_input_controller.h
+++ b/media/audio/audio_input_controller.h
@@ -58,7 +58,7 @@ class MEDIA_EXPORT AudioInputController
virtual ~SyncWriter() {}
// Notify the synchronous writer about the number of bytes in the
- // AudioInputController which has been recorded.
+ // soundcard which has been recorded.
virtual void UpdateRecordedBytes(uint32 bytes) = 0;
// Write certain amount of data from |data|. This method returns
@@ -117,7 +117,8 @@ class MEDIA_EXPORT AudioInputController
///////////////////////////////////////////////////////////////////////////
// AudioInputCallback methods.
- virtual void OnData(AudioInputStream* stream, const uint8* src, uint32 size);
+ virtual void OnData(AudioInputStream* stream, const uint8* src, uint32 size,
+ uint32 hardware_delay_bytes);
virtual void OnClose(AudioInputStream* stream);
virtual void OnError(AudioInputStream* stream, int code);
diff --git a/media/audio/audio_input_unittest.cc b/media/audio/audio_input_unittest.cc
index f62de94..914aa4c3 100644
--- a/media/audio/audio_input_unittest.cc
+++ b/media/audio/audio_input_unittest.cc
@@ -25,7 +25,7 @@ class TestInputCallback : public AudioInputStream::AudioInputCallback {
max_data_bytes_(max_data_bytes) {
}
virtual void OnData(AudioInputStream* stream, const uint8* data,
- uint32 size) {
+ uint32 size, uint32 hardware_delay_bytes) {
++callback_count_;
// Read the first byte to make sure memory is good.
if (size) {
@@ -75,9 +75,9 @@ class TestInputCallbackBlocking : public TestInputCallback {
block_for_ms_(block_for_ms) {
}
virtual void OnData(AudioInputStream* stream, const uint8* data,
- uint32 size) {
+ uint32 size, uint32 hardware_delay_bytes) {
// Call the base, which increments the callback_count_.
- TestInputCallback::OnData(stream, data, size);
+ TestInputCallback::OnData(stream, data, size, hardware_delay_bytes);
if (callback_count() > block_after_callback_)
base::PlatformThread::Sleep(block_for_ms_);
}
diff --git a/media/audio/audio_io.h b/media/audio/audio_io.h
index 74b5c47..2550873 100644
--- a/media/audio/audio_io.h
+++ b/media/audio/audio_io.h
@@ -112,7 +112,7 @@ class AudioInputStream {
// available. This is called from a special audio thread and the
// implementation should return as soon as possible.
virtual void OnData(AudioInputStream* stream, const uint8* src,
- uint32 size) = 0;
+ uint32 size, uint32 hardware_delay_bytes) = 0;
// The stream is done with this callback, the last call received by this
// audio sink.
diff --git a/media/audio/fake_audio_input_stream.cc b/media/audio/fake_audio_input_stream.cc
index b84db92..8ed02de 100644
--- a/media/audio/fake_audio_input_stream.cc
+++ b/media/audio/fake_audio_input_stream.cc
@@ -48,7 +48,7 @@ void FakeAudioInputStream::Start(AudioInputCallback* callback) {
void FakeAudioInputStream::DoCallback() {
DCHECK(callback_);
- callback_->OnData(this, buffer_.get(), buffer_size_);
+ callback_->OnData(this, buffer_.get(), buffer_size_, buffer_size_);
Time now = Time::Now();
int64 next_callback_ms = (last_callback_time_ +
diff --git a/media/audio/linux/alsa_input.cc b/media/audio/linux/alsa_input.cc
index 9864fb9..8aad65a 100644
--- a/media/audio/linux/alsa_input.cc
+++ b/media/audio/linux/alsa_input.cc
@@ -133,6 +133,21 @@ bool AlsaPcmInputStream::Recover(int original_error) {
return true;
}
+snd_pcm_sframes_t AlsaPcmInputStream::GetCurrentDelay() {
+ snd_pcm_sframes_t delay = -1;
+
+ int error = wrapper_->PcmDelay(device_handle_, &delay);
+ if (error < 0)
+ Recover(error);
+
+ // snd_pcm_delay() may not work in the beginning of the stream. In this case
+ // return delay of data we know currently is in the ALSA's buffer.
+ if (delay < 0)
+ delay = wrapper_->PcmAvailUpdate(device_handle_);
+
+ return delay;
+}
+
void AlsaPcmInputStream::ReadAudio() {
DCHECK(callback_);
@@ -160,11 +175,15 @@ void AlsaPcmInputStream::ReadAudio() {
int num_packets = frames / params_.samples_per_packet;
int num_packets_read = num_packets;
+ int bytes_per_frame = params_.channels * params_.bits_per_sample / 8;
+ uint32 hardware_delay_bytes =
+ static_cast<uint32>(GetCurrentDelay() * bytes_per_frame);
while (num_packets--) {
int frames_read = wrapper_->PcmReadi(device_handle_, audio_packet_.get(),
params_.samples_per_packet);
if (frames_read == params_.samples_per_packet) {
- callback_->OnData(this, audio_packet_.get(), bytes_per_packet_);
+ callback_->OnData(this, audio_packet_.get(), bytes_per_packet_,
+ hardware_delay_bytes);
} else {
LOG(WARNING) << "PcmReadi returning less than expected frames: "
<< frames_read << " vs. " << params_.samples_per_packet
diff --git a/media/audio/linux/alsa_input.h b/media/audio/linux/alsa_input.h
index e97737f..3e5209a 100644
--- a/media/audio/linux/alsa_input.h
+++ b/media/audio/linux/alsa_input.h
@@ -50,6 +50,9 @@ class AlsaPcmInputStream : public AudioInputStream {
// Recovers from any device errors if possible.
bool Recover(int error);
+ // Utility function for talking with the ALSA API.
+ snd_pcm_sframes_t GetCurrentDelay();
+
std::string device_name_;
AudioParameters params_;
int bytes_per_packet_;
diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc
index 3efe86c..e96277f 100644
--- a/media/audio/mac/audio_input_mac.cc
+++ b/media/audio/mac/audio_input_mac.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -159,6 +159,7 @@ void PCMQueueInAudioInputStream::HandleInputBuffer(
if (audio_buffer->mAudioDataByteSize)
callback_->OnData(this,
reinterpret_cast<const uint8*>(audio_buffer->mAudioData),
+ audio_buffer->mAudioDataByteSize,
audio_buffer->mAudioDataByteSize);
// Recycle the buffer.
OSStatus err = QueueNextBuffer(audio_buffer);
diff --git a/media/audio/win/wavein_input_win.cc b/media/audio/win/wavein_input_win.cc
index a1f6a83..b994a29 100644
--- a/media/audio/win/wavein_input_win.cc
+++ b/media/audio/win/wavein_input_win.cc
@@ -190,8 +190,11 @@ void PCMWaveInAudioInputStream::WaveCallback(HWAVEIN hwi, UINT msg,
if (msg == WIM_DATA) {
// WIM_DONE indicates that the driver is done with our buffer. We pass it
// to the callback and check if we need to stop playing.
+ // It should be OK to assume the data in the buffer is what has been
+ // recorded in the soundcard.
WAVEHDR* buffer = reinterpret_cast<WAVEHDR*>(param1);
obj->callback_->OnData(obj, reinterpret_cast<const uint8*>(buffer->lpData),
+ buffer->dwBytesRecorded,
buffer->dwBytesRecorded);
if (obj->state_ == kStateStopping) {