| // Copyright (c) 2006-2008 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 <windows.h> |
| #include <mmsystem.h> |
| |
| #include "base/basictypes.h" |
| #include "media/audio/audio_output.h" |
| #include "media/audio/win/audio_manager_win.h" |
| #include "media/audio/win/waveout_output_win.h" |
| |
| // A do-nothing audio stream. It behaves like a regular audio stream but does |
| // not have any side effect, except possibly the creation and tear-down of |
| // of a thread. It is useful to test code that uses audio streams such as |
| // audio sources. |
| class AudioOutputStreamMockWin : public AudioOutputStream { |
| public: |
| explicit AudioOutputStreamMockWin(AudioManagerWin* manager) |
| : manager_(manager), |
| callback_(NULL), |
| buffer_(NULL), |
| packet_size_(0), |
| left_volume_(1.0), |
| right_volume_(1.0) { |
| } |
| |
| virtual ~AudioOutputStreamMockWin() { |
| delete[] buffer_; |
| packet_size_ = 0; |
| } |
| |
| virtual bool Open(size_t packet_size) { |
| if (packet_size < sizeof(int16)) |
| return false; |
| packet_size_ = packet_size; |
| buffer_ = new char[packet_size_]; |
| return true; |
| } |
| |
| virtual void Start(AudioSourceCallback* callback) { |
| callback_ = callback; |
| memset(buffer_, 0, packet_size_); |
| callback_->OnMoreData(this, buffer_, packet_size_); |
| } |
| |
| // TODO(cpu): flesh out Start and Stop methods. We need a thread to |
| // perform periodic callbacks. |
| virtual void Stop() { |
| } |
| |
| virtual void SetVolume(double left_level, double right_level) { |
| left_volume_ = left_level; |
| right_volume_ = right_level; |
| } |
| |
| virtual void GetVolume(double* left_level, double* right_level) { |
| *left_level = left_volume_; |
| *right_level = right_volume_; |
| } |
| |
| virtual void Close() { |
| callback_->OnClose(this); |
| callback_ = NULL; |
| manager_->ReleaseStream(this); |
| } |
| |
| char* buffer() { |
| return buffer_; |
| } |
| |
| private: |
| AudioManagerWin* manager_; |
| AudioSourceCallback* callback_; |
| char* buffer_; |
| size_t packet_size_; |
| double left_volume_; |
| double right_volume_; |
| }; |
| |
| namespace { |
| AudioOutputStreamMockWin* g_last_mock_stream = NULL; |
| |
| void ReplaceLastMockStream(AudioOutputStreamMockWin* newer) { |
| if (g_last_mock_stream) |
| delete g_last_mock_stream; |
| g_last_mock_stream = newer; |
| } |
| |
| } // namespace. |
| |
| |
| bool AudioManagerWin::HasAudioDevices() { |
| return (::waveOutGetNumDevs() != 0); |
| } |
| |
| // Factory for the implementations of AudioOutputStream. Two implementations |
| // should suffice most windows user's needs. |
| // - PCMWaveOutAudioOutputStream: Based on the waveOutWrite API (in progress) |
| // - PCMDXSoundAudioOutputStream: Based on DirectSound or XAudio (future work). |
| |
| AudioOutputStream* AudioManagerWin::MakeAudioStream(Format format, int channels, |
| int sample_rate, |
| char bits_per_sample) { |
| if (format == AUDIO_MOCK) { |
| return new AudioOutputStreamMockWin(this); |
| } else if (format == AUDIO_PCM_LINEAR) { |
| return new PCMWaveOutAudioOutputStream(this, channels, sample_rate, |
| bits_per_sample, WAVE_MAPPER); |
| } |
| return NULL; |
| } |
| |
| void AudioManagerWin::ReleaseStream(PCMWaveOutAudioOutputStream* stream) { |
| if (stream) |
| delete stream; |
| } |
| |
| void AudioManagerWin::ReleaseStream(AudioOutputStreamMockWin *stream) { |
| // Note that we keep the last mock stream so GetLastMockBuffer() works. |
| ReplaceLastMockStream(stream); |
| } |
| |
| const void* AudioManagerWin::GetLastMockBuffer() { |
| return (g_last_mock_stream) ? g_last_mock_stream->buffer() : NULL; |
| } |
| |
| void AudioManagerWin::MuteAll() { |
| } |
| |
| void AudioManagerWin::UnMuteAll() { |
| } |
| |
| AudioManagerWin::~AudioManagerWin() { |
| ReplaceLastMockStream(NULL); |
| } |
| |
| // TODO(cpu): Decide how to manage the lifetime of the AudioManager singleton. |
| // Right now we are leaking it. |
| AudioManager* AudioManager::GetAudioManager() { |
| static AudioManagerWin* audio_manager = NULL; |
| if (!audio_manager) |
| audio_manager = new AudioManagerWin(); |
| return audio_manager; |
| } |