| 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 |