OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "media/audio/sounds/audio_stream_handler.h" | 5 #include "media/audio/sounds/audio_stream_handler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/single_thread_task_runner.h" |
11 #include "media/audio/audio_manager.h" | 11 #include "media/audio/audio_manager.h" |
12 #include "media/audio/audio_manager_base.h" | 12 #include "media/audio/audio_manager_base.h" |
13 #include "media/base/channel_layout.h" | 13 #include "media/base/channel_layout.h" |
14 | 14 |
15 namespace media { | 15 namespace media { |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 // Volume percent. | 19 // Volume percent. |
20 const double kOutputVolumePercent = 0.8; | 20 const double kOutputVolumePercent = 0.8; |
(...skipping 11 matching lines...) Expand all Loading... |
32 public: | 32 public: |
33 AudioStreamContainer(const WavAudioHandler& wav_audio, | 33 AudioStreamContainer(const WavAudioHandler& wav_audio, |
34 const AudioParameters& params) | 34 const AudioParameters& params) |
35 : stream_(NULL), | 35 : stream_(NULL), |
36 wav_audio_(wav_audio), | 36 wav_audio_(wav_audio), |
37 params_(params), | 37 params_(params), |
38 cursor_(0) { | 38 cursor_(0) { |
39 } | 39 } |
40 | 40 |
41 virtual ~AudioStreamContainer() { | 41 virtual ~AudioStreamContainer() { |
42 DCHECK(AudioManager::Get()->GetMessageLoop()->BelongsToCurrentThread()); | 42 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); |
43 } | 43 } |
44 | 44 |
45 void Play() { | 45 void Play() { |
46 DCHECK(AudioManager::Get()->GetMessageLoop()->BelongsToCurrentThread()); | 46 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); |
47 | 47 |
48 if (!stream_) { | 48 if (!stream_) { |
49 stream_ = AudioManager::Get()->MakeAudioOutputStreamProxy(params_, | 49 stream_ = AudioManager::Get()->MakeAudioOutputStreamProxy(params_, |
50 std::string(), | 50 std::string(), |
51 std::string()); | 51 std::string()); |
52 if (!stream_ || !stream_->Open()) { | 52 if (!stream_ || !stream_->Open()) { |
53 LOG(ERROR) << "Failed to open an output stream."; | 53 LOG(ERROR) << "Failed to open an output stream."; |
54 return; | 54 return; |
55 } | 55 } |
56 stream_->SetVolume(kOutputVolumePercent); | 56 stream_->SetVolume(kOutputVolumePercent); |
57 } else { | 57 } else { |
58 // TODO (ygorshenin@): implement smart stream rewind. | 58 // TODO (ygorshenin@): implement smart stream rewind. |
59 stream_->Stop(); | 59 stream_->Stop(); |
60 } | 60 } |
61 | 61 |
62 cursor_ = 0; | 62 cursor_ = 0; |
63 if (g_audio_source_for_testing) | 63 if (g_audio_source_for_testing) |
64 stream_->Start(g_audio_source_for_testing); | 64 stream_->Start(g_audio_source_for_testing); |
65 else | 65 else |
66 stream_->Start(this); | 66 stream_->Start(this); |
67 | 67 |
68 if (g_observer_for_testing) | 68 if (g_observer_for_testing) |
69 g_observer_for_testing->OnPlay(); | 69 g_observer_for_testing->OnPlay(); |
70 } | 70 } |
71 | 71 |
72 void Stop() { | 72 void Stop() { |
73 DCHECK(AudioManager::Get()->GetMessageLoop()->BelongsToCurrentThread()); | 73 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); |
74 if (!stream_) | 74 if (!stream_) |
75 return; | 75 return; |
76 stream_->Stop(); | 76 stream_->Stop(); |
77 stream_->Close(); | 77 stream_->Close(); |
78 stream_ = NULL; | 78 stream_ = NULL; |
79 | 79 |
80 if (g_observer_for_testing) | 80 if (g_observer_for_testing) |
81 g_observer_for_testing->OnStop(cursor_); | 81 g_observer_for_testing->OnStop(cursor_); |
82 } | 82 } |
83 | 83 |
84 private: | 84 private: |
85 // AudioOutputStream::AudioSourceCallback overrides: | 85 // AudioOutputStream::AudioSourceCallback overrides: |
86 // Following methods could be called from *ANY* thread. | 86 // Following methods could be called from *ANY* thread. |
87 virtual int OnMoreData(AudioBus* dest, | 87 virtual int OnMoreData(AudioBus* dest, |
88 AudioBuffersState /* state */) OVERRIDE { | 88 AudioBuffersState /* state */) OVERRIDE { |
89 size_t bytes_written = 0; | 89 size_t bytes_written = 0; |
90 if (wav_audio_.AtEnd(cursor_) || | 90 if (wav_audio_.AtEnd(cursor_) || |
91 !wav_audio_.CopyTo(dest, cursor_, &bytes_written)) { | 91 !wav_audio_.CopyTo(dest, cursor_, &bytes_written)) { |
92 AudioManager::Get()->GetMessageLoop()->PostTask( | 92 AudioManager::Get()->GetTaskRunner()->PostTask( |
93 FROM_HERE, | 93 FROM_HERE, |
94 base::Bind(&AudioStreamContainer::Stop, base::Unretained(this))); | 94 base::Bind(&AudioStreamContainer::Stop, base::Unretained(this))); |
95 return 0; | 95 return 0; |
96 } | 96 } |
97 cursor_ += bytes_written; | 97 cursor_ += bytes_written; |
98 | 98 |
99 return dest->frames(); | 99 return dest->frames(); |
100 } | 100 } |
101 | 101 |
102 virtual int OnMoreIOData(AudioBus* /* source */, | 102 virtual int OnMoreIOData(AudioBus* /* source */, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 if (!params.IsValid()) { | 135 if (!params.IsValid()) { |
136 LOG(ERROR) << "Audio params are invalid."; | 136 LOG(ERROR) << "Audio params are invalid."; |
137 return; | 137 return; |
138 } | 138 } |
139 stream_.reset(new AudioStreamContainer(wav_audio_, params)); | 139 stream_.reset(new AudioStreamContainer(wav_audio_, params)); |
140 initialized_ = true; | 140 initialized_ = true; |
141 } | 141 } |
142 | 142 |
143 AudioStreamHandler::~AudioStreamHandler() { | 143 AudioStreamHandler::~AudioStreamHandler() { |
144 DCHECK(CalledOnValidThread()); | 144 DCHECK(CalledOnValidThread()); |
145 AudioManager::Get()->GetMessageLoop()->PostTask( | 145 AudioManager::Get()->GetTaskRunner()->PostTask( |
146 FROM_HERE, | 146 FROM_HERE, |
147 base::Bind(&AudioStreamContainer::Stop, base::Unretained(stream_.get()))); | 147 base::Bind(&AudioStreamContainer::Stop, base::Unretained(stream_.get()))); |
148 AudioManager::Get()->GetMessageLoop()->DeleteSoon(FROM_HERE, | 148 AudioManager::Get()->GetTaskRunner()->DeleteSoon(FROM_HERE, |
149 stream_.release()); | 149 stream_.release()); |
150 } | 150 } |
151 | 151 |
152 bool AudioStreamHandler::IsInitialized() const { | 152 bool AudioStreamHandler::IsInitialized() const { |
153 DCHECK(CalledOnValidThread()); | 153 DCHECK(CalledOnValidThread()); |
154 return initialized_; | 154 return initialized_; |
155 } | 155 } |
156 | 156 |
157 bool AudioStreamHandler::Play() { | 157 bool AudioStreamHandler::Play() { |
158 DCHECK(CalledOnValidThread()); | 158 DCHECK(CalledOnValidThread()); |
159 | 159 |
160 if (!IsInitialized()) | 160 if (!IsInitialized()) |
161 return false; | 161 return false; |
162 | 162 |
163 AudioManager::Get()->GetMessageLoop()->PostTask( | 163 AudioManager::Get()->GetTaskRunner()->PostTask( |
164 FROM_HERE, | 164 FROM_HERE, |
165 base::Bind(base::IgnoreResult(&AudioStreamContainer::Play), | 165 base::Bind(base::IgnoreResult(&AudioStreamContainer::Play), |
166 base::Unretained(stream_.get()))); | 166 base::Unretained(stream_.get()))); |
167 return true; | 167 return true; |
168 } | 168 } |
169 | 169 |
170 void AudioStreamHandler::Stop() { | 170 void AudioStreamHandler::Stop() { |
171 DCHECK(CalledOnValidThread()); | 171 DCHECK(CalledOnValidThread()); |
172 AudioManager::Get()->GetMessageLoop()->PostTask( | 172 AudioManager::Get()->GetTaskRunner()->PostTask( |
173 FROM_HERE, | 173 FROM_HERE, |
174 base::Bind(&AudioStreamContainer::Stop, base::Unretained(stream_.get()))); | 174 base::Bind(&AudioStreamContainer::Stop, base::Unretained(stream_.get()))); |
175 } | 175 } |
176 | 176 |
177 // static | 177 // static |
178 void AudioStreamHandler::SetObserverForTesting(TestObserver* observer) { | 178 void AudioStreamHandler::SetObserverForTesting(TestObserver* observer) { |
179 g_observer_for_testing = observer; | 179 g_observer_for_testing = observer; |
180 } | 180 } |
181 | 181 |
182 // static | 182 // static |
183 void AudioStreamHandler::SetAudioSourceForTesting( | 183 void AudioStreamHandler::SetAudioSourceForTesting( |
184 AudioOutputStream::AudioSourceCallback* source) { | 184 AudioOutputStream::AudioSourceCallback* source) { |
185 g_audio_source_for_testing = source; | 185 g_audio_source_for_testing = source; |
186 } | 186 } |
187 | 187 |
188 } // namespace media | 188 } // namespace media |
OLD | NEW |