diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-31 23:18:48 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-31 23:18:48 +0000 |
commit | 2f6d086da79c737bc2a0ee3023ca80c608c75d19 (patch) | |
tree | 6943204cb1c9c7d7cbe722f91a64a1c326601fef | |
parent | 87949cc2b85979964ca9de9483ba1ba2758e0b81 (diff) | |
download | chromium_src-2f6d086da79c737bc2a0ee3023ca80c608c75d19.zip chromium_src-2f6d086da79c737bc2a0ee3023ca80c608c75d19.tar.gz chromium_src-2f6d086da79c737bc2a0ee3023ca80c608c75d19.tar.bz2 |
Add AudioParameters struct. Use it everywhere.
BUG=None
TEST=unittests
Review URL: http://codereview.chromium.org/3226012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58097 0039d316-1c4b-4281-b951-d872f2087c98
51 files changed, 464 insertions, 543 deletions
diff --git a/chrome/browser/renderer_host/audio_renderer_host.cc b/chrome/browser/renderer_host/audio_renderer_host.cc index fcfd0bf..3219333 100644 --- a/chrome/browser/renderer_host/audio_renderer_host.cc +++ b/chrome/browser/renderer_host/audio_renderer_host.cc @@ -55,17 +55,16 @@ static size_t GetMaxAudioStreamsAllowed() { return kMaxStreams; } -static uint32 SelectHardwarePacketSize(int channels, int sample_rate, - int bits_per_sample) { +static uint32 SelectHardwarePacketSize(AudioParameters params) { // Select the number of samples that can provide at least // |kMillisecondsPerHardwarePacket| worth of audio data. int samples = kMinSamplesPerHardwarePacket; while (samples <= kMaxSamplesPerHardwarePacket && samples * base::Time::kMillisecondsPerSecond < - sample_rate * kMillisecondsPerHardwarePacket) { + params.sample_rate * kMillisecondsPerHardwarePacket) { samples *= 2; } - return channels * samples * bits_per_sample / 8; + return params.channels * samples * params.bits_per_sample / 8; } /////////////////////////////////////////////////////////////////////////////// @@ -332,9 +331,7 @@ void AudioRendererHost::OnCreateStream( // Select the hardwaer packet size if not specified. uint32 hardware_packet_size = params.packet_size; if (!hardware_packet_size) { - hardware_packet_size = SelectHardwarePacketSize(params.channels, - params.sample_rate, - params.bits_per_sample); + hardware_packet_size = SelectHardwarePacketSize(params.params); } scoped_ptr<AudioEntry> entry(new AudioEntry()); @@ -355,18 +352,13 @@ void AudioRendererHost::OnCreateStream( entry->reader.reset(reader.release()); controller = media::AudioOutputController::CreateLowLatency( - this, params.format, params.channels, - params.sample_rate, - params.bits_per_sample, + this, params.params, hardware_packet_size, entry->reader.get()); } else { // The choice of buffer capacity is based on experiment. controller = - media::AudioOutputController::Create(this, params.format, - params.channels, - params.sample_rate, - params.bits_per_sample, + media::AudioOutputController::Create(this, params.params, hardware_packet_size, 3 * hardware_packet_size); } diff --git a/chrome/browser/renderer_host/audio_renderer_host_unittest.cc b/chrome/browser/renderer_host/audio_renderer_host_unittest.cc index 7020d04..ad2fa7e 100644 --- a/chrome/browser/renderer_host/audio_renderer_host_unittest.cc +++ b/chrome/browser/renderer_host/audio_renderer_host_unittest.cc @@ -212,12 +212,12 @@ class AudioRendererHostTest : public testing::Test { ViewHostMsg_Audio_CreateStream_Params params; if (mock_stream_) - params.format = AudioManager::AUDIO_MOCK; + params.params.format = AudioParameters::AUDIO_MOCK; else - params.format = AudioManager::AUDIO_PCM_LINEAR; - params.channels = 2; - params.sample_rate = AudioManager::kAudioCDSampleRate; - params.bits_per_sample = 16; + params.params.format = AudioParameters::AUDIO_PCM_LINEAR; + params.params.channels = 2; + params.params.sample_rate = AudioParameters::kAudioCDSampleRate; + params.params.bits_per_sample = 16; params.packet_size = 0; // Send a create stream message to the audio output stream and wait until @@ -238,12 +238,12 @@ class AudioRendererHostTest : public testing::Test { ViewHostMsg_Audio_CreateStream_Params params; if (mock_stream_) - params.format = AudioManager::AUDIO_MOCK; + params.params.format = AudioParameters::AUDIO_MOCK; else - params.format = AudioManager::AUDIO_PCM_LINEAR; - params.channels = 2; - params.sample_rate = AudioManager::kAudioCDSampleRate; - params.bits_per_sample = 16; + params.params.format = AudioParameters::AUDIO_PCM_LINEAR; + params.params.channels = 2; + params.params.sample_rate = AudioParameters::kAudioCDSampleRate; + params.params.bits_per_sample = 16; params.packet_size = 0; // Send a create stream message to the audio output stream and wait until diff --git a/chrome/browser/speech/speech_recognizer.cc b/chrome/browser/speech/speech_recognizer.cc index 9c186ea..df41bf5 100644 --- a/chrome/browser/speech/speech_recognizer.cc +++ b/chrome/browser/speech/speech_recognizer.cc @@ -134,10 +134,10 @@ bool SpeechRecognizer::StartRecording() { int samples_per_packet = (kAudioSampleRate * kAudioPacketIntervalMs) / 1000; DCHECK((samples_per_packet % encoder_->samples_per_frame()) == 0); - audio_controller_ = AudioInputController::Create(this, - AudioManager::AUDIO_PCM_LINEAR, kNumAudioChannels, - kAudioSampleRate, kNumBitsPerAudioSample, - samples_per_packet); + AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kNumAudioChannels, + kAudioSampleRate, kNumBitsPerAudioSample); + audio_controller_ = + AudioInputController::Create(this, params, samples_per_packet); DCHECK(audio_controller_.get()); LOG(INFO) << "SpeechRecognizer starting record."; audio_controller_->Record(); diff --git a/chrome/common/render_messages_params.cc b/chrome/common/render_messages_params.cc index f28ab06..78e1d72 100644 --- a/chrome/common/render_messages_params.cc +++ b/chrome/common/render_messages_params.cc @@ -159,8 +159,8 @@ struct ParamTraits<NavigationGesture> { // Traits for AudioManager::Format. template <> -struct ParamTraits<AudioManager::Format> { - typedef AudioManager::Format param_type; +struct ParamTraits<AudioParameters::Format> { + typedef AudioParameters::Format param_type; static void Write(Message* m, const param_type& p) { m->WriteInt(p); } @@ -168,19 +168,19 @@ struct ParamTraits<AudioManager::Format> { int type; if (!m->ReadInt(iter, &type)) return false; - *p = static_cast<AudioManager::Format>(type); + *p = static_cast<AudioParameters::Format>(type); return true; } static void Log(const param_type& p, std::string* l) { std::string format; switch (p) { - case AudioManager::AUDIO_PCM_LINEAR: + case AudioParameters::AUDIO_PCM_LINEAR: format = "AUDIO_PCM_LINEAR"; break; - case AudioManager::AUDIO_PCM_LOW_LATENCY: + case AudioParameters::AUDIO_PCM_LOW_LATENCY: format = "AUDIO_PCM_LOW_LATENCY"; break; - case AudioManager::AUDIO_MOCK: + case AudioParameters::AUDIO_MOCK: format = "AUDIO_MOCK"; break; default: @@ -730,10 +730,10 @@ void ParamTraits<ViewHostMsg_DidPrintPage_Params>::Log(const param_type& p, void ParamTraits<ViewHostMsg_Audio_CreateStream_Params>::Write( Message* m, const param_type& p) { - WriteParam(m, p.format); - WriteParam(m, p.channels); - WriteParam(m, p.sample_rate); - WriteParam(m, p.bits_per_sample); + WriteParam(m, p.params.format); + WriteParam(m, p.params.channels); + WriteParam(m, p.params.sample_rate); + WriteParam(m, p.params.bits_per_sample); WriteParam(m, p.packet_size); } @@ -741,10 +741,10 @@ bool ParamTraits<ViewHostMsg_Audio_CreateStream_Params>::Read(const Message* m, void** iter, param_type* p) { return - ReadParam(m, iter, &p->format) && - ReadParam(m, iter, &p->channels) && - ReadParam(m, iter, &p->sample_rate) && - ReadParam(m, iter, &p->bits_per_sample) && + ReadParam(m, iter, &p->params.format) && + ReadParam(m, iter, &p->params.channels) && + ReadParam(m, iter, &p->params.sample_rate) && + ReadParam(m, iter, &p->params.bits_per_sample) && ReadParam(m, iter, &p->packet_size); } @@ -752,13 +752,13 @@ void ParamTraits<ViewHostMsg_Audio_CreateStream_Params>::Log( const param_type& p, std::string* l) { l->append("<ViewHostMsg_Audio_CreateStream_Params>("); - LogParam(p.format, l); + LogParam(p.params.format, l); l->append(", "); - LogParam(p.channels, l); + LogParam(p.params.channels, l); l->append(", "); - LogParam(p.sample_rate, l); + LogParam(p.params.sample_rate, l); l->append(", "); - LogParam(p.bits_per_sample, l); + LogParam(p.params.bits_per_sample, l); l->append(", "); LogParam(p.packet_size, l); l->append(")"); diff --git a/chrome/common/render_messages_params.h b/chrome/common/render_messages_params.h index eaf7556..1f83458 100644 --- a/chrome/common/render_messages_params.h +++ b/chrome/common/render_messages_params.h @@ -27,7 +27,7 @@ #include "chrome/common/window_container_type.h" #include "googleurl/src/gurl.h" #include "ipc/ipc_param_traits.h" -#include "media/audio/audio_manager.h" +#include "media/audio/audio_parameters.h" #include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h" #include "third_party/WebKit/WebKit/chromium/public/WebTextDirection.h" #include "webkit/glue/password_form.h" @@ -494,16 +494,7 @@ struct ViewHostMsg_DidPrintPage_Params { // Parameters for creating an audio output stream. struct ViewHostMsg_Audio_CreateStream_Params { // Format request for the stream. - AudioManager::Format format; - - // Number of channels. - int channels; - - // Sampling rate (frequency) of the output stream. - int sample_rate; - - // Number of bits per sample; - int bits_per_sample; + AudioParameters params; // Number of bytes per packet. Determines the maximum number of bytes // transported for each audio packet request. diff --git a/chrome/renderer/media/audio_renderer_impl.cc b/chrome/renderer/media/audio_renderer_impl.cc index 06356cc..b7e021f 100644 --- a/chrome/renderer/media/audio_renderer_impl.cc +++ b/chrome/renderer/media/audio_renderer_impl.cc @@ -27,9 +27,6 @@ const int kPacketsInBuffer = 3; AudioRendererImpl::AudioRendererImpl(AudioMessageFilter* filter) : AudioRendererBase(), - channels_(0), - sample_rate_(0), - sample_bits_(0), bytes_per_second_(0), filter_(filter), stream_id_(0), @@ -63,18 +60,19 @@ bool AudioRendererImpl::IsMediaFormatSupported( bool AudioRendererImpl::OnInitialize(const media::MediaFormat& media_format) { // Parse integer values in MediaFormat. if (!ParseMediaFormat(media_format, - &channels_, - &sample_rate_, - &sample_bits_)) { + ¶ms_.channels, + ¶ms_.sample_rate, + ¶ms_.bits_per_sample)) { return false; } + params_.format = AudioParameters::AUDIO_PCM_LINEAR; // Calculate the number of bytes per second using information of the stream. - bytes_per_second_ = sample_rate_ * channels_ * sample_bits_ / 8; + bytes_per_second_ = params_.sample_rate * params_.channels * + params_.bits_per_sample / 8; + io_loop_->PostTask(FROM_HERE, - NewRunnableMethod(this, &AudioRendererImpl::CreateStreamTask, - AudioManager::AUDIO_PCM_LINEAR, channels_, - sample_rate_, sample_bits_)); + NewRunnableMethod(this, &AudioRendererImpl::CreateStreamTask, params_)); return true; } @@ -253,9 +251,7 @@ void AudioRendererImpl::OnVolume(double volume) { // pipeline. } -void AudioRendererImpl::CreateStreamTask( - AudioManager::Format format, int channels, - int sample_rate, int bits_per_sample) { +void AudioRendererImpl::CreateStreamTask(AudioParameters audio_params) { DCHECK(MessageLoop::current() == io_loop_); AutoLock auto_lock(lock_); @@ -268,10 +264,7 @@ void AudioRendererImpl::CreateStreamTask( io_loop_->AddDestructionObserver(this); ViewHostMsg_Audio_CreateStream_Params params; - params.format = format; - params.channels = channels; - params.sample_rate = sample_rate; - params.bits_per_sample = bits_per_sample; + params.params = audio_params; params.packet_size = 0; filter_->Send(new ViewHostMsg_CreateAudioStream(0, stream_id_, params, diff --git a/chrome/renderer/media/audio_renderer_impl.h b/chrome/renderer/media/audio_renderer_impl.h index 30ac36f..f8fa094 100644 --- a/chrome/renderer/media/audio_renderer_impl.h +++ b/chrome/renderer/media/audio_renderer_impl.h @@ -115,8 +115,7 @@ class AudioRendererImpl : public media::AudioRendererBase, // The following methods are tasks posted on the IO thread that needs to // be executed on that thread. They interact with AudioMessageFilter and // sends IPC messages on that thread. - void CreateStreamTask(AudioManager::Format format, int channels, - int sample_rate, int bits_per_sample); + void CreateStreamTask(AudioParameters params); void PlayTask(); void PauseTask(); void SeekTask(); @@ -128,9 +127,7 @@ class AudioRendererImpl : public media::AudioRendererBase, virtual void WillDestroyCurrentMessageLoop(); // Information about the audio stream. - int channels_; - int sample_rate_; - int sample_bits_; + AudioParameters params_; uint32 bytes_per_second_; scoped_refptr<AudioMessageFilter> filter_; diff --git a/chrome/renderer/pepper_devices.cc b/chrome/renderer/pepper_devices.cc index 0e4f2ac..54232ee 100644 --- a/chrome/renderer/pepper_devices.cc +++ b/chrome/renderer/pepper_devices.cc @@ -173,23 +173,23 @@ NPError AudioDeviceContext::Initialize(AudioMessageFilter* filter, context_= context; ViewHostMsg_Audio_CreateStream_Params params; - params.format = AudioManager::AUDIO_PCM_LINEAR; - params.channels = config->outputChannelMap; - params.sample_rate = config->sampleRate; + params.params.format = AudioParameters::AUDIO_PCM_LINEAR; + params.params.channels = config->outputChannelMap; + params.params.sample_rate = config->sampleRate; switch (config->sampleType) { case NPAudioSampleTypeInt16: - params.bits_per_sample = 16; + params.params.bits_per_sample = 16; break; case NPAudioSampleTypeFloat32: - params.bits_per_sample = 32; + params.params.bits_per_sample = 32; break; default: return NPERR_INVALID_PARAM; } context->config = *config; - params.packet_size = config->sampleFrameCount * config->outputChannelMap - * (params.bits_per_sample >> 3); + params.packet_size = config->sampleFrameCount * config->outputChannelMap * + (params.params.bits_per_sample >> 3); stream_id_ = filter_->AddDelegate(this); filter->Send(new ViewHostMsg_CreateAudioStream(0, stream_id_, params, true)); @@ -278,4 +278,3 @@ void AudioDeviceContext::Run() { FireAudioCallback(); } } - diff --git a/chrome/renderer/pepper_plugin_delegate_impl.cc b/chrome/renderer/pepper_plugin_delegate_impl.cc index 8ccaed4..8e6763c 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.cc +++ b/chrome/renderer/pepper_plugin_delegate_impl.cc @@ -344,13 +344,13 @@ bool PlatformAudioImpl::Initialize( client_ = client; ViewHostMsg_Audio_CreateStream_Params params; - params.format = AudioManager::AUDIO_PCM_LINEAR; - params.channels = 2; - params.sample_rate = sample_rate; - params.bits_per_sample = 16; + params.params.format = AudioParameters::AUDIO_PCM_LINEAR; + params.params.channels = 2; + params.params.sample_rate = sample_rate; + params.params.bits_per_sample = 16; - params.packet_size = sample_count * params.channels * - (params.bits_per_sample >> 3); + params.packet_size = sample_count * params.params.channels * + (params.params.bits_per_sample >> 3); stream_id_ = filter_->AddDelegate(this); return filter_->Send(new ViewHostMsg_CreateAudioStream(0, stream_id_, params, diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc index 9c143c1..fc4b97d 100644 --- a/media/audio/audio_input_controller.cc +++ b/media/audio/audio_input_controller.cc @@ -3,13 +3,12 @@ // found in the LICENSE file. #include "media/audio/audio_input_controller.h" +#include "media/base/limits.h" namespace { -const int kMaxSampleRate = 192000; -const int kMaxBitsPerSample = 64; const int kMaxInputChannels = 2; -const int kMaxSamplesPerPacket = kMaxSampleRate; +const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate; } // namespace @@ -32,20 +31,15 @@ AudioInputController::~AudioInputController() { // static scoped_refptr<AudioInputController> AudioInputController::Create( EventHandler* event_handler, - AudioManager::Format format, - int channels, - int sample_rate, - int bits_per_sample, + AudioParameters params, int samples_per_packet) { - if ((channels > kMaxInputChannels) || (channels <= 0) || - (sample_rate > kMaxSampleRate) || (sample_rate <= 0) || - (bits_per_sample > kMaxBitsPerSample) || (bits_per_sample <= 0) || + if (!params.IsValid() || + (params.channels > kMaxInputChannels) || (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0)) return NULL; if (factory_) { - return factory_->Create(event_handler, format, channels, sample_rate, - bits_per_sample, samples_per_packet); + return factory_->Create(event_handler, params, samples_per_packet); } scoped_refptr<AudioInputController> controller = new AudioInputController( @@ -56,8 +50,7 @@ scoped_refptr<AudioInputController> AudioInputController::Create( controller->thread_.message_loop()->PostTask( FROM_HERE, NewRunnableMethod(controller.get(), &AudioInputController::DoCreate, - format, channels, sample_rate, bits_per_sample, - samples_per_packet)); + params, samples_per_packet)); return controller; } @@ -82,11 +75,10 @@ void AudioInputController::Close() { thread_.Stop(); } -void AudioInputController::DoCreate(AudioManager::Format format, int channels, - int sample_rate, int bits_per_sample, +void AudioInputController::DoCreate(AudioParameters params, uint32 samples_per_packet) { stream_ = AudioManager::GetAudioManager()->MakeAudioInputStream( - format, channels, sample_rate, bits_per_sample, samples_per_packet); + params, samples_per_packet); if (!stream_) { // TODO(satish): Define error types. diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h index deded58..f6e8d1e 100644 --- a/media/audio/audio_input_controller.h +++ b/media/audio/audio_input_controller.h @@ -55,10 +55,7 @@ class AudioInputController : class Factory { public: virtual AudioInputController* Create(EventHandler* event_handler, - AudioManager::Format format, - int channels, - int sample_rate, - int bits_per_sample, + AudioParameters params, int samples_per_packet) = 0; protected: @@ -73,10 +70,7 @@ class AudioInputController : // handler will receive a OnCreated() call. static scoped_refptr<AudioInputController> Create( EventHandler* event_handler, - AudioManager::Format format, // Format of the stream. - int channels, // Number of channels. - int sample_rate, // Sampling frequency/rate. - int bits_per_sample, // Number of bits per sample. + AudioParameters params, int samples_per_packet); // Size of the hardware buffer. // Sets the factory used by the static method Create. AudioInputController @@ -116,8 +110,7 @@ class AudioInputController : AudioInputController(EventHandler* handler); // The following methods are executed on the audio controller thread. - void DoCreate(AudioManager::Format format, int channels, - int sample_rate, int bits_per_sample, + void DoCreate(AudioParameters params, uint32 samples_per_packet); void DoRecord(); void DoClose(); diff --git a/media/audio/audio_input_controller_unittest.cc b/media/audio/audio_input_controller_unittest.cc index dfa7736..03219f8 100644 --- a/media/audio/audio_input_controller_unittest.cc +++ b/media/audio/audio_input_controller_unittest.cc @@ -16,7 +16,7 @@ using ::testing::NotNull; namespace { -const int kSampleRate = AudioManager::kAudioCDSampleRate; +const int kSampleRate = AudioParameters::kAudioCDSampleRate; const int kBitsPerSample = 16; const int kChannels = 2; const int kSamplesPerPacket = kSampleRate / 10; @@ -54,9 +54,10 @@ TEST(AudioInputControllerTest, CreateAndClose) { EXPECT_CALL(event_handler, OnCreated(NotNull())) .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)); - scoped_refptr<AudioInputController> controller = AudioInputController::Create( - &event_handler, AudioManager::AUDIO_MOCK, kChannels, - kSampleRate, kBitsPerSample, kSamplesPerPacket); + AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels, + kSampleRate, kBitsPerSample); + scoped_refptr<AudioInputController> controller = + AudioInputController::Create(&event_handler, params, kSamplesPerPacket); ASSERT_TRUE(controller.get()); // Wait for OnCreated() to be called. @@ -84,9 +85,10 @@ TEST(AudioInputControllerTest, RecordAndClose) { .Times(AtLeast(10)) .WillRepeatedly(CheckCountAndSignalEvent(&count, 10, &event)); - scoped_refptr<AudioInputController> controller = AudioInputController::Create( - &event_handler, AudioManager::AUDIO_MOCK, kChannels, - kSampleRate, kBitsPerSample, kSamplesPerPacket); + AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels, + kSampleRate, kBitsPerSample); + scoped_refptr<AudioInputController> controller = + AudioInputController::Create(&event_handler, params, kSamplesPerPacket); ASSERT_TRUE(controller.get()); // Wait for OnCreated() to be called. @@ -105,9 +107,10 @@ TEST(AudioInputControllerTest, SamplesPerPacketTooLarge) { // Create an audio device with a very large packet size. MockAudioInputControllerEventHandler event_handler; + AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels, + kSampleRate, kBitsPerSample); scoped_refptr<AudioInputController> controller = AudioInputController::Create( - &event_handler, AudioManager::AUDIO_MOCK, kChannels, - kSampleRate, kBitsPerSample, kSamplesPerPacket * 1000); + &event_handler, params, kSamplesPerPacket * 1000); ASSERT_FALSE(controller); } @@ -115,9 +118,10 @@ TEST(AudioInputControllerTest, SamplesPerPacketTooLarge) { TEST(AudioInputControllerTest, CloseTwice) { MockAudioInputControllerEventHandler event_handler; EXPECT_CALL(event_handler, OnCreated(NotNull())); - scoped_refptr<AudioInputController> controller = AudioInputController::Create( - &event_handler, AudioManager::AUDIO_MOCK, kChannels, - kSampleRate, kBitsPerSample, kSamplesPerPacket); + AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels, + kSampleRate, kBitsPerSample); + scoped_refptr<AudioInputController> controller = + AudioInputController::Create(&event_handler, params, kSamplesPerPacket); ASSERT_TRUE(controller.get()); controller->Close(); diff --git a/media/audio/audio_manager.cc b/media/audio/audio_manager.cc index 7148d21..7bb2402 100644 --- a/media/audio/audio_manager.cc +++ b/media/audio/audio_manager.cc @@ -20,15 +20,11 @@ class NullAudioManager : public AudioManager { // Implementation of AudioManager. virtual bool HasAudioOutputDevices() { return false; } virtual bool HasAudioInputDevices() { return false; } - virtual AudioOutputStream* MakeAudioOutputStream(Format format, int channels, - int sample_rate, - char bits_per_sample) { + virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params) { NOTIMPLEMENTED(); return NULL; } - virtual AudioInputStream* MakeAudioInputStream(Format format, int channels, - int sample_rate, - char bits_per_sample, + virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, uint32 samples_per_packet) { NOTIMPLEMENTED(); return NULL; diff --git a/media/audio/audio_manager.h b/media/audio/audio_manager.h index 2185950..2c988ba 100644 --- a/media/audio/audio_manager.h +++ b/media/audio/audio_manager.h @@ -6,6 +6,7 @@ #define MEDIA_AUDIO_AUDIO_MANAGER_H_ #include "base/basictypes.h" +#include "media/audio/audio_parameters.h" class AudioInputStream; class AudioOutputStream; @@ -16,20 +17,6 @@ class MessageLoop; // iterators over the existing streams. class AudioManager { public: - enum Format { - AUDIO_PCM_LINEAR = 0, // PCM is 'raw' amplitude samples. - AUDIO_PCM_LOW_LATENCY, // Linear PCM, low latency requested. - AUDIO_MOCK, // Creates a dummy AudioOutputStream object. - AUDIO_LAST_FORMAT // Only used for validation of format. - }; - - // Telephone quality sample rate, mostly for speech-only audio. - static const uint32 kTelephoneSampleRate = 8000; - // CD sampling rate is 44.1 KHz or conveniently 2x2x3x3x5x5x7x7. - static const uint32 kAudioCDSampleRate = 44100; - // Digital Audio Tape sample rate. - static const uint32 kAudioDATSampleRate = 48000; - // Returns true if the OS reports existence of audio devices. This does not // guarantee that the existing devices support all formats and sample rates. virtual bool HasAudioOutputDevices() = 0; @@ -52,9 +39,7 @@ class AudioManager { // available. // // Do not free the returned AudioOutputStream. It is owned by AudioManager. - virtual AudioOutputStream* MakeAudioOutputStream(Format format, int channels, - int sample_rate, - char bits_per_sample) = 0; + virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params) = 0; // Factory to create audio recording streams. // |channels| can be 1 or 2. @@ -68,9 +53,7 @@ class AudioManager { // // Do not free the returned AudioInputStream. It is owned by AudioManager. // When you are done with it, call |Stop()| and |Close()| to release it. - virtual AudioInputStream* MakeAudioInputStream(Format format, int channels, - int sample_rate, - char bits_per_sample, + virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, uint32 samples_per_packet) = 0; // Muting continues playback but effectively the volume is set to zero. diff --git a/media/audio/audio_manager_base.h b/media/audio/audio_manager_base.h index ed8ab0e..6d01c26 100644 --- a/media/audio/audio_manager_base.h +++ b/media/audio/audio_manager_base.h @@ -22,7 +22,6 @@ class AudioManagerBase : public AudioManager { bool initialized() { return initialized_; } - protected: // Thread used to interact with AudioOutputStreams created by this // audio manger. base::Thread audio_thread_; diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc index 45ad62c..66c91a3 100644 --- a/media/audio/audio_output_controller.cc +++ b/media/audio/audio_output_controller.cc @@ -10,29 +10,24 @@ // renderer to avoid renderer from requesting too much memory. static const uint32 kMegabytes = 1024 * 1024; static const uint32 kMaxHardwareBufferSize = 2 * kMegabytes; -static const int kMaxChannels = 32; -static const int kMaxBitsPerSample = 64; -static const int kMaxSampleRate = 192000; // Signal a pause in low-latency mode. static const int kPauseMark = -1; +namespace { // Return true if the parameters for creating an audio stream is valid. // Return false otherwise. -static bool CheckParameters(int channels, int sample_rate, - int bits_per_sample, uint32 hardware_buffer_size) { - if (channels <= 0 || channels > kMaxChannels) - return false; - if (sample_rate <= 0 || sample_rate > kMaxSampleRate) - return false; - if (bits_per_sample <= 0 || bits_per_sample > kMaxBitsPerSample) +static bool CheckParameters(AudioParameters params, + uint32 hardware_buffer_size) { + if (!params.IsValid()) return false; if (hardware_buffer_size <= 0 || - hardware_buffer_size > kMaxHardwareBufferSize) { + hardware_buffer_size > kMaxHardwareBufferSize) return false; - } return true; } +} // namespace + namespace media { AudioOutputController::AudioOutputController(EventHandler* handler, @@ -54,15 +49,11 @@ AudioOutputController::~AudioOutputController() { // static scoped_refptr<AudioOutputController> AudioOutputController::Create( EventHandler* event_handler, - AudioManager::Format format, - int channels, - int sample_rate, - int bits_per_sample, + AudioParameters params, uint32 hardware_buffer_size, uint32 buffer_capacity) { - if (!CheckParameters(channels, sample_rate, bits_per_sample, - hardware_buffer_size)) + if (!CheckParameters(params, hardware_buffer_size)) return NULL; // Starts the audio controller thread. @@ -74,25 +65,20 @@ scoped_refptr<AudioOutputController> AudioOutputController::Create( controller->message_loop_->PostTask( FROM_HERE, NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate, - format, channels, sample_rate, bits_per_sample, - hardware_buffer_size)); + params, hardware_buffer_size)); return controller; } // static scoped_refptr<AudioOutputController> AudioOutputController::CreateLowLatency( EventHandler* event_handler, - AudioManager::Format format, - int channels, - int sample_rate, - int bits_per_sample, + AudioParameters params, uint32 hardware_buffer_size, SyncReader* sync_reader) { DCHECK(sync_reader); - if (!CheckParameters(channels, sample_rate, bits_per_sample, - hardware_buffer_size)) + if (!CheckParameters(params, hardware_buffer_size)) return NULL; // Starts the audio controller thread. @@ -104,8 +90,7 @@ scoped_refptr<AudioOutputController> AudioOutputController::CreateLowLatency( controller->message_loop_->PostTask( FROM_HERE, NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate, - format, channels, sample_rate, bits_per_sample, - hardware_buffer_size)); + params, hardware_buffer_size)); return controller; } @@ -158,8 +143,7 @@ void AudioOutputController::EnqueueData(const uint8* data, uint32 size) { SubmitOnMoreData_Locked(); } -void AudioOutputController::DoCreate(AudioManager::Format format, int channels, - int sample_rate, int bits_per_sample, +void AudioOutputController::DoCreate(AudioParameters params, uint32 hardware_buffer_size) { DCHECK_EQ(message_loop_, MessageLoop::current()); @@ -170,17 +154,14 @@ void AudioOutputController::DoCreate(AudioManager::Format format, int channels, return; DCHECK(state_ == kEmpty); - // Create the stream in the first place. - stream_ = AudioManager::GetAudioManager()->MakeAudioOutputStream( - format, channels, sample_rate, bits_per_sample); - + stream_ = AudioManager::GetAudioManager()->MakeAudioOutputStream(params); if (!stream_) { // TODO(hclam): Define error types. handler_->OnError(this, 0); return; } - if (stream_ && !stream_->Open(hardware_buffer_size)) { + if (!stream_->Open(hardware_buffer_size)) { stream_->Close(); stream_ = NULL; diff --git a/media/audio/audio_output_controller.h b/media/audio/audio_output_controller.h index 4600067..c260e58 100644 --- a/media/audio/audio_output_controller.h +++ b/media/audio/audio_output_controller.h @@ -106,10 +106,7 @@ class AudioOutputController // event handler will receive a OnCreated() call. static scoped_refptr<AudioOutputController> Create( EventHandler* event_handler, - AudioManager::Format format, // Format of the stream. - int channels, // Number of channels. - int sample_rate, // Sampling frequency/rate. - int bits_per_sample, // Number of bits per sample. + AudioParameters params, uint32 hardware_buffer_size, // Size of the hardware buffer. // Soft limit for buffer capacity in this controller. This parameter @@ -119,10 +116,7 @@ class AudioOutputController // Factory method for creating a low latency audio stream. static scoped_refptr<AudioOutputController> CreateLowLatency( EventHandler* event_handler, - AudioManager::Format format, // Format of the stream. - int channels, // Number of channels. - int sample_rate, // Sampling frequency/rate. - int bits_per_sample, // Number of bits per sample. + AudioParameters params, uint32 hardware_buffer_size, // Size of the hardware buffer. // External synchronous reader for audio controller. @@ -170,9 +164,7 @@ class AudioOutputController uint32 capacity, SyncReader* sync_reader); // The following methods are executed on the audio controller thread. - void DoCreate(AudioManager::Format format, int channels, - int sample_rate, int bits_per_sample, - uint32 hardware_buffer_size); + void DoCreate(AudioParameters params, uint32 hardware_buffer_size); void DoPlay(); void DoPause(); void DoFlush(); diff --git a/media/audio/audio_output_controller_unittest.cc b/media/audio/audio_output_controller_unittest.cc index 9383c9d..db1716c 100644 --- a/media/audio/audio_output_controller_unittest.cc +++ b/media/audio/audio_output_controller_unittest.cc @@ -17,7 +17,7 @@ using ::testing::InvokeWithoutArgs; using ::testing::NotNull; using ::testing::Return; -static const int kSampleRate = AudioManager::kAudioCDSampleRate; +static const int kSampleRate = AudioParameters::kAudioCDSampleRate; static const int kBitsPerSample = 16; static const int kChannels = 2; static const int kHardwareBufferSize = kSampleRate * kBitsPerSample * @@ -85,10 +85,10 @@ TEST(AudioOutputControllerTest, CreateAndClose) { return; MockAudioOutputControllerEventHandler event_handler; + AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, + kSampleRate, kBitsPerSample); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, - AudioManager::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample, + AudioOutputController::Create(&event_handler, params, kHardwareBufferSize, kBufferCapacity); ASSERT_TRUE(controller.get()); @@ -120,10 +120,10 @@ TEST(AudioOutputControllerTest, PlayAndClose) { .Times(AtLeast(10)) .WillRepeatedly(SignalEvent(&event, &count, 10)); + AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, + kSampleRate, kBitsPerSample); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, - AudioManager::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample, + AudioOutputController::Create(&event_handler, params, kHardwareBufferSize, kBufferCapacity); ASSERT_TRUE(controller.get()); @@ -166,10 +166,10 @@ TEST(AudioOutputControllerTest, PlayPauseClose) { .Times(Exactly(1)) .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)); + AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, + kSampleRate, kBitsPerSample); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, - AudioManager::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample, + AudioOutputController::Create(&event_handler, params, kHardwareBufferSize, kBufferCapacity); ASSERT_TRUE(controller.get()); @@ -224,10 +224,10 @@ TEST(AudioOutputControllerTest, PlayPausePlay) { .Times(Exactly(1)) .RetiresOnSaturation(); + AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, + kSampleRate, kBitsPerSample); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, - AudioManager::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample, + AudioOutputController::Create(&event_handler, params, kHardwareBufferSize, kBufferCapacity); ASSERT_TRUE(controller.get()); @@ -261,10 +261,10 @@ TEST(AudioOutputControllerTest, HardwareBufferTooLarge) { // Create an audio device with a very large hardware buffer size. MockAudioOutputControllerEventHandler event_handler; + AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, + kSampleRate, kBitsPerSample); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, - AudioManager::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample, + AudioOutputController::Create(&event_handler, params, kHardwareBufferSize * 1000, kBufferCapacity); @@ -289,10 +289,10 @@ TEST(AudioOutputControllerTest, CloseTwice) { .Times(AtLeast(1)) .WillRepeatedly(SignalEvent(&event)); + AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, + kSampleRate, kBitsPerSample); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, - AudioManager::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample, + AudioOutputController::Create(&event_handler, params, kHardwareBufferSize, kBufferCapacity); ASSERT_TRUE(controller.get()); diff --git a/media/audio/audio_parameters.cc b/media/audio/audio_parameters.cc new file mode 100644 index 0000000..ca12452 --- /dev/null +++ b/media/audio/audio_parameters.cc @@ -0,0 +1,30 @@ +// Copyright (c) 2010 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. + +#include "media/audio/audio_parameters.h" + +#include "media/base/limits.h" + +AudioParameters::AudioParameters() + : format(AUDIO_PCM_LINEAR), + channels(0), + sample_rate(0), + bits_per_sample(0) { +} + +AudioParameters::AudioParameters(Format format, int channels, + int sample_rate, int bits_per_sample) + : format(format), + channels(channels), + sample_rate(sample_rate), + bits_per_sample(bits_per_sample) { +} + +bool AudioParameters::IsValid() const { + return (format >= 0) && (format < AUDIO_LAST_FORMAT) && + (channels > 0) && (channels <= media::Limits::kMaxChannels) && + (sample_rate > 0) && (sample_rate <= media::Limits::kMaxSampleRate) && + (bits_per_sample > 0) && + (bits_per_sample <= media::Limits::kMaxBitsPerSample); +} diff --git a/media/audio/audio_parameters.h b/media/audio/audio_parameters.h new file mode 100644 index 0000000..b7b8ae5 --- /dev/null +++ b/media/audio/audio_parameters.h @@ -0,0 +1,38 @@ +// Copyright (c) 2010 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. + +#ifndef MEDIA_AUDIO_AUDIO_PARAMETERS_H_ +#define MEDIA_AUDIO_AUDIO_PARAMETERS_H_ + +#include "base/basictypes.h" + +struct AudioParameters { + enum Format { + AUDIO_PCM_LINEAR = 0, // PCM is 'raw' amplitude samples. + AUDIO_PCM_LOW_LATENCY, // Linear PCM, low latency requested. + AUDIO_MOCK, // Creates a dummy AudioOutputStream object. + AUDIO_LAST_FORMAT // Only used for validation of format. + }; + + // Telephone quality sample rate, mostly for speech-only audio. + static const uint32 kTelephoneSampleRate = 8000; + // CD sampling rate is 44.1 KHz or conveniently 2x2x3x3x5x5x7x7. + static const uint32 kAudioCDSampleRate = 44100; + // Digital Audio Tape sample rate. + static const uint32 kAudioDATSampleRate = 48000; + + AudioParameters(); + + AudioParameters(Format format, int channels, + int sample_rate, int bits_per_sample); + + bool IsValid() const; + + Format format; // Format of the stream. + int channels; // Number of channels. + int sample_rate; // Sampling frequency/rate. + int bits_per_sample; // Number of bits per sample. +}; + +#endif // MEDIA_AUDIO_AUDIO_PARAMETERS_H_ diff --git a/media/audio/fake_audio_input_stream.cc b/media/audio/fake_audio_input_stream.cc index d631fb8..c0e4529 100644 --- a/media/audio/fake_audio_input_stream.cc +++ b/media/audio/fake_audio_input_stream.cc @@ -7,21 +7,18 @@ using base::Time; using base::TimeDelta; -AudioInputStream* FakeAudioInputStream::MakeFakeStream(int channels, - int bits_per_sample, - int sampling_rate, +AudioInputStream* FakeAudioInputStream::MakeFakeStream(AudioParameters params, int samples_per_packet) { - return new FakeAudioInputStream(channels, bits_per_sample, sampling_rate, - samples_per_packet); + return new FakeAudioInputStream(params, samples_per_packet); } -FakeAudioInputStream::FakeAudioInputStream(int channels, int bits_per_sample, - int sampling_rate, +FakeAudioInputStream::FakeAudioInputStream(AudioParameters params, int samples_per_packet) : callback_(NULL), - buffer_size_((channels * bits_per_sample * samples_per_packet) / 8), + buffer_size_((params.channels * params.bits_per_sample * + samples_per_packet) / 8), thread_("FakeAudioRecordingThread"), - callback_interval_ms_((samples_per_packet * 1000) / sampling_rate) { + callback_interval_ms_((samples_per_packet * 1000) / params.sample_rate) { // This object is ref counted (so that it can be used with Thread, PostTask) // but the caller expects a plain pointer. So we take a reference here and // will Release() ourselves in Close(). diff --git a/media/audio/fake_audio_input_stream.h b/media/audio/fake_audio_input_stream.h index 1cca917..036503d 100644 --- a/media/audio/fake_audio_input_stream.h +++ b/media/audio/fake_audio_input_stream.h @@ -14,13 +14,14 @@ #include "base/thread.h" #include "base/time.h" #include "media/audio/audio_io.h" +#include "media/audio/audio_parameters.h" class FakeAudioInputStream : public AudioInputStream, public base::RefCountedThreadSafe<FakeAudioInputStream> { public: - static AudioInputStream* MakeFakeStream(int channels, int bits_per_sample, - int sampling_rate, int samples_per_packet); + static AudioInputStream* MakeFakeStream(AudioParameters params, + int samples_per_packet); virtual bool Open(); virtual void Start(AudioInputCallback* callback); @@ -31,8 +32,7 @@ class FakeAudioInputStream : // Give RefCountedThreadSafe access our destructor. friend class base::RefCountedThreadSafe<FakeAudioInputStream>; - FakeAudioInputStream(int channels, int bits_per_sample, int sampling_rate, - int samples_per_packet); + FakeAudioInputStream(AudioParameters params, int samples_per_packet); virtual ~FakeAudioInputStream() {} void DoCallback(); @@ -48,4 +48,3 @@ class FakeAudioInputStream : }; #endif // MEDIA_AUDIO_FAKE_AUDIO_INPUT_STREAM_H_ - diff --git a/media/audio/fake_audio_input_stream_unittest.cc b/media/audio/fake_audio_input_stream_unittest.cc index 473ed10..eee8c92 100644 --- a/media/audio/fake_audio_input_stream_unittest.cc +++ b/media/audio/fake_audio_input_stream_unittest.cc @@ -41,7 +41,7 @@ TEST(FakeAudioInputTest, BasicCallbacks) { ASSERT_TRUE(NULL != audio_man); // Ask for one recorded packet every 50ms. AudioInputStream* stream = audio_man->MakeAudioInputStream( - AudioManager::AUDIO_MOCK, 2, 8000, 8, 400); + AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8), 400); ASSERT_TRUE(NULL != stream); EXPECT_TRUE(stream->Open()); stream->Start(&callback); diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc index e8ebc5c..e3670d8 100644 --- a/media/audio/linux/alsa_output.cc +++ b/media/audio/linux/alsa_output.cc @@ -117,7 +117,7 @@ namespace { // ALSA is currently limited to 48Khz. // TODO(fbarchard): Resample audio from higher frequency to 48000. -const uint32 kMaxSampleRate = 48000; +const int kAlsaMaxSampleRate = 48000; snd_pcm_format_t BitsToFormat(char bits_per_sample) { switch (bits_per_sample) { @@ -237,20 +237,17 @@ std::ostream& operator<<(std::ostream& os, } AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name, - AudioManager::Format format, - uint32 channels, - uint32 sample_rate, - uint32 bits_per_sample, + AudioParameters params, AlsaWrapper* wrapper, AudioManagerLinux* manager, MessageLoop* message_loop) : shared_data_(MessageLoop::current()), requested_device_name_(device_name), - pcm_format_(BitsToFormat(bits_per_sample)), - channels_(channels), - sample_rate_(sample_rate), - bytes_per_sample_(bits_per_sample / 8), - bytes_per_frame_(channels_ * bits_per_sample / 8), + pcm_format_(BitsToFormat(params.bits_per_sample)), + channels_(params.channels), + sample_rate_(params.sample_rate), + bytes_per_sample_(params.bits_per_sample / 8), + bytes_per_frame_(channels_ * params.bits_per_sample / 8), should_downmix_(false), latency_micros_(0), micros_per_packet_(0), @@ -265,18 +262,18 @@ AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name, message_loop_(message_loop) { // Sanity check input values. - if ((sample_rate > kMaxSampleRate) || (sample_rate <= 0)) { + if ((params.sample_rate > kAlsaMaxSampleRate) || (params.sample_rate <= 0)) { LOG(WARNING) << "Unsupported audio frequency."; shared_data_.TransitionTo(kInError); } - if (AudioManager::AUDIO_PCM_LINEAR != format) { + if (AudioParameters::AUDIO_PCM_LINEAR != params.format) { LOG(WARNING) << "Only linear PCM supported."; shared_data_.TransitionTo(kInError); } if (pcm_format_ == SND_PCM_FORMAT_UNKNOWN) { - LOG(WARNING) << "Unsupported bits per sample: " << bits_per_sample; + LOG(WARNING) << "Unsupported bits per sample: " << params.bits_per_sample; shared_data_.TransitionTo(kInError); } } diff --git a/media/audio/linux/alsa_output.h b/media/audio/linux/alsa_output.h index f98f2c0..f6fd0d6 100644 --- a/media/audio/linux/alsa_output.h +++ b/media/audio/linux/alsa_output.h @@ -37,7 +37,7 @@ #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "media/audio/audio_io.h" -#include "media/audio/audio_manager_base.h" +#include "media/audio/audio_parameters.h" namespace media { class SeekableBuffer; @@ -45,6 +45,7 @@ class SeekableBuffer; class AlsaWrapper; class AudioManagerLinux; +class MessageLoop; class AlsaPcmOutputStream : public AudioOutputStream, @@ -72,10 +73,7 @@ class AlsaPcmOutputStream : // // If unsure of what to use for |device_name|, use |kAutoSelectDevice|. AlsaPcmOutputStream(const std::string& device_name, - AudioManager::Format format, - uint32 channels, - uint32 sample_rate, - uint32 bits_per_sample, + AudioParameters params, AlsaWrapper* wrapper, AudioManagerLinux* manager, MessageLoop* message_loop); diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc index 7d3a283..23d86d32 100644 --- a/media/audio/linux/alsa_output_unittest.cc +++ b/media/audio/linux/alsa_output_unittest.cc @@ -71,12 +71,10 @@ class MockAudioManagerLinux : public AudioManagerLinux { MOCK_METHOD0(Init, void()); MOCK_METHOD0(HasAudioOutputDevices, bool()); MOCK_METHOD0(HasAudioInputDevices, bool()); - MOCK_METHOD4(MakeAudioOutputStream, AudioOutputStream*(Format format, - int channels, - int sample_rate, - char bits_per_sample)); + MOCK_METHOD1(MakeAudioOutputStream, AudioOutputStream*( + AudioParameters params)); MOCK_METHOD5(MakeAudioInputStream, AudioInputStream*( - Format format, + AudioParameters::Format format, int channels, int sample_rate, char bits_per_sample, @@ -98,11 +96,10 @@ class AlsaPcmOutputStreamTest : public testing::Test { } AlsaPcmOutputStream* CreateStreamWithChannels(int channels) { + AudioParameters params(kTestFormat, channels, kTestSampleRate, + kTestBitsPerSample); return new AlsaPcmOutputStream(kTestDeviceName, - kTestFormat, - channels, - kTestSampleRate, - kTestBitsPerSample, + params, &mock_alsa_wrapper_, &mock_manager_, &message_loop_); @@ -131,7 +128,7 @@ class AlsaPcmOutputStreamTest : public testing::Test { static const int kTestSampleRate; static const int kTestBitsPerSample; static const int kTestBytesPerFrame; - static const AudioManager::Format kTestFormat; + static const AudioParameters::Format kTestFormat; static const char kTestDeviceName[]; static const char kDummyMessage[]; static const uint32 kTestFramesPerPacket; @@ -160,13 +157,13 @@ class AlsaPcmOutputStreamTest : public testing::Test { const int AlsaPcmOutputStreamTest::kTestChannels = 2; const int AlsaPcmOutputStreamTest::kTestSampleRate = - AudioManager::kAudioCDSampleRate; + AudioParameters::kAudioCDSampleRate; const int AlsaPcmOutputStreamTest::kTestBitsPerSample = 8; const int AlsaPcmOutputStreamTest::kTestBytesPerFrame = AlsaPcmOutputStreamTest::kTestBitsPerSample / 8 * AlsaPcmOutputStreamTest::kTestChannels; -const AudioManager::Format AlsaPcmOutputStreamTest::kTestFormat = - AudioManager::AUDIO_PCM_LINEAR; +const AudioParameters::Format AlsaPcmOutputStreamTest::kTestFormat = + AudioParameters::AUDIO_PCM_LINEAR; const char AlsaPcmOutputStreamTest::kTestDeviceName[] = "TestDevice"; const char AlsaPcmOutputStreamTest::kDummyMessage[] = "dummy"; const uint32 AlsaPcmOutputStreamTest::kTestFramesPerPacket = 1000; @@ -202,11 +199,10 @@ TEST_F(AlsaPcmOutputStreamTest, ConstructedState) { test_stream_->shared_data_.state()); // Bad bits per sample. + AudioParameters bad_bps_params(kTestFormat, kTestChannels, + kTestSampleRate, kTestBitsPerSample - 1); test_stream_ = new AlsaPcmOutputStream(kTestDeviceName, - kTestFormat, - kTestChannels, - kTestSampleRate, - kTestBitsPerSample - 1, + bad_bps_params, &mock_alsa_wrapper_, &mock_manager_, &message_loop_); @@ -214,11 +210,11 @@ TEST_F(AlsaPcmOutputStreamTest, ConstructedState) { test_stream_->shared_data_.state()); // Bad format. + AudioParameters bad_format_params( + AudioParameters::AUDIO_LAST_FORMAT, kTestChannels, + kTestSampleRate, kTestBitsPerSample); test_stream_ = new AlsaPcmOutputStream(kTestDeviceName, - AudioManager::AUDIO_LAST_FORMAT, - kTestChannels, - kTestSampleRate, - kTestBitsPerSample, + bad_format_params, &mock_alsa_wrapper_, &mock_manager_, &message_loop_); diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc index 713a753..00f23b1a 100644 --- a/media/audio/linux/audio_manager_linux.cc +++ b/media/audio/linux/audio_manager_linux.cc @@ -23,29 +23,11 @@ bool AudioManagerLinux::HasAudioInputDevices() { return false; } -AudioInputStream* AudioManagerLinux::MakeAudioInputStream( - Format format, - int channels, - int sample_rate, - char bits_per_sample, - uint32 samples_per_packet) { - if (format == AUDIO_MOCK) { - return FakeAudioInputStream::MakeFakeStream(channels, bits_per_sample, - sample_rate, - samples_per_packet); - } - // TODO(satish): implement. - return NULL; -} - AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream( - Format format, - int channels, - int sample_rate, - char bits_per_sample) { + AudioParameters params) { // Early return for testing hook. Do this before checking for // |initialized_|. - if (format == AudioManager::AUDIO_MOCK) { + if (params.format == AudioParameters::AUDIO_MOCK) { return FakeAudioOutputStream::MakeFakeStream(); } @@ -59,8 +41,7 @@ AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream( switches::kAlsaDevice); } AlsaPcmOutputStream* stream = - new AlsaPcmOutputStream(device_name, format, channels, sample_rate, - bits_per_sample, wrapper_.get(), this, + new AlsaPcmOutputStream(device_name, params, wrapper_.get(), this, GetMessageLoop()); AutoLock l(lock_); @@ -68,6 +49,15 @@ AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream( return stream; } +AudioInputStream* AudioManagerLinux::MakeAudioInputStream( + AudioParameters params, uint32 samples_per_packet) { + if (params.format == AudioParameters::AUDIO_MOCK) { + return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet); + } + // TODO(satish): implement. + return NULL; +} + AudioManagerLinux::AudioManagerLinux() { } diff --git a/media/audio/linux/audio_manager_linux.h b/media/audio/linux/audio_manager_linux.h index 2703eed..f13e1a8 100644 --- a/media/audio/linux/audio_manager_linux.h +++ b/media/audio/linux/audio_manager_linux.h @@ -26,21 +26,16 @@ class AudioManagerLinux : public AudioManagerBase { // Implementation of AudioManager. virtual bool HasAudioOutputDevices(); virtual bool HasAudioInputDevices(); - virtual AudioOutputStream* MakeAudioOutputStream(Format format, int channels, - int sample_rate, - char bits_per_sample); - virtual AudioInputStream* MakeAudioInputStream(Format format, int channels, - int sample_rate, - char bits_per_sample, - uint32 samples_per_packet); + virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params); + virtual AudioInputStream* MakeAudioInputStream( + AudioParameters params, uint32 samples_per_packet); + virtual void MuteAll(); virtual void UnMuteAll(); virtual void ReleaseOutputStream(AlsaPcmOutputStream* stream); protected: - // Friend function for invoking the destructor at exit. - friend void DestroyAudioManagerLinux(void*); virtual ~AudioManagerLinux(); private: diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc index 2202484..9705cb30 100644 --- a/media/audio/mac/audio_input_mac.cc +++ b/media/audio/mac/audio_input_mac.cc @@ -18,9 +18,7 @@ enum { PCMQueueInAudioInputStream::PCMQueueInAudioInputStream( AudioManagerMac* manager, - int channels, - int sampling_rate, - char bits_per_sample, + AudioParameters params, uint32 samples_per_buffer) : manager_(manager), callback_(NULL), @@ -31,14 +29,14 @@ PCMQueueInAudioInputStream::PCMQueueInAudioInputStream( // A frame is one sample across all channels. In interleaved audio the per // frame fields identify the set of n |channels|. In uncompressed audio, a // packet is always one frame. - format_.mSampleRate = sampling_rate; + format_.mSampleRate = params.sample_rate; format_.mFormatID = kAudioFormatLinearPCM; format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; - format_.mBitsPerChannel = bits_per_sample; - format_.mChannelsPerFrame = channels; + format_.mBitsPerChannel = params.bits_per_sample; + format_.mChannelsPerFrame = params.channels; format_.mFramesPerPacket = 1; - format_.mBytesPerPacket = (bits_per_sample * channels) / 8; + format_.mBytesPerPacket = (params.bits_per_sample * params.channels) / 8; format_.mBytesPerFrame = format_.mBytesPerPacket; buffer_size_bytes_ = format_.mBytesPerFrame * samples_per_buffer; diff --git a/media/audio/mac/audio_input_mac.h b/media/audio/mac/audio_input_mac.h index 9615d18..c232d85 100644 --- a/media/audio/mac/audio_input_mac.h +++ b/media/audio/mac/audio_input_mac.h @@ -9,6 +9,7 @@ #include <AudioToolbox/AudioFormat.h> #include "media/audio/audio_io.h" +#include "media/audio/audio_parameters.h" class AudioManagerMac; @@ -18,9 +19,7 @@ class PCMQueueInAudioInputStream : public AudioInputStream { public: // Parameters as per AudioManager::MakeAudioInputStream. PCMQueueInAudioInputStream(AudioManagerMac* manager, - int channels, - int sampling_rate, - char bits_per_sample, + AudioParameters params, uint32 samples_per_packet); virtual ~PCMQueueInAudioInputStream(); diff --git a/media/audio/mac/audio_input_mac_unittest.cc b/media/audio/mac/audio_input_mac_unittest.cc index fe6b9a4..da0c918 100644 --- a/media/audio/mac/audio_input_mac_unittest.cc +++ b/media/audio/mac/audio_input_mac_unittest.cc @@ -34,9 +34,11 @@ class AudioInputStreamMacTest : public testing::Test { ias_ = NULL; AudioManager* audio_man = AudioManager::GetAudioManager(); ASSERT_TRUE(NULL != audio_man); - if (audio_man->HasAudioInputDevices()) - ias_ = audio_man->MakeAudioInputStream(AudioManager::AUDIO_PCM_LINEAR, 2, - kSampleRate, 16, kSamplesPerCall); + if (audio_man->HasAudioInputDevices()) { + AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, 2, + kSampleRate, 16); + ias_ = audio_man->MakeAudioInputStream(params, kSamplesPerCall); + } } virtual void TearDown() { ias_->Close(); diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc index a82af0b..dde2917 100644 --- a/media/audio/mac/audio_manager_mac.cc +++ b/media/audio/mac/audio_manager_mac.cc @@ -38,33 +38,21 @@ bool AudioManagerMac::HasAudioInputDevices() { return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice); } -AudioInputStream* AudioManagerMac::MakeAudioInputStream( - Format format, - int channels, - int sample_rate, - char bits_per_sample, - uint32 samples_per_packet) { - if (format == AUDIO_MOCK) { - return FakeAudioInputStream::MakeFakeStream(channels, bits_per_sample, - sample_rate, - samples_per_packet); - } else if (format == AUDIO_PCM_LINEAR) { - return new PCMQueueInAudioInputStream(this, channels, sample_rate, - bits_per_sample, samples_per_packet); - } - return NULL; -} - AudioOutputStream* AudioManagerMac::MakeAudioOutputStream( - Format format, - int channels, - int sample_rate, - char bits_per_sample) { - if (format == AUDIO_MOCK) { + AudioParameters params) { + if (params.format == AudioParameters::AUDIO_MOCK) return FakeAudioOutputStream::MakeFakeStream(); - } else if (format == AUDIO_PCM_LINEAR) { - return new PCMQueueOutAudioOutputStream(this, channels, sample_rate, - bits_per_sample); + else if (params.format != AudioParameters::AUDIO_PCM_LINEAR) + return NULL; + return new PCMQueueOutAudioOutputStream(this, params); +} + +AudioInputStream* AudioManagerMac::MakeAudioInputStream( + AudioParameters params, uint32 samples_per_packet) { + if (params.format == AudioParameters::AUDIO_MOCK) { + return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet); + } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { + return new PCMQueueInAudioInputStream(this, params, samples_per_packet); } return NULL; } diff --git a/media/audio/mac/audio_manager_mac.h b/media/audio/mac/audio_manager_mac.h index 3d720c5..53df700 100644 --- a/media/audio/mac/audio_manager_mac.h +++ b/media/audio/mac/audio_manager_mac.h @@ -21,12 +21,8 @@ class AudioManagerMac : public AudioManagerBase { // Implementation of AudioManager. virtual bool HasAudioOutputDevices(); virtual bool HasAudioInputDevices(); - virtual AudioOutputStream* MakeAudioOutputStream(Format format, int channels, - int sample_rate, - char bits_per_sample); - virtual AudioInputStream* MakeAudioInputStream(Format format, int channels, - int sample_rate, - char bits_per_sample, + virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params); + virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, uint32 samples_per_packet); virtual void MuteAll(); virtual void UnMuteAll(); diff --git a/media/audio/mac/audio_output_mac.cc b/media/audio/mac/audio_output_mac.cc index cd7c8eba..45de9a7 100644 --- a/media/audio/mac/audio_output_mac.cc +++ b/media/audio/mac/audio_output_mac.cc @@ -44,8 +44,7 @@ enum { #endif PCMQueueOutAudioOutputStream::PCMQueueOutAudioOutputStream( - AudioManagerMac* manager, int channels, int sampling_rate, - char bits_per_sample) + AudioManagerMac* manager, AudioParameters params) : format_(), audio_queue_(NULL), buffer_(), @@ -59,20 +58,20 @@ PCMQueueOutAudioOutputStream::PCMQueueOutAudioOutputStream( // A frame is one sample across all channels. In interleaved audio the per // frame fields identify the set of n |channels|. In uncompressed audio, a // packet is always one frame. - format_.mSampleRate = sampling_rate; + format_.mSampleRate = params.sample_rate; format_.mFormatID = kAudioFormatLinearPCM; format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; - format_.mBitsPerChannel = bits_per_sample; - format_.mChannelsPerFrame = channels; + format_.mBitsPerChannel = params.bits_per_sample; + format_.mChannelsPerFrame = params.channels; format_.mFramesPerPacket = 1; - format_.mBytesPerPacket = (format_.mBitsPerChannel * channels) / 8; + format_.mBytesPerPacket = (format_.mBitsPerChannel * params.channels) / 8; format_.mBytesPerFrame = format_.mBytesPerPacket; // Silence buffer has a duration of 6ms to simulate the behavior of Windows. // This value is choosen by experiments and macs cannot keep up with // anything less than 6ms. - silence_bytes_ = format_.mBytesPerFrame * sampling_rate * 6 / 1000; + silence_bytes_ = format_.mBytesPerFrame * params.sample_rate * 6 / 1000; } PCMQueueOutAudioOutputStream::~PCMQueueOutAudioOutputStream() { diff --git a/media/audio/mac/audio_output_mac.h b/media/audio/mac/audio_output_mac.h index 636e63b..60cf2b6 100644 --- a/media/audio/mac/audio_output_mac.h +++ b/media/audio/mac/audio_output_mac.h @@ -9,6 +9,7 @@ #include <AudioToolbox/AudioQueue.h> #include "media/audio/audio_io.h" +#include "media/audio/audio_parameters.h" class AudioManagerMac; @@ -20,8 +21,7 @@ class PCMQueueOutAudioOutputStream : public AudioOutputStream { // The ctor takes all the usual parameters, plus |manager| which is the // the audio manager who is creating this object. PCMQueueOutAudioOutputStream(AudioManagerMac* manager, - int channels, int sampling_rate, - char bits_per_sample); + AudioParameters params); // The dtor is typically called by the AudioManager only and it is usually // triggered by calling AudioOutputStream::Close(). virtual ~PCMQueueOutAudioOutputStream(); diff --git a/media/audio/mac/audio_output_mac_unittest.cc b/media/audio/mac/audio_output_mac_unittest.cc index 1d64066..892dafe 100644 --- a/media/audio/mac/audio_output_mac_unittest.cc +++ b/media/audio/mac/audio_output_mac_unittest.cc @@ -33,7 +33,7 @@ TEST(MacAudioTest, SineWaveAudio16MonoTest) { const int freq = 200; SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, - freq, AudioManager::kTelephoneSampleRate); + freq, AudioParameters::kTelephoneSampleRate); // TODO(cpu): Put the real test when the mock renderer is ported. int16 buffer[samples] = { 0xffff }; @@ -43,7 +43,7 @@ TEST(MacAudioTest, SineWaveAudio16MonoTest) { } // =========================================================================== -// Validation of AudioManager::AUDIO_PCM_LINEAR +// Validation of AudioParameters::AUDIO_PCM_LINEAR // // Unlike windows, the tests can reliably detect the existense of real // audio devices on the bots thus no need for 'headless' detection. @@ -54,9 +54,8 @@ TEST(MacAudioTest, PCMWaveStreamGetAndClose) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; - AudioOutputStream* oas = - audio_man->MakeAudioOutputStream(AudioManager::AUDIO_PCM_LINEAR, 2, - 8000, 16); + AudioOutputStream* oas = audio_man->MakeAudioOutputStream( + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16)); ASSERT_TRUE(NULL != oas); oas->Close(); } @@ -67,9 +66,8 @@ TEST(MacAudioTest, PCMWaveStreamOpenAndClose) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; - AudioOutputStream* oas = - audio_man->MakeAudioOutputStream(AudioManager::AUDIO_PCM_LINEAR, 2, - 8000, 16); + AudioOutputStream* oas = audio_man->MakeAudioOutputStream( + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16)); ASSERT_TRUE(NULL != oas); EXPECT_TRUE(oas->Open(1024)); oas->Close(); @@ -84,14 +82,14 @@ TEST(MacAudioTest, PCMWaveStreamPlay200HzTone44KssMono) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; - AudioOutputStream* oas = - audio_man->MakeAudioOutputStream(AudioManager::AUDIO_PCM_LINEAR, 1, - AudioManager::kAudioCDSampleRate, 16); + AudioOutputStream* oas = audio_man->MakeAudioOutputStream( + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, + AudioParameters::kAudioCDSampleRate, 16)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, - 200.0, AudioManager::kAudioCDSampleRate); - uint32 bytes_100_ms = (AudioManager::kAudioCDSampleRate / 10) * 2; + 200.0, AudioParameters::kAudioCDSampleRate); + uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; EXPECT_TRUE(oas->Open(bytes_100_ms)); @@ -117,14 +115,14 @@ TEST(MacAudioTest, PCMWaveStreamPlay200HzTone22KssMono) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; - AudioOutputStream* oas = - audio_man->MakeAudioOutputStream(AudioManager::AUDIO_PCM_LINEAR, 1, - AudioManager::kAudioCDSampleRate/2, 16); + AudioOutputStream* oas = audio_man->MakeAudioOutputStream( + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, + AudioParameters::kAudioCDSampleRate / 2, 16)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, - 200.0, AudioManager::kAudioCDSampleRate/2); - uint32 bytes_100_ms = (AudioManager::kAudioCDSampleRate / 20) * 2; + 200.0, AudioParameters::kAudioCDSampleRate/2); + uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 20) * 2; EXPECT_TRUE(oas->Open(bytes_100_ms)); oas->Start(&source); @@ -144,13 +142,13 @@ TEST(MacAudioTest, PCMWaveStreamPendingBytes) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; - AudioOutputStream* oas = - audio_man->MakeAudioOutputStream(AudioManager::AUDIO_PCM_LINEAR, 1, - AudioManager::kAudioCDSampleRate, 16); + AudioOutputStream* oas = audio_man->MakeAudioOutputStream( + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, + AudioParameters::kAudioCDSampleRate, 16)); ASSERT_TRUE(NULL != oas); NiceMock<MockAudioSource> source; - uint32 bytes_100_ms = (AudioManager::kAudioCDSampleRate / 10) * 2; + uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; EXPECT_TRUE(oas->Open(bytes_100_ms)); // We expect the amount of pending bytes will reaching |bytes_100_ms| diff --git a/media/audio/simple_sources_unittest.cc b/media/audio/simple_sources_unittest.cc index 029d565..dd65e36 100644 --- a/media/audio/simple_sources_unittest.cc +++ b/media/audio/simple_sources_unittest.cc @@ -72,14 +72,14 @@ TEST(SimpleSources, SineWaveAudio16MonoTest) { const int freq = 200; SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, - freq, AudioManager::kTelephoneSampleRate); + freq, AudioParameters::kTelephoneSampleRate); AudioManager* audio_man = AudioManager::GetAudioManager(); ASSERT_TRUE(NULL != audio_man); - AudioOutputStream* oas = - audio_man->MakeAudioOutputStream(AudioManager::AUDIO_MOCK, 1, - AudioManager::kTelephoneSampleRate, - bytes_per_sample * 2); + AudioParameters params( + AudioParameters::AUDIO_MOCK, 1, AudioParameters::kTelephoneSampleRate, + bytes_per_sample * 2); + AudioOutputStream* oas = audio_man->MakeAudioOutputStream(params); ASSERT_TRUE(NULL != oas); EXPECT_TRUE(oas->Open(samples * bytes_per_sample)); @@ -93,7 +93,7 @@ TEST(SimpleSources, SineWaveAudio16MonoTest) { FakeAudioOutputStream::GetLastFakeStream()->buffer()); ASSERT_TRUE(NULL != last_buffer); - uint32 half_period = AudioManager::kTelephoneSampleRate / (freq * 2); + uint32 half_period = AudioParameters::kTelephoneSampleRate / (freq * 2); // Spot test positive incursion of sine wave. EXPECT_EQ(0, last_buffer[0]); diff --git a/media/audio/test_audio_input_controller_factory.cc b/media/audio/test_audio_input_controller_factory.cc index c56afd8..99980bf 100644 --- a/media/audio/test_audio_input_controller_factory.cc +++ b/media/audio/test_audio_input_controller_factory.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -25,10 +25,7 @@ TestAudioInputControllerFactory::TestAudioInputControllerFactory() AudioInputController* TestAudioInputControllerFactory::Create( AudioInputController::EventHandler* event_handler, - AudioManager::Format format, - int channels, - int sample_rate, - int bits_per_sample, + AudioParameters params, int samples_per_packet) { DCHECK(!controller_); // Only one test instance managed at a time. controller_ = new TestAudioInputController(this, event_handler); diff --git a/media/audio/test_audio_input_controller_factory.h b/media/audio/test_audio_input_controller_factory.h index bd8f7b9..0d14828 100644 --- a/media/audio/test_audio_input_controller_factory.h +++ b/media/audio/test_audio_input_controller_factory.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -74,10 +74,7 @@ class TestAudioInputControllerFactory : public AudioInputController::Factory { // AudioInputController::Factory methods. AudioInputController* Create( AudioInputController::EventHandler* event_handler, - AudioManager::Format format, - int channels, - int sample_rate, - int bits_per_sample, + AudioParameters params, int samples_per_packet); TestAudioInputController* controller() const { return controller_; } diff --git a/media/audio/win/audio_input_win_unittest.cc b/media/audio/win/audio_input_win_unittest.cc index b3841cb..39cc3fba 100644 --- a/media/audio/win/audio_input_win_unittest.cc +++ b/media/audio/win/audio_input_win_unittest.cc @@ -98,17 +98,23 @@ TEST(WinAudioInputTest, SanityOnMakeParams) { if (!CanRunAudioTests()) return; AudioManager* audio_man = AudioManager::GetAudioManager(); - AudioManager::Format fmt = AudioManager::AUDIO_PCM_LINEAR; - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 8, 8000, 16, 0)); - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 1, 1024 * 1024, 16, - 0)); - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 2, 8000, 80, 0)); - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 2, 8000, 80, - 1024 * 4096)); - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, -2, 8000, 16, 0)); - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 2, -8000, 16, 0)); - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 2, 8000, -16, 0)); - EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 2, 8000, 16, -1024)); + AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR; + EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( + AudioParameters(fmt, 8, 8000, 16), 0)); + EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( + AudioParameters(fmt, 1, 1024 * 1024, 16), 0)); + EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( + AudioParameters(fmt, 2, 8000, 80), 0)); + EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( + AudioParameters(fmt, 2, 8000, 80), 1024 * 4096)); + EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( + AudioParameters(fmt, -2, 8000, 16), 0)); + EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( + AudioParameters(fmt, 2, -8000, 16), 0)); + EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( + AudioParameters(fmt, 2, 8000, -16), 0)); + EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( + AudioParameters(fmt, 2, 8000, 16), -1024)); } // Test create and close of an AudioInputStream without recording audio. @@ -117,7 +123,7 @@ TEST(WinAudioInputTest, CreateAndClose) { return; AudioManager* audio_man = AudioManager::GetAudioManager(); AudioInputStream* ais = audio_man->MakeAudioInputStream( - AudioManager::AUDIO_PCM_LINEAR, 2, 8000, 16, 0); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16), 0); ASSERT_TRUE(NULL != ais); ais->Close(); } @@ -128,7 +134,7 @@ TEST(WinAudioInputTest, OpenAndClose) { return; AudioManager* audio_man = AudioManager::GetAudioManager(); AudioInputStream* ais = audio_man->MakeAudioInputStream( - AudioManager::AUDIO_PCM_LINEAR, 2, 8000, 16, 0); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16), 0); ASSERT_TRUE(NULL != ais); EXPECT_TRUE(ais->Open()); ais->Close(); @@ -142,7 +148,8 @@ TEST(WinAudioInputTest, Record) { const int kSamplingRate = 8000; const int kSamplesPerPacket = kSamplingRate / 20; AudioInputStream* ais = audio_man->MakeAudioInputStream( - AudioManager::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16, kSamplesPerPacket); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16), + kSamplesPerPacket); ASSERT_TRUE(NULL != ais); EXPECT_TRUE(ais->Open()); @@ -166,7 +173,8 @@ TEST(WinAudioInputTest, RecordWithSlowSink) { const int kSamplingRate = 8000; const int kSamplesPerPacket = kSamplingRate / 20; AudioInputStream* ais = audio_man->MakeAudioInputStream( - AudioManager::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16, kSamplesPerPacket); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16), + kSamplesPerPacket); ASSERT_TRUE(NULL != ais); EXPECT_TRUE(ais->Open()); diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc index 6c4a606..f1c88e3 100644 --- a/media/audio/win/audio_manager_win.cc +++ b/media/audio/win/audio_manager_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -13,27 +13,19 @@ #include "media/audio/win/audio_manager_win.h" #include "media/audio/win/wavein_input_win.h" #include "media/audio/win/waveout_output_win.h" +#include "media/base/limits.h" namespace { -// The next 3 constants are some sensible limits to prevent integer overflow -// at this layer. // Up to 6 channels can be passed to the driver. // This should work, given the right drivers, but graceful error handling is // needed. // In theory 7.1 could also be supported, but it has not been tested. -// The 192 Khz constant is the frequency of quicktime lossless audio codec. -// MP4 is limited to 96 Khz, and mp3 is limited to 48 Khz. -// OGG vorbis was initially limited to 96 Khz, but recent tools are unlimited. -// 192 Khz is also the limit on most PC audio hardware. The minimum is 100 Hz. -// Humans range is 20 to 20000 Hz. Below 20 can be felt (woofer). - -const int kMaxChannels = 6; -const int kMaxSampleRate = 192000; -const int kMaxBitsPerSample = 64; - -const int kMaxInputChannels = 2; -const int kMaxSamplesPerPacket = kMaxSampleRate; +// TODO(sergeyu): Test that 7.1 audio works. +const int kWinMaxChannels = 6; + +const int kWinMaxInputChannels = 2; +const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate; // We use 3 buffers for recording audio so that if a recording callback takes // some time to return we won't lose audio. More buffers while recording are // ok because they don't introduce any delay in recording, unlike in playback @@ -56,48 +48,32 @@ bool AudioManagerWin::HasAudioInputDevices() { // - PCMWaveOutAudioOutputStream: Based on the waveOutWrite API (in progress) // - PCMDXSoundAudioOutputStream: Based on DirectSound or XAudio (future work). AudioOutputStream* AudioManagerWin::MakeAudioOutputStream( - Format format, - int channels, - int sample_rate, - char bits_per_sample) { - if ((channels > kMaxChannels) || (channels <= 0) || - (sample_rate > kMaxSampleRate) || (sample_rate <= 0) || - (bits_per_sample > kMaxBitsPerSample) || (bits_per_sample <= 0)) + AudioParameters params) { + if (!params.IsValid() || (params.channels > kWinMaxChannels)) return NULL; - if (format == AUDIO_MOCK) { + if (params.format == AudioParameters::AUDIO_MOCK) { return FakeAudioOutputStream::MakeFakeStream(); - } else if (format == AUDIO_PCM_LINEAR) { - return new PCMWaveOutAudioOutputStream(this, channels, sample_rate, 3, - bits_per_sample, WAVE_MAPPER); - } else if (format == AUDIO_PCM_LOW_LATENCY) { + } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { + return new PCMWaveOutAudioOutputStream(this, params, 3, WAVE_MAPPER); + } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) { // TODO(cpu): waveout cannot hit 20ms latency. Use other method. - return new PCMWaveOutAudioOutputStream(this, channels, sample_rate, 2, - bits_per_sample, WAVE_MAPPER); + return new PCMWaveOutAudioOutputStream(this, params, 2, WAVE_MAPPER); } return NULL; } // Factory for the implementations of AudioInputStream. AudioInputStream* AudioManagerWin::MakeAudioInputStream( - Format format, - int channels, - int sample_rate, - char bits_per_sample, - uint32 samples_per_packet) { - if ((channels > kMaxInputChannels) || (channels <= 0) || - (sample_rate > kMaxSampleRate) || (sample_rate <= 0) || - (bits_per_sample > kMaxBitsPerSample) || (bits_per_sample <= 0) || + AudioParameters params, uint32 samples_per_packet) { + if (!params.IsValid() || (params.channels > kWinMaxInputChannels) || (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0)) return NULL; - if (format == AUDIO_MOCK) { - return FakeAudioInputStream::MakeFakeStream(channels, bits_per_sample, - sample_rate, - samples_per_packet); - } else if (format == AUDIO_PCM_LINEAR) { - return new PCMWaveInAudioInputStream(this, channels, sample_rate, - kNumInputBuffers, bits_per_sample, + if (params.format == AudioParameters::AUDIO_MOCK) { + return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet); + } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { + return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers, samples_per_packet, WAVE_MAPPER); } return NULL; diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h index b8bd579..61c7b33 100644 --- a/media/audio/win/audio_manager_win.h +++ b/media/audio/win/audio_manager_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -22,12 +22,8 @@ class AudioManagerWin : public AudioManagerBase { // Implementation of AudioManager. virtual bool HasAudioOutputDevices(); virtual bool HasAudioInputDevices(); - virtual AudioOutputStream* MakeAudioOutputStream(Format format, int channels, - int sample_rate, - char bits_per_sample); - virtual AudioInputStream* MakeAudioInputStream(Format format, int channels, - int sample_rate, - char bits_per_sample, + virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params); + virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, uint32 samples_per_packet); virtual void MuteAll(); virtual void UnMuteAll(); diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc index 98f763c..01cddf1 100644 --- a/media/audio/win/audio_output_win_unittest.cc +++ b/media/audio/win/audio_output_win_unittest.cc @@ -206,8 +206,8 @@ class ReadOnlyMappedFile { TEST(WinAudioTest, MockStreamBasicCallbacks) { AudioManager* audio_man = AudioManager::GetAudioManager(); ASSERT_TRUE(NULL != audio_man); - AudioOutputStream* oas = - audio_man->MakeAudioOutputStream(AudioManager::AUDIO_MOCK, 2, 8000, 8); + AudioOutputStream* oas = audio_man->MakeAudioOutputStream( + AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8)); ASSERT_TRUE(NULL != oas); EXPECT_TRUE(oas->Open(256)); TestSourceBasic source; @@ -236,7 +236,7 @@ TEST(WinAudioTest, PCMWaveStreamGetAndClose) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 2, 8000, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16)); ASSERT_TRUE(NULL != oas); oas->Close(); } @@ -249,14 +249,19 @@ TEST(WinAudioTest, SanityOnMakeParams) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; - AudioManager::Format fmt = AudioManager::AUDIO_PCM_LINEAR; - EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(fmt, 8, 8000, 16)); - EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(fmt, 1, 1024 * 1024, - 16)); - EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(fmt, 2, 8000, 80)); - EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(fmt, -2, 8000, 16)); - EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(fmt, 2, -8000, 16)); - EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(fmt, 2, -8000, -16)); + AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR; + EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( + AudioParameters(fmt, 8, 8000, 16))); + EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( + AudioParameters(fmt, 1, 1024 * 1024, 16))); + EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( + AudioParameters(fmt, 2, 8000, 80))); + EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( + AudioParameters(fmt, -2, 8000, 16))); + EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( + AudioParameters(fmt, 2, -8000, 16))); + EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( + AudioParameters(fmt, 2, -8000, -16))); } // Test that it can be opened and closed. @@ -268,7 +273,7 @@ TEST(WinAudioTest, PCMWaveStreamOpenAndClose) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 2, 8000, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16)); ASSERT_TRUE(NULL != oas); EXPECT_TRUE(oas->Open(1024)); oas->Close(); @@ -283,7 +288,7 @@ TEST(WinAudioTest, PCMWaveStreamOpenLimit) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 2, 8000, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16)); ASSERT_TRUE(NULL != oas); EXPECT_FALSE(oas->Open(1024 * 1024 * 1024)); oas->Close(); @@ -299,7 +304,7 @@ TEST(WinAudioTest, PCMWaveStreamTripleBuffer) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 1, 16000, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16)); ASSERT_TRUE(NULL != oas); TestSourceTripleBuffer test_triple_buffer; EXPECT_TRUE(oas->Open(512)); @@ -323,7 +328,7 @@ TEST(WinAudioTest, PCMWaveSlowSource) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 1, 16000, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16)); ASSERT_TRUE(NULL != oas); TestSourceLaggy test_laggy(2, 90); EXPECT_TRUE(oas->Open(512)); @@ -349,12 +354,13 @@ TEST(WinAudioTest, PCMWaveStreamPlaySlowLoop) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 1, AudioManager::kAudioCDSampleRate, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, + AudioParameters::kAudioCDSampleRate, 16)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, - 200.0, AudioManager::kAudioCDSampleRate); - uint32 bytes_100_ms = (AudioManager::kAudioCDSampleRate / 10) * 2; + 200.0, AudioParameters::kAudioCDSampleRate); + uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; EXPECT_TRUE(oas->Open(bytes_100_ms)); oas->SetVolume(1.0); @@ -379,12 +385,13 @@ TEST(WinAudioTest, PCMWaveStreamPlay200HzTone44Kss) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 1, AudioManager::kAudioCDSampleRate, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, + AudioParameters::kAudioCDSampleRate, 16)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, - 200.0, AudioManager::kAudioCDSampleRate); - uint32 bytes_100_ms = (AudioManager::kAudioCDSampleRate / 10) * 2; + 200.0, AudioParameters::kAudioCDSampleRate); + uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; EXPECT_TRUE(oas->Open(bytes_100_ms)); oas->SetVolume(1.0); @@ -406,13 +413,13 @@ TEST(WinAudioTest, PCMWaveStreamPlay200HzTone22Kss) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 1, AudioManager::kAudioCDSampleRate/2, - 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, + AudioParameters::kAudioCDSampleRate / 2, 16)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, - 200.0, AudioManager::kAudioCDSampleRate/2); - uint32 bytes_100_ms = (AudioManager::kAudioCDSampleRate / 20) * 2; + 200.0, AudioParameters::kAudioCDSampleRate/2); + uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 20) * 2; EXPECT_TRUE(oas->Open(bytes_100_ms)); @@ -452,7 +459,7 @@ TEST(WinAudioTest, PushSourceFile16KHz) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 1, 16000, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16)); ASSERT_TRUE(NULL != oas); // compute buffer size for 100ms of audio. Which is 3200 bytes. @@ -496,12 +503,13 @@ TEST(WinAudioTest, PCMWaveStreamPlayTwice200HzTone44Kss) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 1, AudioManager::kAudioCDSampleRate, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, + AudioParameters::kAudioCDSampleRate, 16)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, - 200.0, AudioManager::kAudioCDSampleRate); - uint32 bytes_100_ms = (AudioManager::kAudioCDSampleRate / 10) * 2; + 200.0, AudioParameters::kAudioCDSampleRate); + uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; EXPECT_TRUE(oas->Open(bytes_100_ms)); oas->SetVolume(1.0); @@ -534,13 +542,14 @@ TEST(WinAudioTest, PCMWaveStreamPlay200HzTone44KssLowLatency) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LOW_LATENCY, 1, AudioManager::kAudioCDSampleRate, - 16); + AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, 1, + AudioParameters::kAudioCDSampleRate, 16)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, - 200.0, AudioManager::kAudioCDSampleRate); - uint32 bytes_50_ms = (AudioManager::kAudioCDSampleRate / 20) * sizeof(uint16); + 200.0, AudioParameters::kAudioCDSampleRate); + uint32 bytes_50_ms = (AudioParameters::kAudioCDSampleRate / 20) * + sizeof(uint16); EXPECT_TRUE(oas->Open(bytes_50_ms)); oas->SetVolume(1.0); @@ -561,11 +570,12 @@ TEST(WinAudioTest, PCMWaveStreamPendingBytes) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, 1, AudioManager::kAudioCDSampleRate, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, + AudioParameters::kAudioCDSampleRate, 16)); ASSERT_TRUE(NULL != oas); NiceMock<MockAudioSource> source; - uint32 bytes_100_ms = (AudioManager::kAudioCDSampleRate / 10) * 2; + uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; EXPECT_TRUE(oas->Open(bytes_100_ms)); // We expect the amount of pending bytes will reaching 2 times of @@ -642,7 +652,7 @@ DWORD __stdcall SyncSocketThread(void* context) { SyncThreadContext& ctx = *(reinterpret_cast<SyncThreadContext*>(context)); const int kTwoSecBytes = - AudioManager::kAudioCDSampleRate * 2 * sizeof(uint16); + AudioParameters::kAudioCDSampleRate * 2 * sizeof(uint16); char* buffer = new char[kTwoSecBytes]; SineWaveAudioSource sine(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, ctx.sine_freq, ctx.sample_rate); @@ -679,9 +689,10 @@ TEST(WinAudioTest, SyncSocketBasic) { if (!audio_man->HasAudioOutputDevices()) return; - int sample_rate = AudioManager::kAudioCDSampleRate; + int sample_rate = AudioParameters::kAudioCDSampleRate; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LOW_LATENCY, 1, sample_rate, 16); + AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, 1, + sample_rate, 16)); ASSERT_TRUE(NULL != oas); // compute buffer size for 20ms of audio, 882 samples (mono). diff --git a/media/audio/win/wavein_input_win.cc b/media/audio/win/wavein_input_win.cc index 58253c3..b328dcd 100644 --- a/media/audio/win/wavein_input_win.cc +++ b/media/audio/win/wavein_input_win.cc @@ -25,8 +25,8 @@ WAVEHDR* GetNextBuffer(WAVEHDR* current) { } // namespace PCMWaveInAudioInputStream::PCMWaveInAudioInputStream( - AudioManagerWin* manager, int channels, int sampling_rate, int num_buffers, - char bits_per_sample, uint32 samples_per_packet, UINT device_id) + AudioManagerWin* manager, AudioParameters params, int num_buffers, + uint32 samples_per_packet, UINT device_id) : state_(kStateEmpty), manager_(manager), device_id_(device_id), @@ -34,11 +34,11 @@ PCMWaveInAudioInputStream::PCMWaveInAudioInputStream( callback_(NULL), num_buffers_(num_buffers), buffer_(NULL), - channels_(channels) { + channels_(params.channels) { format_.wFormatTag = WAVE_FORMAT_PCM; - format_.nChannels = channels > 2 ? 2 : channels; - format_.nSamplesPerSec = sampling_rate; - format_.wBitsPerSample = bits_per_sample; + format_.nChannels = params.channels > 2 ? 2 : params.channels; + format_.nSamplesPerSec = params.sample_rate; + format_.wBitsPerSample = params.bits_per_sample; format_.cbSize = 0; format_.nBlockAlign = (format_.nChannels * format_.wBitsPerSample) / 8; format_.nAvgBytesPerSec = format_.nBlockAlign * format_.nSamplesPerSec; diff --git a/media/audio/win/wavein_input_win.h b/media/audio/win/wavein_input_win.h index a4ea435..46aa0b6 100644 --- a/media/audio/win/wavein_input_win.h +++ b/media/audio/win/wavein_input_win.h @@ -11,6 +11,7 @@ #include "base/basictypes.h" #include "base/scoped_handle_win.h" #include "media/audio/audio_io.h" +#include "media/audio/audio_parameters.h" class AudioManagerWin; @@ -19,9 +20,8 @@ class PCMWaveInAudioInputStream : public AudioInputStream { // The ctor takes all the usual parameters, plus |manager| which is the // the audio manager who is creating this object and |device_id| which // is provided by the operating system. - PCMWaveInAudioInputStream(AudioManagerWin* manager, int channels, - int sampling_rate, int num_buffers, - char bits_per_sample, uint32 samples_per_packet, + PCMWaveInAudioInputStream(AudioManagerWin* manager, AudioParameters params, + int num_buffers, uint32 samples_per_packet, UINT device_id); virtual ~PCMWaveInAudioInputStream(); diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc index cbd0ddc..819f1b7 100644 --- a/media/audio/win/waveout_output_win.cc +++ b/media/audio/win/waveout_output_win.cc @@ -42,8 +42,8 @@ WAVEHDR* GetNextBuffer(WAVEHDR* current) { } // namespace PCMWaveOutAudioOutputStream::PCMWaveOutAudioOutputStream( - AudioManagerWin* manager, int channels, int sampling_rate, int num_buffers, - char bits_per_sample, UINT device_id) + AudioManagerWin* manager, AudioParameters params, int num_buffers, + UINT device_id) : state_(PCMA_BRAND_NEW), manager_(manager), device_id_(device_id), @@ -53,12 +53,12 @@ PCMWaveOutAudioOutputStream::PCMWaveOutAudioOutputStream( buffer_(NULL), buffer_size_(0), volume_(1), - channels_(channels), + channels_(params.channels), pending_bytes_(0) { format_.wFormatTag = WAVE_FORMAT_PCM; - format_.nChannels = channels > 2 ? 2 : channels; - format_.nSamplesPerSec = sampling_rate; - format_.wBitsPerSample = bits_per_sample; + format_.nChannels = params.channels > 2 ? 2 : params.channels; + format_.nSamplesPerSec = params.sample_rate; + format_.wBitsPerSample = params.bits_per_sample; format_.cbSize = 0; // The next are computed from above. format_.nBlockAlign = (format_.nChannels * format_.wBitsPerSample) / 8; diff --git a/media/audio/win/waveout_output_win.h b/media/audio/win/waveout_output_win.h index d9b47c0..7b87e4e 100644 --- a/media/audio/win/waveout_output_win.h +++ b/media/audio/win/waveout_output_win.h @@ -11,6 +11,7 @@ #include "base/basictypes.h" #include "base/scoped_handle_win.h" #include "media/audio/audio_io.h" +#include "media/audio/audio_parameters.h" class AudioManagerWin; @@ -28,9 +29,8 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream { // The ctor takes all the usual parameters, plus |manager| which is the // the audio manager who is creating this object and |device_id| which // is provided by the operating system. - PCMWaveOutAudioOutputStream(AudioManagerWin* manager, - int channels, int sampling_rate, int num_buffers, - char bits_per_sample, UINT device_id); + PCMWaveOutAudioOutputStream(AudioManagerWin* manager, AudioParameters params, + int num_buffers, UINT device_id); virtual ~PCMWaveOutAudioOutputStream(); // Implementation of AudioOutputStream. diff --git a/media/base/limits.h b/media/base/limits.h index 8694efa..517a5d1 100644 --- a/media/base/limits.h +++ b/media/base/limits.h @@ -16,10 +16,14 @@ struct Limits { static const size_t kMaxDimension = (1 << 15) - 1; // 32767 static const size_t kMaxCanvas = (1 << (14 * 2)); // 16384 x 16384 - // For audio. - static const size_t kMaxSampleRate = 192000; - static const size_t kMaxChannels = 32; - static const size_t kMaxBPS = 64; + // Following limits are used by AudioParameters::IsValid(). + // The 192 Khz constant is the frequency of quicktime lossless audio codec. + // MP4 is limited to 96 Khz, and mp3 is limited to 48 Khz. + // OGG vorbis was initially limited to 96 Khz, but recent tools are unlimited. + // 192 Khz is also the limit on most PC audio hardware. + static const int kMaxSampleRate = 192000; + static const int kMaxChannels = 32; + static const int kMaxBitsPerSample = 64; // Maximum possible time. static const int64 kMaxTimeInMicroseconds = kint64max; diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc index 9fd1034..1a2a182 100644 --- a/media/filters/audio_renderer_impl.cc +++ b/media/filters/audio_renderer_impl.cc @@ -79,23 +79,23 @@ void AudioRendererImpl::OnError(AudioOutputStream* stream, int code) { bool AudioRendererImpl::OnInitialize(const MediaFormat& media_format) { // Parse out audio parameters. - int channels; - int sample_rate; - int sample_bits; - if (!ParseMediaFormat(media_format, &channels, &sample_rate, &sample_bits)) { + AudioParameters params; + if (!ParseMediaFormat(media_format, ¶ms.channels, + ¶ms.sample_rate, ¶ms.bits_per_sample)) { return false; } - bytes_per_second_ = sample_rate * channels * sample_bits / 8; + bytes_per_second_ = params.sample_rate * params.channels * + params.bits_per_sample / 8; // Create our audio stream. - stream_ = AudioManager::GetAudioManager()->MakeAudioOutputStream( - AudioManager::AUDIO_PCM_LINEAR, channels, sample_rate, sample_bits); + stream_ = AudioManager::GetAudioManager()->MakeAudioOutputStream(params); if (!stream_) return false; // Calculate buffer size and open the stream. - size_t size = kSamplesPerBuffer * channels * sample_bits / 8; + size_t size = kSamplesPerBuffer * params.channels * + params.bits_per_sample / 8; if (!stream_->Open(size)) { stream_->Close(); stream_ = NULL; diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc index 827b0bc..ba3b5d2 100644 --- a/media/filters/ffmpeg_audio_decoder.cc +++ b/media/filters/ffmpeg_audio_decoder.cc @@ -61,13 +61,11 @@ void FFmpegAudioDecoder::DoInitialize(DemuxerStream* demuxer_stream, DCHECK_GT(codec_context_->channels, 0); DCHECK_GT(bps, 0); DCHECK_GT(codec_context_->sample_rate, 0); - if (codec_context_->channels == 0 || - static_cast<size_t>(codec_context_->channels) > Limits::kMaxChannels || - bps == 0 || - static_cast<size_t>(bps) > Limits::kMaxBPS || - codec_context_->sample_rate == 0 || - (static_cast<size_t>(codec_context_->sample_rate) > - Limits::kMaxSampleRate)) { + if (codec_context_->channels <= 0 || + codec_context_->channels > Limits::kMaxChannels || + bps <= 0 || bps > Limits::kMaxBitsPerSample || + codec_context_->sample_rate <= 0 || + codec_context_->sample_rate > Limits::kMaxSampleRate) { return; } diff --git a/media/media.gyp b/media/media.gyp index 4392632..6b56922 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -23,12 +23,14 @@ 'audio/audio_io.h', 'audio/audio_input_controller.cc', 'audio/audio_input_controller.h', - 'audio/audio_manager.h', 'audio/audio_manager.cc', - 'audio/audio_manager_base.h', + 'audio/audio_manager.h', 'audio/audio_manager_base.cc', + 'audio/audio_manager_base.h', 'audio/audio_output_controller.cc', 'audio/audio_output_controller.h', + 'audio/audio_parameters.cc', + 'audio/audio_parameters.h', 'audio/audio_util.cc', 'audio/audio_util.h', 'audio/fake_audio_input_stream.cc', |