OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <windows.h> | 5 #include <windows.h> |
| 6 #include <mmsystem.h> |
6 | 7 |
7 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
8 #include "media/audio/audio_output.h" | 9 #include "media/audio/audio_output.h" |
| 10 #include "media/audio/win/audio_manager_win.h" |
| 11 #include "media/audio/win/waveout_output_win.h" |
9 | 12 |
10 // A do-nothing audio stream. It behaves like a regular audio stream but does | 13 // A do-nothing audio stream. It behaves like a regular audio stream but does |
11 // not have any side effect, except possibly the creation and tear-down of | 14 // not have any side effect, except possibly the creation and tear-down of |
12 // of a thread. It is useful to test code that uses audio streams such as | 15 // of a thread. It is useful to test code that uses audio streams such as |
13 // audio sources. | 16 // audio sources. |
14 class AudioOutputStreamWinMock : public AudioOutputStream { | 17 class AudioOutputStreamMockWin : public AudioOutputStream { |
15 public: | 18 public: |
16 AudioOutputStreamWinMock() | 19 explicit AudioOutputStreamMockWin(AudioManagerWin* manager) |
17 : callback_(NULL), | 20 : manager_(manager), |
| 21 callback_(NULL), |
18 buffer_(NULL), | 22 buffer_(NULL), |
19 packet_size_(0), | 23 packet_size_(0), |
20 left_volume_(0.0), | 24 left_volume_(1.0), |
21 right_volume_(0.0) { | 25 right_volume_(1.0) { |
| 26 } |
| 27 |
| 28 virtual ~AudioOutputStreamMockWin() { |
| 29 delete[] buffer_; |
| 30 packet_size_ = 0; |
22 } | 31 } |
23 | 32 |
24 virtual bool Open(size_t packet_size) { | 33 virtual bool Open(size_t packet_size) { |
25 if (packet_size < sizeof(int16)) | 34 if (packet_size < sizeof(int16)) |
26 return false; | 35 return false; |
27 packet_size_ = packet_size; | 36 packet_size_ = packet_size; |
28 buffer_ = new char[packet_size_]; | 37 buffer_ = new char[packet_size_]; |
29 return true; | 38 return true; |
30 } | 39 } |
31 | 40 |
32 virtual void Start(AudioSourceCallback* callback) { | 41 virtual void Start(AudioSourceCallback* callback) { |
33 callback_ = callback; | 42 callback_ = callback; |
| 43 memset(buffer_, 0, packet_size_); |
34 callback_->OnMoreData(this, buffer_, packet_size_); | 44 callback_->OnMoreData(this, buffer_, packet_size_); |
35 } | 45 } |
36 | 46 |
37 // TODO(cpu): flesh out Start and Stop methods. We need a thread to | 47 // TODO(cpu): flesh out Start and Stop methods. We need a thread to |
38 // perform periodic callbacks. | 48 // perform periodic callbacks. |
39 virtual void Stop() { | 49 virtual void Stop() { |
40 } | 50 } |
41 | 51 |
42 virtual void SetVolume(double left_level, double right_level) { | 52 virtual void SetVolume(double left_level, double right_level) { |
43 left_volume_ = left_level; | 53 left_volume_ = left_level; |
44 right_volume_ = right_level; | 54 right_volume_ = right_level; |
45 } | 55 } |
46 | 56 |
47 virtual void GetVolume(double* left_level, double* right_level) { | 57 virtual void GetVolume(double* left_level, double* right_level) { |
48 *left_level = left_volume_; | 58 *left_level = left_volume_; |
49 *right_level = right_volume_; | 59 *right_level = right_volume_; |
50 } | 60 } |
51 | 61 |
52 virtual void Close() { | 62 virtual void Close() { |
53 callback_->OnClose(this); | 63 callback_->OnClose(this); |
54 callback_ = NULL; | 64 callback_ = NULL; |
55 delete this; | 65 manager_->ReleaseStream(this); |
56 } | 66 } |
57 | 67 |
58 protected: | 68 char* buffer() { |
59 virtual ~AudioOutputStreamWinMock() { | 69 return buffer_; |
60 delete[] buffer_; | |
61 packet_size_ = 0; | |
62 } | 70 } |
63 | 71 |
64 private: | 72 private: |
| 73 AudioManagerWin* manager_; |
65 AudioSourceCallback* callback_; | 74 AudioSourceCallback* callback_; |
66 char* buffer_; | 75 char* buffer_; |
67 size_t packet_size_; | 76 size_t packet_size_; |
68 double left_volume_; | 77 double left_volume_; |
69 double right_volume_; | 78 double right_volume_; |
70 }; | 79 }; |
71 | 80 |
72 class AudioManagerWin : public AudioManager { | 81 namespace { |
73 public: | 82 AudioOutputStreamMockWin* g_last_mock_stream = NULL; |
74 virtual AudioOutputStream* MakeAudioStream(Format format, int channels, | 83 |
75 int sample_rate, | 84 void ReplaceLastMockStream(AudioOutputStreamMockWin* newer) { |
76 char bits_per_sample) { | 85 if (g_last_mock_stream) |
77 if (format == AUDIO_MOCK) | 86 delete g_last_mock_stream; |
78 return new AudioOutputStreamWinMock(); | 87 g_last_mock_stream = newer; |
79 return NULL; | 88 } |
| 89 |
| 90 } // namespace. |
| 91 |
| 92 // Factory for the implementations of AudioOutputStream. Two implementations |
| 93 // should suffice most windows user's needs. |
| 94 // - PCMWaveOutAudioOutputStream: Based on the waveOutWrite API (in progress) |
| 95 // - PCMDXSoundAudioOutputStream: Based on DirectSound or XAudio (future work). |
| 96 |
| 97 AudioOutputStream* AudioManagerWin::MakeAudioStream(Format format, int channels, |
| 98 int sample_rate, |
| 99 char bits_per_sample) { |
| 100 if (format == AUDIO_MOCK) { |
| 101 return new AudioOutputStreamMockWin(this); |
| 102 } else if (format == AUDIO_PCM_LINEAR) { |
| 103 return new PCMWaveOutAudioOutputStream(this, channels, sample_rate, |
| 104 bits_per_sample, WAVE_MAPPER); |
80 } | 105 } |
| 106 return NULL; |
| 107 } |
81 | 108 |
82 virtual void MuteAll() { | 109 void AudioManagerWin::ReleaseStream(PCMWaveOutAudioOutputStream* stream) { |
83 } | 110 if (stream) |
| 111 delete stream; |
| 112 } |
84 | 113 |
85 virtual void UnMuteAll() { | 114 void AudioManagerWin::ReleaseStream(AudioOutputStreamMockWin *stream) { |
86 } | 115 // Note that we keep the last mock stream so GetLastMockBuffer() works. |
| 116 ReplaceLastMockStream(stream); |
| 117 } |
87 | 118 |
88 protected: | 119 const void* AudioManagerWin::GetLastMockBuffer() { |
89 virtual ~AudioManagerWin() { | 120 return (g_last_mock_stream) ? g_last_mock_stream->buffer() : NULL; |
90 } | 121 } |
91 }; | 122 |
| 123 void AudioManagerWin::MuteAll() { |
| 124 } |
| 125 |
| 126 void AudioManagerWin::UnMuteAll() { |
| 127 } |
| 128 |
| 129 AudioManagerWin::~AudioManagerWin() { |
| 130 ReplaceLastMockStream(NULL); |
| 131 } |
92 | 132 |
93 // TODO(cpu): Decide how to manage the lifetime of the AudioManager singleton. | 133 // TODO(cpu): Decide how to manage the lifetime of the AudioManager singleton. |
94 // Right now we are leaking it. | 134 // Right now we are leaking it. |
95 AudioManager* GetAudioManager() { | 135 AudioManager* AudioManager::GetAudioManager() { |
96 static AudioManagerWin* audio_manager = NULL; | 136 static AudioManagerWin* audio_manager = NULL; |
97 if (!audio_manager) | 137 if (!audio_manager) |
98 audio_manager = new AudioManagerWin(); | 138 audio_manager = new AudioManagerWin(); |
99 return audio_manager; | 139 return audio_manager; |
100 } | 140 } |
101 | |
102 | |
103 | |
OLD | NEW |