diff options
author | macourteau@chromium.org <macourteau@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-17 18:36:18 +0000 |
---|---|---|
committer | macourteau@chromium.org <macourteau@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-17 18:36:18 +0000 |
commit | bfda05c8bfd42c4e21825686862aa2a008c29344 (patch) | |
tree | 117080b980aa88ee9c969d6ddce35d136052bf5d | |
parent | a5566938c4e9d644245e9bca37eeff2cdb3eb7f4 (diff) | |
download | chromium_src-bfda05c8bfd42c4e21825686862aa2a008c29344.zip chromium_src-bfda05c8bfd42c4e21825686862aa2a008c29344.tar.gz chromium_src-bfda05c8bfd42c4e21825686862aa2a008c29344.tar.bz2 |
Revert 277794 "Modifies AudioInputCallback::OnData and use media..."
> Modifies AudioInputCallback::OnData and use media::AudioBus instead of plain byte vector
>
> BUG=375155
> TEST=WebRTC and WebSpeech demos
>
> Review URL: https://codereview.chromium.org/314713002
R=henrika@chromium.org
TBR=henrika@chromium.org
Review URL: https://codereview.chromium.org/335343004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277814 0039d316-1c4b-4281-b951-d872f2087c98
46 files changed, 282 insertions, 399 deletions
diff --git a/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc b/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc index 72f6109..c9afbf1 100644 --- a/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc +++ b/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc @@ -161,11 +161,9 @@ class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { public: MockAudioInputCallback() {} - MOCK_METHOD4(OnData, - void(AudioInputStream* stream, - const media::AudioBus* src, - uint32 hardware_delay_bytes, - double volume)); + MOCK_METHOD5(OnData, void(AudioInputStream* stream, const uint8* src, + uint32 size, uint32 hardware_delay_bytes, + double volume)); MOCK_METHOD1(OnError, void(AudioInputStream* stream)); private: @@ -240,7 +238,7 @@ class WebContentsAudioInputStreamTest : public testing::Test { static_cast<AudioMirroringManager::MirroringDestination*>(NULL))) .RetiresOnSaturation(); - EXPECT_CALL(mock_input_callback_, OnData(NotNull(), NotNull(), _, _)) + EXPECT_CALL(mock_input_callback_, OnData(NotNull(), NotNull(), _, _, _)) .WillRepeatedly( InvokeWithoutArgs(&on_data_event_, &base::WaitableEvent::Signal)); diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.cc b/content/browser/renderer_host/media/audio_input_renderer_host.cc index 2dcc56d..e5d4f78 100644 --- a/content/browser/renderer_host/media/audio_input_renderer_host.cc +++ b/content/browser/renderer_host/media/audio_input_renderer_host.cc @@ -17,7 +17,6 @@ #include "content/browser/renderer_host/media/audio_input_sync_writer.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "media/audio/audio_manager_base.h" -#include "media/base/audio_bus.h" namespace content { @@ -114,7 +113,8 @@ void AudioInputRendererHost::OnError(media::AudioInputController* controller, } void AudioInputRendererHost::OnData(media::AudioInputController* controller, - const media::AudioBus* data) { + const uint8* data, + uint32 size) { NOTREACHED() << "Only low-latency mode is supported."; } @@ -292,9 +292,8 @@ void AudioInputRendererHost::OnCreateStream( // Create a new AudioEntry structure. scoped_ptr<AudioEntry> entry(new AudioEntry()); - const uint32 segment_size = - (sizeof(media::AudioInputBufferParameters) + - media::AudioBus::CalculateMemorySize(audio_params)); + const uint32 segment_size = (sizeof(media::AudioInputBufferParameters) + + audio_params.GetBytesPerBuffer()); entry->shared_memory_segment_count = config.shared_memory_count; // Create the shared memory and share it with the renderer process @@ -308,8 +307,9 @@ void AudioInputRendererHost::OnCreateStream( return; } - scoped_ptr<AudioInputSyncWriter> writer(new AudioInputSyncWriter( - &entry->shared_memory, entry->shared_memory_segment_count, audio_params)); + scoped_ptr<AudioInputSyncWriter> writer( + new AudioInputSyncWriter(&entry->shared_memory, + entry->shared_memory_segment_count)); if (!writer->Init()) { SendErrorMessage(stream_id, SYNC_WRITER_INIT_FAILED); diff --git a/content/browser/renderer_host/media/audio_input_renderer_host.h b/content/browser/renderer_host/media/audio_input_renderer_host.h index 7bd6692..75a78e8 100644 --- a/content/browser/renderer_host/media/audio_input_renderer_host.h +++ b/content/browser/renderer_host/media/audio_input_renderer_host.h @@ -117,7 +117,8 @@ class CONTENT_EXPORT AudioInputRendererHost virtual void OnError(media::AudioInputController* controller, media::AudioInputController::ErrorCode error_code) OVERRIDE; virtual void OnData(media::AudioInputController* controller, - const media::AudioBus* data) OVERRIDE; + const uint8* data, + uint32 size) OVERRIDE; virtual void OnLog(media::AudioInputController* controller, const std::string& message) OVERRIDE; diff --git a/content/browser/renderer_host/media/audio_input_sync_writer.cc b/content/browser/renderer_host/media/audio_input_sync_writer.cc index a043500..99b91b7 100644 --- a/content/browser/renderer_host/media/audio_input_sync_writer.cc +++ b/content/browser/renderer_host/media/audio_input_sync_writer.cc @@ -9,36 +9,19 @@ #include "base/memory/shared_memory.h" #include "content/browser/renderer_host/media/media_stream_manager.h" -using media::AudioBus; - namespace content { -AudioInputSyncWriter::AudioInputSyncWriter(base::SharedMemory* shared_memory, - int shared_memory_segment_count, - const media::AudioParameters& params) +AudioInputSyncWriter::AudioInputSyncWriter( + base::SharedMemory* shared_memory, + int shared_memory_segment_count) : shared_memory_(shared_memory), shared_memory_segment_count_(shared_memory_segment_count), current_segment_id_(0), - creation_time_(base::Time::Now()), - audio_bus_memory_size_(AudioBus::CalculateMemorySize(params)) { + creation_time_(base::Time::Now()) { DCHECK_GT(shared_memory_segment_count, 0); DCHECK_EQ(shared_memory->requested_size() % shared_memory_segment_count, 0u); shared_memory_segment_size_ = shared_memory->requested_size() / shared_memory_segment_count; - DVLOG(1) << "SharedMemory::requested_size: " - << shared_memory->requested_size(); - DVLOG(1) << "shared_memory_segment_count: " << shared_memory_segment_count; - - // Create vector of audio buses by wrapping existing blocks of memory. - uint8* ptr = static_cast<uint8*>(shared_memory_->memory()); - for (int i = 0; i < shared_memory_segment_count; ++i) { - media::AudioInputBuffer* buffer = - reinterpret_cast<media::AudioInputBuffer*>(ptr); - scoped_ptr<media::AudioBus> audio_bus = - media::AudioBus::WrapMemory(params, buffer->audio); - audio_buses_.push_back(audio_bus.release()); - ptr += shared_memory_segment_size_; - } } AudioInputSyncWriter::~AudioInputSyncWriter() {} @@ -48,9 +31,10 @@ void AudioInputSyncWriter::UpdateRecordedBytes(uint32 bytes) { socket_->Send(&bytes, sizeof(bytes)); } -void AudioInputSyncWriter::Write(const media::AudioBus* data, - double volume, - bool key_pressed) { +uint32 AudioInputSyncWriter::Write(const void* data, + uint32 size, + double volume, + bool key_pressed) { #if !defined(OS_ANDROID) static const base::TimeDelta kLogDelayThreadhold = base::TimeDelta::FromMilliseconds(500); @@ -75,22 +59,19 @@ void AudioInputSyncWriter::Write(const media::AudioBus* data, last_write_time_ = base::Time::Now(); #endif - // Write audio parameters to shared memory. uint8* ptr = static_cast<uint8*>(shared_memory_->memory()); ptr += current_segment_id_ * shared_memory_segment_size_; media::AudioInputBuffer* buffer = reinterpret_cast<media::AudioInputBuffer*>(ptr); buffer->params.volume = volume; - buffer->params.size = audio_bus_memory_size_; + buffer->params.size = size; buffer->params.key_pressed = key_pressed; - - // Copy data from the native audio layer into shared memory using pre- - // allocated audio buses. - media::AudioBus* audio_bus = audio_buses_[current_segment_id_]; - data->CopyTo(audio_bus); + memcpy(buffer->audio, data, size); if (++current_segment_id_ >= shared_memory_segment_count_) current_segment_id_ = 0; + + return size; } void AudioInputSyncWriter::Close() { diff --git a/content/browser/renderer_host/media/audio_input_sync_writer.h b/content/browser/renderer_host/media/audio_input_sync_writer.h index 424d790..75b2bbf 100644 --- a/content/browser/renderer_host/media/audio_input_sync_writer.h +++ b/content/browser/renderer_host/media/audio_input_sync_writer.h @@ -5,13 +5,10 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_SYNC_WRITER_H_ #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_INPUT_SYNC_WRITER_H_ -#include "base/memory/scoped_vector.h" #include "base/process/process.h" #include "base/sync_socket.h" #include "base/time/time.h" #include "media/audio/audio_input_controller.h" -#include "media/audio/audio_parameters.h" -#include "media/base/audio_bus.h" #if defined(OS_POSIX) #include "base/file_descriptor_posix.h" @@ -29,16 +26,16 @@ namespace content { class AudioInputSyncWriter : public media::AudioInputController::SyncWriter { public: explicit AudioInputSyncWriter(base::SharedMemory* shared_memory, - int shared_memory_segment_count, - const media::AudioParameters& params); + int shared_memory_segment_count); virtual ~AudioInputSyncWriter(); - // media::AudioInputController::SyncWriter implementation. + // media::AudioOutputController::SyncWriter implementation. virtual void UpdateRecordedBytes(uint32 bytes) OVERRIDE; - virtual void Write(const media::AudioBus* data, - double volume, - bool key_pressed) OVERRIDE; + virtual uint32 Write(const void* data, + uint32 size, + double volume, + bool key_pressed) OVERRIDE; virtual void Close() OVERRIDE; bool Init(); @@ -68,13 +65,6 @@ class AudioInputSyncWriter : public media::AudioInputController::SyncWriter { // The time of the last Write call. base::Time last_write_time_; - // Size in bytes of each audio bus. - const int audio_bus_memory_size_; - - // Vector of audio buses allocated during construction and deleted in the - // destructor. - ScopedVector<media::AudioBus> audio_buses_; - DISALLOW_IMPLICIT_CONSTRUCTORS(AudioInputSyncWriter); }; diff --git a/content/browser/speech/speech_recognition_browsertest.cc b/content/browser/speech/speech_recognition_browsertest.cc index 5871aa1..e734843 100644 --- a/content/browser/speech/speech_recognition_browsertest.cc +++ b/content/browser/speech/speech_recognition_browsertest.cc @@ -133,7 +133,6 @@ class SpeechRecognitionBrowserTest : size_t buffer_size, bool fill_with_noise) { DCHECK(controller.get()); - const media::AudioParameters& audio_params = controller->audio_parameters(); scoped_ptr<uint8[]> audio_buffer(new uint8[buffer_size]); if (fill_with_noise) { for (size_t i = 0; i < buffer_size; ++i) @@ -142,13 +141,9 @@ class SpeechRecognitionBrowserTest : } else { memset(audio_buffer.get(), 0, buffer_size); } - - scoped_ptr<media::AudioBus> audio_bus = - media::AudioBus::Create(audio_params); - audio_bus->FromInterleaved(&audio_buffer.get()[0], - audio_bus->frames(), - audio_params.bits_per_sample() / 8); - controller->event_handler()->OnData(controller, audio_bus.get()); + controller->event_handler()->OnData(controller, + audio_buffer.get(), + buffer_size); } void FeedAudioController(int duration_ms, bool feed_with_noise) { diff --git a/content/browser/speech/speech_recognizer_impl.cc b/content/browser/speech/speech_recognizer_impl.cc index e49d301..3ba1f08 100644 --- a/content/browser/speech/speech_recognizer_impl.cc +++ b/content/browser/speech/speech_recognizer_impl.cc @@ -37,10 +37,10 @@ class SpeechRecognizerImpl::OnDataConverter const AudioParameters& output_params); virtual ~OnDataConverter(); - // Converts input audio |data| bus into an AudioChunk where the input format + // Converts input |data| buffer into an AudioChunk where the input format // is given by |input_parameters_| and the output format by // |output_parameters_|. - scoped_refptr<AudioChunk> Convert(const AudioBus* data); + scoped_refptr<AudioChunk> Convert(const uint8* data, size_t size); private: // media::AudioConverter::InputCallback implementation. @@ -132,10 +132,11 @@ SpeechRecognizerImpl::OnDataConverter::~OnDataConverter() { } scoped_refptr<AudioChunk> SpeechRecognizerImpl::OnDataConverter::Convert( - const AudioBus* data) { - CHECK_EQ(data->frames(), input_parameters_.frames_per_buffer()); + const uint8* data, size_t size) { + CHECK_EQ(size, static_cast<size_t>(input_parameters_.GetBytesPerBuffer())); - data->CopyTo(input_bus_.get()); + input_bus_->FromInterleaved( + data, input_bus_->frames(), input_parameters_.bits_per_sample() / 8); waiting_for_input_ = true; audio_converter_.Convert(output_bus_.get()); @@ -271,10 +272,13 @@ void SpeechRecognizerImpl::OnError(AudioInputController* controller, } void SpeechRecognizerImpl::OnData(AudioInputController* controller, - const AudioBus* data) { + const uint8* data, uint32 size) { + if (size == 0) // This could happen when audio capture stops and is normal. + return; + // Convert audio from native format to fixed format used by WebSpeech. FSMEventArgs event_args(EVENT_AUDIO_DATA); - event_args.audio_data = audio_converter_->Convert(data); + event_args.audio_data = audio_converter_->Convert(data, size); BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&SpeechRecognizerImpl::DispatchEvent, diff --git a/content/browser/speech/speech_recognizer_impl.h b/content/browser/speech/speech_recognizer_impl.h index 55e07f0..abd3ab4 100644 --- a/content/browser/speech/speech_recognizer_impl.h +++ b/content/browser/speech/speech_recognizer_impl.h @@ -16,7 +16,6 @@ #include "net/url_request/url_request_context_getter.h" namespace media { -class AudioBus; class AudioManager; } @@ -133,7 +132,7 @@ class CONTENT_EXPORT SpeechRecognizerImpl virtual void OnError(media::AudioInputController* controller, media::AudioInputController::ErrorCode error_code) OVERRIDE; virtual void OnData(media::AudioInputController* controller, - const media::AudioBus* data) OVERRIDE; + const uint8* data, uint32 size) OVERRIDE; virtual void OnLog(media::AudioInputController* controller, const std::string& message) OVERRIDE {} diff --git a/content/browser/speech/speech_recognizer_impl_unittest.cc b/content/browser/speech/speech_recognizer_impl_unittest.cc index 13d5eba..3709024 100644 --- a/content/browser/speech/speech_recognizer_impl_unittest.cc +++ b/content/browser/speech/speech_recognizer_impl_unittest.cc @@ -13,7 +13,6 @@ #include "media/audio/fake_audio_output_stream.h" #include "media/audio/mock_audio_manager.h" #include "media/audio/test_audio_input_controller_factory.h" -#include "media/base/audio_bus.h" #include "net/base/net_errors.h" #include "net/url_request/test_url_fetcher_factory.h" #include "net/url_request/url_request_status.h" @@ -67,13 +66,6 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener, ChannelLayoutToChannelCount(SpeechRecognizerImpl::kChannelLayout) * SpeechRecognizerImpl::kNumBitsPerAudioSample) / (8 * 1000); audio_packet_.resize(audio_packet_length_bytes); - - const int channels = - ChannelLayoutToChannelCount(SpeechRecognizerImpl::kChannelLayout); - bytes_per_sample_ = SpeechRecognizerImpl::kNumBitsPerAudioSample / 8; - const int frames = audio_packet_length_bytes / channels / bytes_per_sample_; - audio_bus_ = media::AudioBus::Create(channels, frames); - audio_bus_->Zero(); } void CheckEventsConsistency() { @@ -155,17 +147,10 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener, AudioInputController::set_factory_for_testing(NULL); } - void CopyPacketToAudioBus() { - // Copy the created signal into an audio bus in a deinterleaved format. - audio_bus_->FromInterleaved( - &audio_packet_[0], audio_bus_->frames(), bytes_per_sample_); - } - void FillPacketWithTestWaveform() { // Fill the input with a simple pattern, a 125Hz sawtooth waveform. for (size_t i = 0; i < audio_packet_.size(); ++i) audio_packet_[i] = static_cast<uint8>(i); - CopyPacketToAudioBus(); } void FillPacketWithNoise() { @@ -175,7 +160,6 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener, value += factor; audio_packet_[i] = value % 100; } - CopyPacketToAudioBus(); } protected: @@ -194,8 +178,6 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener, net::TestURLFetcherFactory url_fetcher_factory_; TestAudioInputControllerFactory audio_input_controller_factory_; std::vector<uint8> audio_packet_; - scoped_ptr<media::AudioBus> audio_bus_; - int bytes_per_sample_; float volume_; float noise_volume_; }; @@ -240,7 +222,8 @@ TEST_F(SpeechRecognizerImplTest, StopWithData) { // full recording to complete. const size_t kNumChunks = 5; for (size_t i = 0; i < kNumChunks; ++i) { - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); base::MessageLoop::current()->RunUntilIdle(); net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); ASSERT_TRUE(fetcher); @@ -281,7 +264,8 @@ TEST_F(SpeechRecognizerImplTest, CancelWithData) { TestAudioInputController* controller = audio_input_controller_factory_.controller(); ASSERT_TRUE(controller); - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); base::MessageLoop::current()->RunUntilIdle(); recognizer_->AbortRecognition(); base::MessageLoop::current()->RunUntilIdle(); @@ -301,7 +285,8 @@ TEST_F(SpeechRecognizerImplTest, ConnectionError) { TestAudioInputController* controller = audio_input_controller_factory_.controller(); ASSERT_TRUE(controller); - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); base::MessageLoop::current()->RunUntilIdle(); net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); ASSERT_TRUE(fetcher); @@ -338,7 +323,8 @@ TEST_F(SpeechRecognizerImplTest, ServerError) { TestAudioInputController* controller = audio_input_controller_factory_.controller(); ASSERT_TRUE(controller); - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); base::MessageLoop::current()->RunUntilIdle(); net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); ASSERT_TRUE(fetcher); @@ -391,7 +377,8 @@ TEST_F(SpeechRecognizerImplTest, AudioControllerErrorWithData) { TestAudioInputController* controller = audio_input_controller_factory_.controller(); ASSERT_TRUE(controller); - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); controller->event_handler()->OnError(controller, AudioInputController::UNKNOWN_ERROR); base::MessageLoop::current()->RunUntilIdle(); @@ -416,7 +403,8 @@ TEST_F(SpeechRecognizerImplTest, NoSpeechCallbackIssued) { GoogleOneShotRemoteEngine::kAudioPacketIntervalMs + 1; // The vector is already filled with zero value samples on create. for (int i = 0; i < num_packets; ++i) { - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); } base::MessageLoop::current()->RunUntilIdle(); EXPECT_TRUE(recognition_started_); @@ -444,12 +432,14 @@ TEST_F(SpeechRecognizerImplTest, NoSpeechCallbackNotIssued) { // The vector is already filled with zero value samples on create. for (int i = 0; i < num_packets / 2; ++i) { - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); } FillPacketWithTestWaveform(); for (int i = 0; i < num_packets / 2; ++i) { - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); } base::MessageLoop::current()->RunUntilIdle(); @@ -480,18 +470,21 @@ TEST_F(SpeechRecognizerImplTest, SetInputVolumeCallback) { GoogleOneShotRemoteEngine::kAudioPacketIntervalMs; FillPacketWithNoise(); for (int i = 0; i < num_packets; ++i) { - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); } base::MessageLoop::current()->RunUntilIdle(); EXPECT_EQ(-1.0f, volume_); // No audio volume set yet. // The vector is already filled with zero value samples on create. - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); base::MessageLoop::current()->RunUntilIdle(); EXPECT_FLOAT_EQ(0.74939233f, volume_); FillPacketWithTestWaveform(); - controller->event_handler()->OnData(controller, audio_bus_.get()); + controller->event_handler()->OnData(controller, &audio_packet_[0], + audio_packet_.size()); base::MessageLoop::current()->RunUntilIdle(); EXPECT_NEAR(0.89926866f, volume_, 0.00001f); EXPECT_FLOAT_EQ(0.75071919f, noise_volume_); diff --git a/media/audio/agc_audio_stream.h b/media/audio/agc_audio_stream.h index 940d964..b289a0b 100644 --- a/media/audio/agc_audio_stream.h +++ b/media/audio/agc_audio_stream.h @@ -73,10 +73,12 @@ class MEDIA_EXPORT AgcAudioStream : public AudioInterface { AgcAudioStream() : agc_is_enabled_(false), max_volume_(0.0), normalized_volume_(0.0) { + DVLOG(1) << __FUNCTION__; } virtual ~AgcAudioStream() { DCHECK(thread_checker_.CalledOnValidThread()); + DVLOG(1) << __FUNCTION__; } protected: @@ -85,6 +87,7 @@ class MEDIA_EXPORT AgcAudioStream : public AudioInterface { // The timer is only started if AGC mode is first enabled using the // SetAutomaticGainControl() method. void StartAgc() { + DVLOG(1) << "StartAgc()"; DCHECK(thread_checker_.CalledOnValidThread()); if (!agc_is_enabled_ || timer_.IsRunning()) return; @@ -102,6 +105,7 @@ class MEDIA_EXPORT AgcAudioStream : public AudioInterface { // Stops the periodic timer which periodically checks and updates the // current microphone volume level. void StopAgc() { + DVLOG(1) << "StopAgc()"; DCHECK(thread_checker_.CalledOnValidThread()); if (timer_.IsRunning()) timer_.Stop(); diff --git a/media/audio/alsa/alsa_input.cc b/media/audio/alsa/alsa_input.cc index 0bc9f31..9cde236 100644 --- a/media/audio/alsa/alsa_input.cc +++ b/media/audio/alsa/alsa_input.cc @@ -43,9 +43,7 @@ AlsaPcmInputStream::AlsaPcmInputStream(AudioManagerBase* audio_manager, mixer_handle_(NULL), mixer_element_handle_(NULL), read_callback_behind_schedule_(false), - audio_bus_(AudioBus::Create(params)), - weak_factory_(this) { -} + weak_factory_(this) {} AlsaPcmInputStream::~AlsaPcmInputStream() {} @@ -210,11 +208,8 @@ void AlsaPcmInputStream::ReadAudio() { int frames_read = wrapper_->PcmReadi(device_handle_, audio_buffer_.get(), params_.frames_per_buffer()); if (frames_read == params_.frames_per_buffer()) { - audio_bus_->FromInterleaved(audio_buffer_.get(), - audio_bus_->frames(), - params_.bits_per_sample() / 8); - callback_->OnData( - this, audio_bus_.get(), hardware_delay_bytes, normalized_volume); + callback_->OnData(this, audio_buffer_.get(), bytes_per_buffer_, + hardware_delay_bytes, normalized_volume); } else { LOG(WARNING) << "PcmReadi returning less than expected frames: " << frames_read << " vs. " << params_.frames_per_buffer() diff --git a/media/audio/alsa/alsa_input.h b/media/audio/alsa/alsa_input.h index c26f3e2..90c3883 100644 --- a/media/audio/alsa/alsa_input.h +++ b/media/audio/alsa/alsa_input.h @@ -82,7 +82,6 @@ class AlsaPcmInputStream : public AgcAudioStream<AudioInputStream> { snd_mixer_elem_t* mixer_element_handle_; // Handle to the capture element. scoped_ptr<uint8[]> audio_buffer_; // Buffer used for reading audio data. bool read_callback_behind_schedule_; - scoped_ptr<AudioBus> audio_bus_; // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory<AlsaPcmInputStream> weak_factory_; diff --git a/media/audio/android/audio_android_unittest.cc b/media/audio/android/audio_android_unittest.cc index a356d9c..06df7f0 100644 --- a/media/audio/android/audio_android_unittest.cc +++ b/media/audio/android/audio_android_unittest.cc @@ -148,9 +148,10 @@ std::ostream& operator<<(std::ostream& os, const AudioParameters& params) { // Gmock implementation of AudioInputStream::AudioInputCallback. class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { public: - MOCK_METHOD4(OnData, + MOCK_METHOD5(OnData, void(AudioInputStream* stream, - const AudioBus* src, + const uint8* src, + uint32 size, uint32 hardware_delay_bytes, double volume)); MOCK_METHOD1(OnError, void(AudioInputStream* stream)); @@ -263,19 +264,14 @@ class FileAudioSink : public AudioInputStream::AudioInputCallback { // AudioInputStream::AudioInputCallback implementation. virtual void OnData(AudioInputStream* stream, - const AudioBus* src, + const uint8* src, + uint32 size, uint32 hardware_delay_bytes, double volume) OVERRIDE { - const int num_samples = src->frames() * src->channels(); - scoped_ptr<int16> interleaved(new int16[num_samples]); - const int bytes_per_sample = sizeof(*interleaved); - src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); - // Store data data in a temporary buffer to avoid making blocking // fwrite() calls in the audio callback. The complete buffer will be // written to file in the destructor. - const int size = bytes_per_sample * num_samples; - if (!buffer_->Append((const uint8*)interleaved.get(), size)) + if (!buffer_->Append(src, size)) event_->Signal(); } @@ -311,19 +307,13 @@ class FullDuplexAudioSinkSource // AudioInputStream::AudioInputCallback implementation virtual void OnData(AudioInputStream* stream, - const AudioBus* src, + const uint8* src, + uint32 size, uint32 hardware_delay_bytes, double volume) OVERRIDE { const base::TimeTicks now_time = base::TimeTicks::Now(); const int diff = (now_time - previous_time_).InMilliseconds(); - EXPECT_EQ(params_.bits_per_sample(), 16); - const int num_samples = src->frames() * src->channels(); - scoped_ptr<int16> interleaved(new int16[num_samples]); - const int bytes_per_sample = sizeof(*interleaved); - src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); - const int size = bytes_per_sample * num_samples; - base::AutoLock lock(lock_); if (diff > 1000) { started_ = true; @@ -344,7 +334,7 @@ class FullDuplexAudioSinkSource // Append new data to the FIFO and extend the size if the max capacity // was exceeded. Flush the FIFO when extended just in case. - if (!fifo_->Append((const uint8*)interleaved.get(), size)) { + if (!fifo_->Append(src, size)) { fifo_->set_forward_capacity(2 * fifo_->forward_capacity()); fifo_->Clear(); } @@ -650,10 +640,14 @@ class AudioAndroidInputTest : public AudioAndroidOutputTest, int count = 0; MockAudioInputCallback sink; - EXPECT_CALL(sink, OnData(audio_input_stream_, NotNull(), _, _)) + EXPECT_CALL(sink, + OnData(audio_input_stream_, + NotNull(), + params. + GetBytesPerBuffer(), _, _)) .Times(AtLeast(num_callbacks)) .WillRepeatedly( - CheckCountAndPostQuitTask(&count, num_callbacks, loop())); + CheckCountAndPostQuitTask(&count, num_callbacks, loop())); EXPECT_CALL(sink, OnError(audio_input_stream_)).Times(0); OpenAndStartAudioInputStreamOnAudioThread(&sink); diff --git a/media/audio/android/audio_record_input.cc b/media/audio/android/audio_record_input.cc index 3f19588..583239d 100644 --- a/media/audio/android/audio_record_input.cc +++ b/media/audio/android/audio_record_input.cc @@ -7,18 +7,14 @@ #include "base/logging.h" #include "jni/AudioRecordInput_jni.h" #include "media/audio/android/audio_manager_android.h" -#include "media/base/audio_bus.h" namespace media { AudioRecordInputStream::AudioRecordInputStream( - AudioManagerAndroid* audio_manager, - const AudioParameters& params) + AudioManagerAndroid* audio_manager, const AudioParameters& params) : audio_manager_(audio_manager), callback_(NULL), - direct_buffer_address_(NULL), - audio_bus_(media::AudioBus::Create(params)), - bytes_per_sample_(params.bits_per_sample() / 8) { + direct_buffer_address_(NULL) { DVLOG(2) << __PRETTY_FUNCTION__; DCHECK(params.IsValid()); j_audio_record_.Reset( @@ -52,13 +48,10 @@ bool AudioRecordInputStream::RegisterAudioRecordInput(JNIEnv* env) { void AudioRecordInputStream::OnData(JNIEnv* env, jobject obj, jint size, jint hardware_delay_bytes) { DCHECK(direct_buffer_address_); - DCHECK_EQ(size, - audio_bus_->frames() * audio_bus_->channels() * bytes_per_sample_); // Passing zero as the volume parameter indicates there is no access to a // hardware volume slider. - audio_bus_->FromInterleaved( - direct_buffer_address_, audio_bus_->frames(), bytes_per_sample_); - callback_->OnData(this, audio_bus_.get(), hardware_delay_bytes, 0.0); + callback_->OnData(this, direct_buffer_address_, size, hardware_delay_bytes, + 0.0); } bool AudioRecordInputStream::Open() { diff --git a/media/audio/android/audio_record_input.h b/media/audio/android/audio_record_input.h index c240038..0a2578b 100644 --- a/media/audio/android/audio_record_input.h +++ b/media/audio/android/audio_record_input.h @@ -12,7 +12,6 @@ namespace media { -class AudioBus; class AudioManagerAndroid; // Implements PCM audio input support for Android using the Java AudioRecord @@ -65,9 +64,6 @@ class MEDIA_EXPORT AudioRecordInputStream : public AudioInputStream { // Owned by j_audio_record_. uint8* direct_buffer_address_; - scoped_ptr<media::AudioBus> audio_bus_; - int bytes_per_sample_; - DISALLOW_COPY_AND_ASSIGN(AudioRecordInputStream); }; diff --git a/media/audio/android/opensles_input.cc b/media/audio/android/opensles_input.cc index 1ef3aac..b927edb 100644 --- a/media/audio/android/opensles_input.cc +++ b/media/audio/android/opensles_input.cc @@ -7,7 +7,6 @@ #include "base/debug/trace_event.h" #include "base/logging.h" #include "media/audio/android/audio_manager_android.h" -#include "media/base/audio_bus.h" #define LOG_ON_FAILURE_AND_RETURN(op, ...) \ do { \ @@ -28,8 +27,7 @@ OpenSLESInputStream::OpenSLESInputStream(AudioManagerAndroid* audio_manager, simple_buffer_queue_(NULL), active_buffer_index_(0), buffer_size_bytes_(0), - started_(false), - audio_bus_(media::AudioBus::Create(params)) { + started_(false) { DVLOG(2) << __PRETTY_FUNCTION__; format_.formatType = SL_DATAFORMAT_PCM; format_.numChannels = static_cast<SLuint32>(params.channels()); @@ -297,14 +295,13 @@ void OpenSLESInputStream::ReadBufferQueue() { TRACE_EVENT0("audio", "OpenSLESOutputStream::ReadBufferQueue"); - // Convert from interleaved format to deinterleaved audio bus format. - audio_bus_->FromInterleaved(audio_data_[active_buffer_index_], - audio_bus_->frames(), - format_.bitsPerSample / 8); - // TODO(henrika): Investigate if it is possible to get an accurate // delay estimation. - callback_->OnData(this, audio_bus_.get(), buffer_size_bytes_, 0.0); + callback_->OnData(this, + audio_data_[active_buffer_index_], + buffer_size_bytes_, + buffer_size_bytes_, + 0.0); // Done with this buffer. Send it to device for recording. SLresult err = diff --git a/media/audio/android/opensles_input.h b/media/audio/android/opensles_input.h index 288ab43..cb07d51 100644 --- a/media/audio/android/opensles_input.h +++ b/media/audio/android/opensles_input.h @@ -17,7 +17,6 @@ namespace media { -class AudioBus; class AudioManagerAndroid; // Implements PCM audio input support for Android using the OpenSLES API. @@ -95,8 +94,6 @@ class OpenSLESInputStream : public AudioInputStream { bool started_; - scoped_ptr<media::AudioBus> audio_bus_; - DISALLOW_COPY_AND_ASSIGN(OpenSLESInputStream); }; diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc index 490c62b..e74b0a1e 100644 --- a/media/audio/audio_input_controller.cc +++ b/media/audio/audio_input_controller.cc @@ -202,6 +202,7 @@ void AudioInputController::DoCreate(AudioManager* audio_manager, audio_level_.reset(new media::AudioPowerMonitor( params.sample_rate(), TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMilliseconds))); + audio_bus_ = AudioBus::Create(params); audio_params_ = params; #endif @@ -382,7 +383,8 @@ void AudioInputController::DoCheckForNoData() { } void AudioInputController::OnData(AudioInputStream* stream, - const AudioBus* source, + const uint8* data, + uint32 size, uint32 hardware_delay_bytes, double volume) { // Mark data as active to ensure that the periodic calls to @@ -406,7 +408,7 @@ void AudioInputController::OnData(AudioInputStream* stream, // Use SharedMemory and SyncSocket if the client has created a SyncWriter. // Used by all low-latency clients except WebSpeech. if (SharedMemoryAndSyncSocketMode()) { - sync_writer_->Write(source, volume, key_pressed); + sync_writer_->Write(data, size, volume, key_pressed); sync_writer_->UpdateRecordedBytes(hardware_delay_bytes); #if defined(AUDIO_POWER_MONITORING) @@ -422,7 +424,9 @@ void AudioInputController::OnData(AudioInputStream* stream, // Wrap data into an AudioBus to match AudioPowerMonitor::Scan. // TODO(henrika): remove this section when capture side uses AudioBus. // See http://crbug.com/375155 for details. - audio_level_->Scan(*source, source->frames()); + audio_bus_->FromInterleaved( + data, audio_bus_->frames(), audio_params_.bits_per_sample() / 8); + audio_level_->Scan(*audio_bus_, audio_bus_->frames()); // Get current average power level and add it to the log. // Possible range is given by [-inf, 0] dBFS. @@ -441,28 +445,26 @@ void AudioInputController::OnData(AudioInputStream* stream, audio_level_->Reset(); } #endif + return; } // TODO(henrika): Investigate if we can avoid the extra copy here. // (see http://crbug.com/249316 for details). AFAIK, this scope is only // active for WebSpeech clients. - scoped_ptr<AudioBus> audio_data = - AudioBus::Create(source->channels(), source->frames()); - source->CopyTo(audio_data.get()); + scoped_ptr<uint8[]> audio_data(new uint8[size]); + memcpy(audio_data.get(), data, size); // Ownership of the audio buffer will be with the callback until it is run, // when ownership is passed to the callback function. - task_runner_->PostTask( - FROM_HERE, - base::Bind( - &AudioInputController::DoOnData, this, base::Passed(&audio_data))); + task_runner_->PostTask(FROM_HERE, base::Bind( + &AudioInputController::DoOnData, this, base::Passed(&audio_data), size)); } -void AudioInputController::DoOnData(scoped_ptr<AudioBus> data) { +void AudioInputController::DoOnData(scoped_ptr<uint8[]> data, uint32 size) { DCHECK(task_runner_->BelongsToCurrentThread()); if (handler_) - handler_->OnData(this, data.get()); + handler_->OnData(this, data.get(), size); } void AudioInputController::DoLogAudioLevel(float level_dbfs) { diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h index f2771c7..35ec1b7 100644 --- a/media/audio/audio_input_controller.h +++ b/media/audio/audio_input_controller.h @@ -117,8 +117,8 @@ class MEDIA_EXPORT AudioInputController virtual void OnRecording(AudioInputController* controller) = 0; virtual void OnError(AudioInputController* controller, ErrorCode error_code) = 0; - virtual void OnData(AudioInputController* controller, - const AudioBus* data) = 0; + virtual void OnData(AudioInputController* controller, const uint8* data, + uint32 size) = 0; virtual void OnLog(AudioInputController* controller, const std::string& message) = 0; @@ -136,10 +136,12 @@ class MEDIA_EXPORT AudioInputController // soundcard which has been recorded. virtual void UpdateRecordedBytes(uint32 bytes) = 0; - // Write certain amount of data from |data|. - virtual void Write(const AudioBus* data, - double volume, - bool key_pressed) = 0; + // Write certain amount of data from |data|. This method returns + // number of written bytes. + virtual uint32 Write(const void* data, + uint32 size, + double volume, + bool key_pressed) = 0; // Close this synchronous writer. virtual void Close() = 0; @@ -228,10 +230,8 @@ class MEDIA_EXPORT AudioInputController // AudioInputCallback implementation. Threading details depends on the // device-specific implementation. - virtual void OnData(AudioInputStream* stream, - const AudioBus* source, - uint32 hardware_delay_bytes, - double volume) OVERRIDE; + virtual void OnData(AudioInputStream* stream, const uint8* src, uint32 size, + uint32 hardware_delay_bytes, double volume) OVERRIDE; virtual void OnError(AudioInputStream* stream) OVERRIDE; bool SharedMemoryAndSyncSocketMode() const { return sync_writer_ != NULL; } @@ -261,7 +261,7 @@ class MEDIA_EXPORT AudioInputController void DoReportError(); void DoSetVolume(double volume); void DoSetAutomaticGainControl(bool enabled); - void DoOnData(scoped_ptr<AudioBus> data); + void DoOnData(scoped_ptr<uint8[]> data, uint32 size); void DoLogAudioLevel(float level_dbfs); // Method to check if we get recorded data after a stream was started, @@ -325,6 +325,7 @@ class MEDIA_EXPORT AudioInputController scoped_ptr<AudioPowerMonitor> audio_level_; // We need these to be able to feed data to the AudioPowerMonitor. + scoped_ptr<AudioBus> audio_bus_; media::AudioParameters audio_params_; base::TimeTicks last_audio_level_log_time_; #endif diff --git a/media/audio/audio_input_controller_unittest.cc b/media/audio/audio_input_controller_unittest.cc index e71232d..4e11e35 100644 --- a/media/audio/audio_input_controller_unittest.cc +++ b/media/audio/audio_input_controller_unittest.cc @@ -53,8 +53,8 @@ class MockAudioInputControllerEventHandler MOCK_METHOD1(OnRecording, void(AudioInputController* controller)); MOCK_METHOD2(OnError, void(AudioInputController* controller, AudioInputController::ErrorCode error_code)); - MOCK_METHOD2(OnData, - void(AudioInputController* controller, const AudioBus* data)); + MOCK_METHOD3(OnData, void(AudioInputController* controller, + const uint8* data, uint32 size)); MOCK_METHOD2(OnLog, void(AudioInputController* controller, const std::string& message)); @@ -117,10 +117,10 @@ TEST_F(AudioInputControllerTest, RecordAndClose) { .Times(Exactly(1)); // OnData() shall be called ten times. - EXPECT_CALL(event_handler, OnData(NotNull(), NotNull())) + EXPECT_CALL(event_handler, OnData(NotNull(), NotNull(), _)) .Times(AtLeast(10)) - .WillRepeatedly(CheckCountAndPostQuitTask( - &count, 10, message_loop_.message_loop_proxy())); + .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, + message_loop_.message_loop_proxy())); scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); AudioParameters params(AudioParameters::AUDIO_FAKE, kChannelLayout, @@ -163,10 +163,10 @@ TEST_F(AudioInputControllerTest, DISABLED_RecordAndError) { .Times(Exactly(1)); // OnData() shall be called ten times. - EXPECT_CALL(event_handler, OnData(NotNull(), NotNull())) + EXPECT_CALL(event_handler, OnData(NotNull(), NotNull(), _)) .Times(AtLeast(10)) - .WillRepeatedly(CheckCountAndPostQuitTask( - &count, 10, message_loop_.message_loop_proxy())); + .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, + message_loop_.message_loop_proxy())); // OnError() will be called after the data stream stops while the // controller is in a recording state. diff --git a/media/audio/audio_input_device.cc b/media/audio/audio_input_device.cc index bf140cb..f57284c 100644 --- a/media/audio/audio_input_device.cc +++ b/media/audio/audio_input_device.cc @@ -6,7 +6,6 @@ #include "base/basictypes.h" #include "base/bind.h" -#include "base/memory/scoped_vector.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "media/audio/audio_manager_base.h" @@ -40,9 +39,8 @@ class AudioInputDevice::AudioThreadCallback private: int current_segment_id_; - ScopedVector<media::AudioBus> audio_buses_; CaptureCallback* capture_callback_; - + scoped_ptr<AudioBus> audio_bus_; DISALLOW_COPY_AND_ASSIGN(AudioThreadCallback); }; @@ -275,6 +273,7 @@ AudioInputDevice::AudioThreadCallback::AudioThreadCallback( total_segments), current_segment_id_(0), capture_callback_(capture_callback) { + audio_bus_ = AudioBus::Create(audio_parameters_); } AudioInputDevice::AudioThreadCallback::~AudioThreadCallback() { @@ -282,17 +281,6 @@ AudioInputDevice::AudioThreadCallback::~AudioThreadCallback() { void AudioInputDevice::AudioThreadCallback::MapSharedMemory() { shared_memory_.Map(memory_length_); - - // Create vector of audio buses by wrapping existing blocks of memory. - uint8* ptr = static_cast<uint8*>(shared_memory_.memory()); - for (int i = 0; i < total_segments_; ++i) { - media::AudioInputBuffer* buffer = - reinterpret_cast<media::AudioInputBuffer*>(ptr); - scoped_ptr<media::AudioBus> audio_bus = - media::AudioBus::WrapMemory(audio_parameters_, buffer->audio); - audio_buses_.push_back(audio_bus.release()); - ptr += segment_length_; - } } void AudioInputDevice::AudioThreadCallback::Process(int pending_data) { @@ -309,17 +297,21 @@ void AudioInputDevice::AudioThreadCallback::Process(int pending_data) { double volume = buffer->params.volume; bool key_pressed = buffer->params.key_pressed; - // Use pre-allocated audio bus wrapping existing block of shared memory. - media::AudioBus* audio_bus = audio_buses_[current_segment_id_]; - - // Deliver captured data to the client in floating point format - // and update the audio-delay measurement. int audio_delay_milliseconds = pending_data / bytes_per_ms_; - capture_callback_->Capture( - audio_bus, audio_delay_milliseconds, volume, key_pressed); + int16* memory = reinterpret_cast<int16*>(&buffer->audio[0]); + const int bytes_per_sample = sizeof(memory[0]); if (++current_segment_id_ >= total_segments_) current_segment_id_ = 0; + + // Deinterleave each channel and convert to 32-bit floating-point + // with nominal range -1.0 -> +1.0. + audio_bus_->FromInterleaved(memory, audio_bus_->frames(), bytes_per_sample); + + // Deliver captured data to the client in floating point format + // and update the audio-delay measurement. + capture_callback_->Capture( + audio_bus_.get(), audio_delay_milliseconds, volume, key_pressed); } } // namespace media diff --git a/media/audio/audio_input_unittest.cc b/media/audio/audio_input_unittest.cc index 0bae9db..f972e44 100644 --- a/media/audio/audio_input_unittest.cc +++ b/media/audio/audio_input_unittest.cc @@ -24,7 +24,8 @@ class TestInputCallback : public AudioInputStream::AudioInputCallback { had_error_(0) { } virtual void OnData(AudioInputStream* stream, - const AudioBus* source, + const uint8* data, + uint32 size, uint32 hardware_delay_bytes, double volume) OVERRIDE { ++callback_count_; diff --git a/media/audio/audio_io.h b/media/audio/audio_io.h index d445584..f6151e0 100644 --- a/media/audio/audio_io.h +++ b/media/audio/audio_io.h @@ -109,9 +109,8 @@ class MEDIA_EXPORT AudioInputStream { // Called by the audio recorder when a full packet of audio data is // available. This is called from a special audio thread and the // implementation should return as soon as possible. - virtual void OnData(AudioInputStream* stream, - const AudioBus* source, - uint32 hardware_delay_bytes, + virtual void OnData(AudioInputStream* stream, const uint8* src, + uint32 size, uint32 hardware_delay_bytes, double volume) = 0; // There was an error while recording audio. The audio sink cannot be diff --git a/media/audio/audio_low_latency_input_output_unittest.cc b/media/audio/audio_low_latency_input_output_unittest.cc index eefd380..2ae700a 100644 --- a/media/audio/audio_low_latency_input_output_unittest.cc +++ b/media/audio/audio_low_latency_input_output_unittest.cc @@ -184,7 +184,7 @@ class FullDuplexAudioSinkSource // AudioInputStream::AudioInputCallback. virtual void OnData(AudioInputStream* stream, - const AudioBus* src, + const uint8* src, uint32 size, uint32 hardware_delay_bytes, double volume) OVERRIDE { base::AutoLock lock(lock_); @@ -203,15 +203,14 @@ class FullDuplexAudioSinkSource ++input_elements_to_write_; } - // TODO(henrika): fix this and use AudioFifo instead. // Store the captured audio packet in a seekable media buffer. - // if (!buffer_->Append(src, size)) { - // An attempt to write outside the buffer limits has been made. - // Double the buffer capacity to ensure that we have a buffer large - // enough to handle the current sample test scenario. - // buffer_->set_forward_capacity(2 * buffer_->forward_capacity()); - // buffer_->Clear(); - // } + if (!buffer_->Append(src, size)) { + // An attempt to write outside the buffer limits has been made. + // Double the buffer capacity to ensure that we have a buffer large + // enough to handle the current sample test scenario. + buffer_->set_forward_capacity(2 * buffer_->forward_capacity()); + buffer_->Clear(); + } } virtual void OnError(AudioInputStream* stream) OVERRIDE {} diff --git a/media/audio/cras/cras_input.cc b/media/audio/cras/cras_input.cc index 6085947..0181d88 100644 --- a/media/audio/cras/cras_input.cc +++ b/media/audio/cras/cras_input.cc @@ -27,7 +27,6 @@ CrasInputStream::CrasInputStream(const AudioParameters& params, stream_direction_(device_id == AudioManagerBase::kLoopbackInputDeviceId ? CRAS_STREAM_POST_MIX_PRE_DSP : CRAS_STREAM_INPUT) { DCHECK(audio_manager_); - audio_bus_ = AudioBus::Create(params_); } CrasInputStream::~CrasInputStream() { @@ -223,11 +222,8 @@ void CrasInputStream::ReadAudio(size_t frames, double normalized_volume = 0.0; GetAgcVolume(&normalized_volume); - audio_bus_->FromInterleaved(buffer, - audio_bus_->frames(), - params_.bits_per_sample() / 8); callback_->OnData(this, - audio_bus_.get(), + buffer, frames * bytes_per_frame_, bytes_latency, normalized_volume); diff --git a/media/audio/cras/cras_input.h b/media/audio/cras/cras_input.h index 1919224..36bf9b1 100644 --- a/media/audio/cras/cras_input.h +++ b/media/audio/cras/cras_input.h @@ -98,8 +98,6 @@ class CrasInputStream : public AgcAudioStream<AudioInputStream> { // Direction of the stream. const CRAS_STREAM_DIRECTION stream_direction_; - scoped_ptr<AudioBus> audio_bus_; - DISALLOW_COPY_AND_ASSIGN(CrasInputStream); }; diff --git a/media/audio/cras/cras_input_unittest.cc b/media/audio/cras/cras_input_unittest.cc index eed679a..77f951c 100644 --- a/media/audio/cras/cras_input_unittest.cc +++ b/media/audio/cras/cras_input_unittest.cc @@ -28,8 +28,8 @@ namespace media { class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { public: - MOCK_METHOD4(OnData, void( - AudioInputStream*, const AudioBus*, uint32, double)); + MOCK_METHOD5(OnData, void( + AudioInputStream*, const uint8*, uint32, uint32, double)); MOCK_METHOD1(OnError, void(AudioInputStream*)); }; @@ -85,10 +85,14 @@ class CrasInputStreamTest : public testing::Test { // samples can be provided when doing non-integer SRC. For example // converting from 192k to 44.1k is a ratio of 4.35 to 1. MockAudioInputCallback mock_callback; + unsigned int expected_size = (kTestFramesPerPacket - 8) * + params.channels() * + params.bits_per_sample() / 8; + base::WaitableEvent event(false, false); EXPECT_CALL(mock_callback, - OnData(test_stream, _, _, _)) + OnData(test_stream, _, Ge(expected_size), _, _)) .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)); test_stream->Start(&mock_callback); diff --git a/media/audio/fake_audio_input_stream.cc b/media/audio/fake_audio_input_stream.cc index 384adcb..e05b257 100644 --- a/media/audio/fake_audio_input_stream.cc +++ b/media/audio/fake_audio_input_stream.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/lazy_instance.h" #include "media/audio/audio_manager_base.h" -#include "media/base/audio_bus.h" using base::TimeTicks; using base::TimeDelta; @@ -49,20 +48,17 @@ FakeAudioInputStream::FakeAudioInputStream(AudioManagerBase* manager, : audio_manager_(manager), callback_(NULL), buffer_size_((params.channels() * params.bits_per_sample() * - params.frames_per_buffer()) / - 8), + params.frames_per_buffer()) / 8), params_(params), thread_("FakeAudioRecordingThread"), callback_interval_(base::TimeDelta::FromMilliseconds( (params.frames_per_buffer() * 1000) / params.sample_rate())), - beep_duration_in_buffers_(kBeepDurationMilliseconds * - params.sample_rate() / - params.frames_per_buffer() / - 1000), + beep_duration_in_buffers_( + kBeepDurationMilliseconds * params.sample_rate() / + params.frames_per_buffer() / 1000), beep_generated_in_buffers_(0), beep_period_in_frames_(params.sample_rate() / kBeepFrequency), - frames_elapsed_(0), - audio_bus_(AudioBus::Create(params)) { + frames_elapsed_(0) { } FakeAudioInputStream::~FakeAudioInputStream() {} @@ -70,7 +66,6 @@ FakeAudioInputStream::~FakeAudioInputStream() {} bool FakeAudioInputStream::Open() { buffer_.reset(new uint8[buffer_size_]); memset(buffer_.get(), 0, buffer_size_); - audio_bus_->Zero(); return true; } @@ -146,9 +141,7 @@ void FakeAudioInputStream::DoCallback() { beep_generated_in_buffers_ = 0; } - audio_bus_->FromInterleaved( - buffer_.get(), audio_bus_->frames(), params_.bits_per_sample() / 8); - callback_->OnData(this, audio_bus_.get(), buffer_size_, 1.0); + callback_->OnData(this, buffer_.get(), buffer_size_, buffer_size_, 1.0); frames_elapsed_ += params_.frames_per_buffer(); thread_.message_loop()->PostDelayedTask( diff --git a/media/audio/fake_audio_input_stream.h b/media/audio/fake_audio_input_stream.h index e6c625e..8dc2427 100644 --- a/media/audio/fake_audio_input_stream.h +++ b/media/audio/fake_audio_input_stream.h @@ -18,7 +18,6 @@ namespace media { -class AudioBus; class AudioManagerBase; class MEDIA_EXPORT FakeAudioInputStream @@ -69,7 +68,6 @@ class MEDIA_EXPORT FakeAudioInputStream int beep_generated_in_buffers_; int beep_period_in_frames_; int frames_elapsed_; - scoped_ptr<media::AudioBus> audio_bus_; DISALLOW_COPY_AND_ASSIGN(FakeAudioInputStream); }; diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc index b7f6e17..94dc944 100644 --- a/media/audio/mac/audio_input_mac.cc +++ b/media/audio/mac/audio_input_mac.cc @@ -10,19 +10,16 @@ #include "base/logging.h" #include "base/mac/mac_logging.h" #include "media/audio/mac/audio_manager_mac.h" -#include "media/base/audio_bus.h" namespace media { PCMQueueInAudioInputStream::PCMQueueInAudioInputStream( - AudioManagerMac* manager, - const AudioParameters& params) + AudioManagerMac* manager, const AudioParameters& params) : manager_(manager), callback_(NULL), audio_queue_(NULL), buffer_size_bytes_(0), - started_(false), - audio_bus_(media::AudioBus::Create(params)) { + started_(false) { // We must have a manager. DCHECK(manager_); // A frame is one sample across all channels. In interleaved audio the per @@ -218,11 +215,11 @@ void PCMQueueInAudioInputStream::HandleInputBuffer( if (elapsed < kMinDelay) base::PlatformThread::Sleep(kMinDelay - elapsed); - uint8* audio_data = reinterpret_cast<uint8*>(audio_buffer->mAudioData); - audio_bus_->FromInterleaved( - audio_data, audio_bus_->frames(), format_.mBitsPerChannel / 8); - callback_->OnData( - this, audio_bus_.get(), audio_buffer->mAudioDataByteSize, 0.0); + callback_->OnData(this, + reinterpret_cast<const uint8*>(audio_buffer->mAudioData), + audio_buffer->mAudioDataByteSize, + audio_buffer->mAudioDataByteSize, + 0.0); last_fill_ = base::TimeTicks::Now(); } diff --git a/media/audio/mac/audio_input_mac.h b/media/audio/mac/audio_input_mac.h index a6e897e..e8f77c7 100644 --- a/media/audio/mac/audio_input_mac.h +++ b/media/audio/mac/audio_input_mac.h @@ -16,7 +16,6 @@ namespace media { -class AudioBus; class AudioManagerMac; // Implementation of AudioInputStream for Mac OS X using the audio queue service @@ -84,8 +83,6 @@ class PCMQueueInAudioInputStream : public AudioInputStream { // Used to defer Start() to workaround http://crbug.com/160920. base::CancelableClosure deferred_start_cb_; - scoped_ptr<media::AudioBus> audio_bus_; - DISALLOW_COPY_AND_ASSIGN(PCMQueueInAudioInputStream); }; diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc index d7a3430..bf93358 100644 --- a/media/audio/mac/audio_low_latency_input_mac.cc +++ b/media/audio/mac/audio_low_latency_input_mac.cc @@ -10,7 +10,6 @@ #include "base/logging.h" #include "base/mac/mac_logging.h" #include "media/audio/mac/audio_manager_mac.h" -#include "media/base/audio_bus.h" #include "media/base/data_buffer.h" namespace media { @@ -32,10 +31,11 @@ static std::ostream& operator<<(std::ostream& os, // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html // for more details and background regarding this implementation. -AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager, - const AudioParameters& input_params, - const AudioParameters& output_params, - AudioDeviceID audio_device_id) +AUAudioInputStream::AUAudioInputStream( + AudioManagerMac* manager, + const AudioParameters& input_params, + const AudioParameters& output_params, + AudioDeviceID audio_device_id) : manager_(manager), sink_(NULL), audio_unit_(0), @@ -43,8 +43,7 @@ AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager, started_(false), hardware_latency_frames_(0), fifo_delay_bytes_(0), - number_of_channels_in_frame_(0), - audio_bus_(media::AudioBus::Create(input_params)) { + number_of_channels_in_frame_(0) { DCHECK(manager_); // Set up the desired (output) format specified by the client. @@ -543,13 +542,12 @@ OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames, // Read from FIFO into temporary data buffer. fifo_->Read(data_->writable_data(), requested_size_bytes_); - // Copy captured (and interleaved) data into deinterleaved audio bus. - audio_bus_->FromInterleaved( - data_->data(), audio_bus_->frames(), format_.mBitsPerChannel / 8); - // Deliver data packet, delay estimation and volume level to the user. - sink_->OnData( - this, audio_bus_.get(), capture_delay_bytes, normalized_volume); + sink_->OnData(this, + data_->data(), + requested_size_bytes_, + 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 7726227..ae0c405 100644 --- a/media/audio/mac/audio_low_latency_input_mac.h +++ b/media/audio/mac/audio_low_latency_input_mac.h @@ -49,7 +49,6 @@ namespace media { -class AudioBus; class AudioManagerMac; class DataBuffer; @@ -166,10 +165,6 @@ class AUAudioInputStream : public AgcAudioStream<AudioInputStream> { // Used to defer Start() to workaround http://crbug.com/160920. base::CancelableClosure deferred_start_cb_; - // Extra audio bus used for storage of deinterleaved data for the OnData - // callback. - scoped_ptr<media::AudioBus> audio_bus_; - DISALLOW_COPY_AND_ASSIGN(AUAudioInputStream); }; diff --git a/media/audio/mac/audio_low_latency_input_mac_unittest.cc b/media/audio/mac/audio_low_latency_input_mac_unittest.cc index 79721d4..fdd7c05 100644 --- a/media/audio/mac/audio_low_latency_input_mac_unittest.cc +++ b/media/audio/mac/audio_low_latency_input_mac_unittest.cc @@ -31,11 +31,9 @@ ACTION_P4(CheckCountAndPostQuitTask, count, limit, loop, closure) { class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { public: - MOCK_METHOD4(OnData, - void(AudioInputStream* stream, - const AudioBus* src, - uint32 hardware_delay_bytes, - double volume)); + MOCK_METHOD5(OnData, void(AudioInputStream* stream, + const uint8* src, uint32 size, + uint32 hardware_delay_bytes, double volume)); MOCK_METHOD1(OnError, void(AudioInputStream* stream)); }; @@ -76,19 +74,12 @@ class WriteToFileAudioSink : public AudioInputStream::AudioInputCallback { // AudioInputStream::AudioInputCallback implementation. virtual void OnData(AudioInputStream* stream, - const AudioBus* src, - uint32 hardware_delay_bytes, - double volume) OVERRIDE { - const int num_samples = src->frames() * src->channels(); - scoped_ptr<int16> interleaved(new int16[num_samples]); - const int bytes_per_sample = sizeof(*interleaved); - src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); - + const uint8* src, uint32 size, + uint32 hardware_delay_bytes, double volume) OVERRIDE { // Store data data in a temporary buffer to avoid making blocking // fwrite() calls in the audio callback. The complete buffer will be // written to file in the destructor. - const int size = bytes_per_sample * num_samples; - if (buffer_.Append((const uint8*)interleaved.get(), size)) { + if (buffer_.Append(src, size)) { bytes_to_write_ += size; } } @@ -233,13 +224,18 @@ TEST_F(MacAudioInputTest, AUAudioInputStreamVerifyMonoRecording) { AudioInputStream* ais = CreateAudioInputStream(CHANNEL_LAYOUT_MONO); EXPECT_TRUE(ais->Open()); + int fs = static_cast<int>(AUAudioInputStream::HardwareSampleRate()); + int samples_per_packet = fs / 100; + int bits_per_sample = 16; + uint32 bytes_per_packet = samples_per_packet * (bits_per_sample / 8); + MockAudioInputCallback sink; // We use 10ms packets and will run the test until ten packets are received. // All should contain valid packets of the same size and a valid delay // estimate. base::RunLoop run_loop; - EXPECT_CALL(sink, OnData(ais, NotNull(), _, _)) + EXPECT_CALL(sink, OnData(ais, NotNull(), bytes_per_packet, _, _)) .Times(AtLeast(10)) .WillRepeatedly(CheckCountAndPostQuitTask( &count, 10, &message_loop_, run_loop.QuitClosure())); @@ -260,6 +256,11 @@ TEST_F(MacAudioInputTest, AUAudioInputStreamVerifyStereoRecording) { AudioInputStream* ais = CreateAudioInputStream(CHANNEL_LAYOUT_STEREO); EXPECT_TRUE(ais->Open()); + int fs = static_cast<int>(AUAudioInputStream::HardwareSampleRate()); + int samples_per_packet = fs / 100; + int bits_per_sample = 16; + uint32 bytes_per_packet = 2 * samples_per_packet * (bits_per_sample / 8); + MockAudioInputCallback sink; // We use 10ms packets and will run the test until ten packets are received. @@ -273,7 +274,7 @@ TEST_F(MacAudioInputTest, AUAudioInputStreamVerifyStereoRecording) { // ensure that we can land the patch but will revisit this test again when // more analysis of the delay estimates are done. base::RunLoop run_loop; - EXPECT_CALL(sink, OnData(ais, NotNull(), _, _)) + EXPECT_CALL(sink, OnData(ais, NotNull(), bytes_per_packet, _, _)) .Times(AtLeast(10)) .WillRepeatedly(CheckCountAndPostQuitTask( &count, 10, &message_loop_, run_loop.QuitClosure())); diff --git a/media/audio/pulse/pulse_input.cc b/media/audio/pulse/pulse_input.cc index d5cb94ec..9d31cdd 100644 --- a/media/audio/pulse/pulse_input.cc +++ b/media/audio/pulse/pulse_input.cc @@ -34,8 +34,6 @@ PulseAudioInputStream::PulseAudioInputStream(AudioManagerPulse* audio_manager, context_state_changed_(false) { DCHECK(mainloop); DCHECK(context); - CHECK(params_.IsValid()); - audio_bus_ = AudioBus::Create(params_); } PulseAudioInputStream::~PulseAudioInputStream() { @@ -274,11 +272,8 @@ void PulseAudioInputStream::ReadData() { 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); + callback_->OnData(this, audio_data_buffer_.get(), packet_size, + hardware_delay, normalized_volume); if (buffer_->forward_bytes() < packet_size) break; diff --git a/media/audio/pulse/pulse_input.h b/media/audio/pulse/pulse_input.h index 7e64bb2..7566eac 100644 --- a/media/audio/pulse/pulse_input.h +++ b/media/audio/pulse/pulse_input.h @@ -75,8 +75,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); diff --git a/media/audio/pulse/pulse_output.cc b/media/audio/pulse/pulse_output.cc index 19fc47b..a67ee7f 100644 --- a/media/audio/pulse/pulse_output.cc +++ b/media/audio/pulse/pulse_output.cc @@ -49,6 +49,8 @@ PulseAudioOutputStream::PulseAudioOutputStream(const AudioParameters& params, pa_stream_(NULL), volume_(1.0f), source_callback_(NULL) { + DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); + CHECK(params_.IsValid()); audio_bus_ = AudioBus::Create(params_); } @@ -62,7 +64,7 @@ PulseAudioOutputStream::~PulseAudioOutputStream() { } bool PulseAudioOutputStream::Open() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); return pulse::CreateOutputStream(&pa_mainloop_, &pa_context_, &pa_stream_, params_, device_id_, &StreamNotifyCallback, &StreamRequestCallback, this); @@ -107,7 +109,7 @@ void PulseAudioOutputStream::Reset() { } void PulseAudioOutputStream::Close() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); Reset(); @@ -157,7 +159,7 @@ void PulseAudioOutputStream::FulfillWriteRequest(size_t requested_bytes) { } void PulseAudioOutputStream::Start(AudioSourceCallback* callback) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); CHECK(callback); CHECK(pa_stream_); @@ -179,7 +181,7 @@ void PulseAudioOutputStream::Start(AudioSourceCallback* callback) { } void PulseAudioOutputStream::Stop() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); // Cork (pause) the stream. Waiting for the main loop lock will ensure // outstanding callbacks have completed. @@ -202,13 +204,13 @@ void PulseAudioOutputStream::Stop() { } void PulseAudioOutputStream::SetVolume(double volume) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); volume_ = static_cast<float>(volume); } void PulseAudioOutputStream::GetVolume(double* volume) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread()); *volume = volume_; } diff --git a/media/audio/pulse/pulse_output.h b/media/audio/pulse/pulse_output.h index e1c0045..437e28c 100644 --- a/media/audio/pulse/pulse_output.h +++ b/media/audio/pulse/pulse_output.h @@ -23,7 +23,6 @@ #include <string> #include "base/memory/scoped_ptr.h" -#include "base/threading/thread_checker.h" #include "media/audio/audio_io.h" #include "media/audio/audio_parameters.h" @@ -91,8 +90,6 @@ class PulseAudioOutputStream : public AudioOutputStream { // Container for retrieving data from AudioSourceCallback::OnMoreData(). scoped_ptr<AudioBus> audio_bus_; - base::ThreadChecker thread_checker_; - DISALLOW_COPY_AND_ASSIGN(PulseAudioOutputStream); }; diff --git a/media/audio/virtual_audio_input_stream.cc b/media/audio/virtual_audio_input_stream.cc index f660b9c..f632d3b 100644 --- a/media/audio/virtual_audio_input_stream.cc +++ b/media/audio/virtual_audio_input_stream.cc @@ -139,7 +139,14 @@ void VirtualAudioInputStream::PumpAudio(AudioBus* audio_bus) { base::AutoLock scoped_lock(converter_network_lock_); mixer_.Convert(audio_bus); } - callback_->OnData(this, audio_bus, params_.GetBytesPerBuffer(), 1.0); + audio_bus->ToInterleaved(params_.frames_per_buffer(), + params_.bits_per_sample() / 8, + buffer_.get()); + callback_->OnData(this, + buffer_.get(), + params_.GetBytesPerBuffer(), + params_.GetBytesPerBuffer(), + 1.0); } void VirtualAudioInputStream::Close() { diff --git a/media/audio/virtual_audio_input_stream_unittest.cc b/media/audio/virtual_audio_input_stream_unittest.cc index 3aa87b0..07c4948 100644 --- a/media/audio/virtual_audio_input_stream_unittest.cc +++ b/media/audio/virtual_audio_input_stream_unittest.cc @@ -32,17 +32,16 @@ class MockInputCallback : public AudioInputStream::AudioInputCallback { public: MockInputCallback() : data_pushed_(false, false) { - ON_CALL(*this, OnData(_, _, _, _)).WillByDefault( - InvokeWithoutArgs(&data_pushed_, &base::WaitableEvent::Signal)); + ON_CALL(*this, OnData(_, _, _, _, _)) + .WillByDefault(InvokeWithoutArgs(&data_pushed_, + &base::WaitableEvent::Signal)); } virtual ~MockInputCallback() {} - MOCK_METHOD4(OnData, - void(AudioInputStream* stream, - const AudioBus* source, - uint32 hardware_delay_bytes, - double volume)); + MOCK_METHOD5(OnData, void(AudioInputStream* stream, const uint8* data, + uint32 size, uint32 hardware_delay_bytes, + double volume)); MOCK_METHOD1(OnError, void(AudioInputStream* stream)); void WaitForDataPushes() { @@ -114,7 +113,8 @@ class VirtualAudioInputStreamTest : public testing::TestWithParam<bool> { } void Start() { - EXPECT_CALL(input_callback_, OnData(_, NotNull(), _, _)).Times(AtLeast(1)); + EXPECT_CALL(input_callback_, OnData(_, NotNull(), _, _, _)) + .Times(AtLeast(1)); ASSERT_TRUE(!!stream_); stream_->Start(&input_callback_); diff --git a/media/audio/win/audio_low_latency_input_win.cc b/media/audio/win/audio_low_latency_input_win.cc index c43ed22..0219ca4 100644 --- a/media/audio/win/audio_low_latency_input_win.cc +++ b/media/audio/win/audio_low_latency_input_win.cc @@ -9,7 +9,6 @@ #include "base/strings/utf_string_conversions.h" #include "media/audio/win/audio_manager_win.h" #include "media/audio/win/avrt_wrapper_win.h" -#include "media/base/audio_bus.h" using base::win::ScopedComPtr; using base::win::ScopedCOMInitializer; @@ -34,9 +33,10 @@ bool IsDefaultCommunicationDevice(IMMDeviceEnumerator* enumerator, } // namespace -WASAPIAudioInputStream::WASAPIAudioInputStream(AudioManagerWin* manager, - const AudioParameters& params, - const std::string& device_id) +WASAPIAudioInputStream::WASAPIAudioInputStream( + AudioManagerWin* manager, + const AudioParameters& params, + const std::string& device_id) : manager_(manager), capture_thread_(NULL), opened_(false), @@ -49,8 +49,7 @@ WASAPIAudioInputStream::WASAPIAudioInputStream(AudioManagerWin* manager, device_id_(device_id), perf_count_to_100ns_units_(0.0), ms_to_frame_count_(0.0), - sink_(NULL), - audio_bus_(media::AudioBus::Create(params)) { + sink_(NULL) { DCHECK(manager_); // Load the Avrt DLL if not already loaded. Required to support MMCSS. @@ -437,15 +436,16 @@ void WASAPIAudioInputStream::Run() { // size which was specified at construction. uint32 delay_frames = static_cast<uint32>(audio_delay_frames + 0.5); while (buffer_frame_index >= packet_size_frames_) { - // Copy data to audio bus to match the OnData interface. - uint8* audio_data = reinterpret_cast<uint8*>(capture_buffer.get()); - audio_bus_->FromInterleaved( - audio_data, audio_bus_->frames(), format_.wBitsPerSample / 8); + uint8* audio_data = + reinterpret_cast<uint8*>(capture_buffer.get()); // Deliver data packet, delay estimation and volume level to // the user. - sink_->OnData( - this, audio_bus_.get(), delay_frames * frame_size_, volume); + sink_->OnData(this, + audio_data, + packet_size_bytes_, + delay_frames * frame_size_, + volume); // Store parts of the recorded data which can't be delivered // using the current packet size. The stored section will be used diff --git a/media/audio/win/audio_low_latency_input_win.h b/media/audio/win/audio_low_latency_input_win.h index a33a582..948a3fb 100644 --- a/media/audio/win/audio_low_latency_input_win.h +++ b/media/audio/win/audio_low_latency_input_win.h @@ -75,7 +75,6 @@ namespace media { -class AudioBus; class AudioManagerWin; // AudioInputStream implementation using Windows Core Audio APIs. @@ -212,10 +211,6 @@ class MEDIA_EXPORT WASAPIAudioInputStream // This event will be signaled when capturing shall stop. base::win::ScopedHandle stop_capture_event_; - // Extra audio bus used for storage of deinterleaved data for the OnData - // callback. - scoped_ptr<media::AudioBus> audio_bus_; - DISALLOW_COPY_AND_ASSIGN(WASAPIAudioInputStream); }; diff --git a/media/audio/win/audio_low_latency_input_win_unittest.cc b/media/audio/win/audio_low_latency_input_win_unittest.cc index eee1887..34a016f 100644 --- a/media/audio/win/audio_low_latency_input_win_unittest.cc +++ b/media/audio/win/audio_low_latency_input_win_unittest.cc @@ -38,23 +38,21 @@ ACTION_P3(CheckCountAndPostQuitTask, count, limit, loop) { class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { public: - MOCK_METHOD4(OnData, - void(AudioInputStream* stream, - const AudioBus* src, - uint32 hardware_delay_bytes, - double volume)); + MOCK_METHOD5(OnData, void(AudioInputStream* stream, + const uint8* src, uint32 size, + uint32 hardware_delay_bytes, double volume)); MOCK_METHOD1(OnError, void(AudioInputStream* stream)); }; class FakeAudioInputCallback : public AudioInputStream::AudioInputCallback { public: FakeAudioInputCallback() - : error_(false), - data_event_(false, false), - num_received_audio_frames_(0) {} + : error_(false), + data_event_(false, false) { + } + const std::vector<uint8>& received_data() const { return received_data_; } bool error() const { return error_; } - int num_received_audio_frames() const { return num_received_audio_frames_; } // Waits until OnData() is called on another thread. void WaitForData() { @@ -62,11 +60,9 @@ class FakeAudioInputCallback : public AudioInputStream::AudioInputCallback { } virtual void OnData(AudioInputStream* stream, - const AudioBus* src, - uint32 hardware_delay_bytes, - double volume) OVERRIDE { - EXPECT_NE(hardware_delay_bytes, 0u); - num_received_audio_frames_ += src->frames(); + const uint8* src, uint32 size, + uint32 hardware_delay_bytes, double volume) OVERRIDE { + received_data_.insert(received_data_.end(), src, src + size); data_event_.Signal(); } @@ -75,7 +71,7 @@ class FakeAudioInputCallback : public AudioInputStream::AudioInputCallback { } private: - int num_received_audio_frames_; + std::vector<uint8> received_data_; base::WaitableEvent data_event_; bool error_; @@ -90,9 +86,8 @@ class WriteToFileAudioSink : public AudioInputStream::AudioInputCallback { // 2 bytes per sample, 2 channels, 10ms @ 48kHz, 10 seconds <=> 1920000 bytes. static const size_t kMaxBufferSize = 2 * 2 * 480 * 100 * 10; - explicit WriteToFileAudioSink(const char* file_name, int bits_per_sample) - : bits_per_sample_(bits_per_sample), - buffer_(0, kMaxBufferSize), + explicit WriteToFileAudioSink(const char* file_name) + : buffer_(0, kMaxBufferSize), bytes_to_write_(0) { base::FilePath file_path; EXPECT_TRUE(PathService::Get(base::DIR_EXE, &file_path)); @@ -100,7 +95,6 @@ class WriteToFileAudioSink : public AudioInputStream::AudioInputCallback { binary_file_ = base::OpenFile(file_path, "wb"); DLOG_IF(ERROR, !binary_file_) << "Failed to open binary PCM data file."; VLOG(0) << ">> Output file: " << file_path.value() << " has been created."; - VLOG(0) << "bits_per_sample_:" << bits_per_sample_; } virtual ~WriteToFileAudioSink() { @@ -123,20 +117,14 @@ class WriteToFileAudioSink : public AudioInputStream::AudioInputCallback { // AudioInputStream::AudioInputCallback implementation. virtual void OnData(AudioInputStream* stream, - const AudioBus* src, + const uint8* src, + uint32 size, uint32 hardware_delay_bytes, double volume) { - EXPECT_EQ(bits_per_sample_, 16); - const int num_samples = src->frames() * src->channels(); - scoped_ptr<int16> interleaved(new int16[num_samples]); - const int bytes_per_sample = sizeof(*interleaved); - src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); - // Store data data in a temporary buffer to avoid making blocking // fwrite() calls in the audio callback. The complete buffer will be // written to file in the destructor. - const int size = bytes_per_sample * num_samples; - if (buffer_.Append((const uint8*)interleaved.get(), size)) { + if (buffer_.Append(src, size)) { bytes_to_write_ += size; } } @@ -144,7 +132,6 @@ class WriteToFileAudioSink : public AudioInputStream::AudioInputCallback { virtual void OnError(AudioInputStream* stream) {} private: - int bits_per_sample_; media::SeekableBuffer buffer_; FILE* binary_file_; size_t bytes_to_write_; @@ -389,7 +376,8 @@ TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { // We use 10ms packets and will run the test until ten packets are received. // All should contain valid packets of the same size and a valid delay // estimate. - EXPECT_CALL(sink, OnData(ais.get(), NotNull(), Gt(bytes_per_packet), _)) + EXPECT_CALL(sink, OnData( + ais.get(), NotNull(), bytes_per_packet, Gt(bytes_per_packet), _)) .Times(AtLeast(10)) .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); ais->Start(&sink); @@ -409,7 +397,8 @@ TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * (aisw.bits_per_sample() / 8); - EXPECT_CALL(sink, OnData(ais.get(), NotNull(), Gt(bytes_per_packet), _)) + EXPECT_CALL(sink, OnData( + ais.get(), NotNull(), bytes_per_packet, Gt(bytes_per_packet), _)) .Times(AtLeast(10)) .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); ais->Start(&sink); @@ -425,7 +414,8 @@ TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * (aisw.bits_per_sample() / 8); - EXPECT_CALL(sink, OnData(ais.get(), NotNull(), Gt(bytes_per_packet), _)) + EXPECT_CALL(sink, OnData( + ais.get(), NotNull(), bytes_per_packet, Gt(bytes_per_packet), _)) .Times(AtLeast(10)) .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); ais->Start(&sink); @@ -434,7 +424,7 @@ TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { ais.Close(); } -// Test that we can capture a stream in loopback. +// Test that we can capture loopback stream. TEST(WinAudioInputTest, WASAPIAudioInputStreamLoopback) { scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); if (!audio_manager->HasAudioOutputDevices() || !CoreAudioUtil::IsSupported()) @@ -459,7 +449,7 @@ TEST(WinAudioInputTest, WASAPIAudioInputStreamLoopback) { sink.WaitForData(); stream.Close(); - EXPECT_GT(sink.num_received_audio_frames(), 0); + EXPECT_FALSE(sink.received_data().empty()); EXPECT_FALSE(sink.error()); } @@ -484,7 +474,7 @@ TEST(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) { EXPECT_TRUE(ais->Open()); VLOG(0) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]"; - WriteToFileAudioSink file_sink(file_name, aisw.bits_per_sample()); + WriteToFileAudioSink file_sink(file_name); VLOG(0) << ">> Speak into the default microphone while recording."; ais->Start(&file_sink); base::PlatformThread::Sleep(TestTimeouts::action_timeout()); diff --git a/media/audio/win/wavein_input_win.cc b/media/audio/win/wavein_input_win.cc index f12bcf2..43a356f 100644 --- a/media/audio/win/wavein_input_win.cc +++ b/media/audio/win/wavein_input_win.cc @@ -10,7 +10,6 @@ #include "media/audio/audio_io.h" #include "media/audio/win/audio_manager_win.h" #include "media/audio/win/device_enumeration_win.h" -#include "media/base/audio_bus.h" namespace media { @@ -21,9 +20,7 @@ static WAVEHDR* GetNextBuffer(WAVEHDR* current) { } PCMWaveInAudioInputStream::PCMWaveInAudioInputStream( - AudioManagerWin* manager, - const AudioParameters& params, - int num_buffers, + AudioManagerWin* manager, const AudioParameters& params, int num_buffers, const std::string& device_id) : state_(kStateEmpty), manager_(manager), @@ -32,8 +29,7 @@ PCMWaveInAudioInputStream::PCMWaveInAudioInputStream( callback_(NULL), num_buffers_(num_buffers), buffer_(NULL), - channels_(params.channels()), - audio_bus_(media::AudioBus::Create(params)) { + channels_(params.channels()) { DCHECK_GT(num_buffers_, 0); format_.wFormatTag = WAVE_FORMAT_PCM; format_.nChannels = params.channels() > 2 ? 2 : params.channels(); @@ -294,11 +290,11 @@ void PCMWaveInAudioInputStream::WaveCallback(HWAVEIN hwi, UINT msg, // there is currently no support for controlling the microphone volume // level. WAVEHDR* buffer = reinterpret_cast<WAVEHDR*>(param1); - obj->audio_bus_->FromInterleaved(reinterpret_cast<uint8*>(buffer->lpData), - obj->audio_bus_->frames(), - obj->format_.wBitsPerSample / 8); - obj->callback_->OnData( - obj, obj->audio_bus_.get(), buffer->dwBytesRecorded, 0.0); + obj->callback_->OnData(obj, + reinterpret_cast<const uint8*>(buffer->lpData), + buffer->dwBytesRecorded, + buffer->dwBytesRecorded, + 0.0); // Queue the finished buffer back with the audio driver. Since we are // reusing the same buffers we can get away without calling diff --git a/media/audio/win/wavein_input_win.h b/media/audio/win/wavein_input_win.h index 5b1edd5..df5ce4d 100644 --- a/media/audio/win/wavein_input_win.h +++ b/media/audio/win/wavein_input_win.h @@ -20,7 +20,6 @@ namespace media { -class AudioBus; class AudioManagerWin; class PCMWaveInAudioInputStream : public AudioInputStream { @@ -124,10 +123,6 @@ class PCMWaveInAudioInputStream : public AudioInputStream { // Lock used to avoid conflicts when Stop() is called during a callback. base::Lock lock_; - // Extra audio bus used for storage of deinterleaved data for the OnData - // callback. - scoped_ptr<media::AudioBus> audio_bus_; - DISALLOW_COPY_AND_ASSIGN(PCMWaveInAudioInputStream); }; diff --git a/media/base/audio_bus.h b/media/base/audio_bus.h index c5b161f..56ef977 100644 --- a/media/base/audio_bus.h +++ b/media/base/audio_bus.h @@ -108,9 +108,10 @@ class MEDIA_EXPORT AudioBus { // the channels are valid. void SwapChannels(int a, int b); - virtual ~AudioBus(); - private: + friend struct base::DefaultDeleter<AudioBus>; + ~AudioBus(); + AudioBus(int channels, int frames); AudioBus(int channels, int frames, float* data); AudioBus(int frames, const std::vector<float*>& channel_data); |