| 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/cancelable_callback.h" | 9 #include "base/cancelable_callback.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 AudioStreamHandler::TestObserver* g_observer_for_testing = NULL; | 31 AudioStreamHandler::TestObserver* g_observer_for_testing = NULL; |
| 32 AudioOutputStream::AudioSourceCallback* g_audio_source_for_testing = NULL; | 32 AudioOutputStream::AudioSourceCallback* g_audio_source_for_testing = NULL; |
| 33 | 33 |
| 34 } // namespace | 34 } // namespace |
| 35 | 35 |
| 36 class AudioStreamHandler::AudioStreamContainer | 36 class AudioStreamHandler::AudioStreamContainer |
| 37 : public AudioOutputStream::AudioSourceCallback { | 37 : public AudioOutputStream::AudioSourceCallback { |
| 38 public: | 38 public: |
| 39 AudioStreamContainer(const WavAudioHandler& wav_audio) | 39 AudioStreamContainer(const WavAudioHandler& wav_audio) |
| 40 : stream_(NULL), | 40 : started_(false), |
| 41 wav_audio_(wav_audio), | 41 stream_(NULL), |
| 42 cursor_(0), | 42 cursor_(0), |
| 43 started_(false), | 43 delayed_stop_posted_(false), |
| 44 delayed_stop_posted_(false) { | 44 wav_audio_(wav_audio) {} |
| 45 } | |
| 46 | 45 |
| 47 virtual ~AudioStreamContainer() { | 46 virtual ~AudioStreamContainer() { |
| 48 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); | 47 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); |
| 49 } | 48 } |
| 50 | 49 |
| 51 void Play() { | 50 void Play() { |
| 52 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); | 51 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); |
| 53 | 52 |
| 54 if (!stream_) { | 53 if (!stream_) { |
| 55 const AudioParameters& p = wav_audio_.params(); | 54 const AudioParameters& p = wav_audio_.params(); |
| 56 const AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY, | 55 const AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 57 p.channel_layout(), | 56 p.channel_layout(), |
| 58 p.sample_rate(), | 57 p.sample_rate(), |
| 59 p.bits_per_sample(), | 58 p.bits_per_sample(), |
| 60 kDefaultFrameCount); | 59 kDefaultFrameCount); |
| 61 stream_ = AudioManager::Get()->MakeAudioOutputStreamProxy( | 60 stream_ = AudioManager::Get()->MakeAudioOutputStreamProxy(params, |
| 62 params, std::string()); | 61 std::string()); |
| 63 if (!stream_ || !stream_->Open()) { | 62 if (!stream_ || !stream_->Open()) { |
| 64 LOG(ERROR) << "Failed to open an output stream."; | 63 LOG(ERROR) << "Failed to open an output stream."; |
| 65 return; | 64 return; |
| 66 } | 65 } |
| 67 stream_->SetVolume(kOutputVolumePercent); | 66 stream_->SetVolume(kOutputVolumePercent); |
| 68 } | 67 } |
| 69 | 68 |
| 70 { | 69 { |
| 71 base::AutoLock al(state_lock_); | 70 base::AutoLock al(state_lock_); |
| 72 | 71 |
| 73 delayed_stop_posted_ = false; | 72 delayed_stop_posted_ = false; |
| 74 stop_closure_.Reset(base::Bind( | 73 stop_closure_.Reset(base::Bind(&AudioStreamContainer::StopStream, |
| 75 &AudioStreamContainer::StopStream, base::Unretained(this))); | 74 base::Unretained(this))); |
| 76 | 75 |
| 77 if (started_) { | 76 if (started_) { |
| 78 if (wav_audio_.AtEnd(cursor_)) | 77 if (wav_audio_.AtEnd(cursor_)) |
| 79 cursor_ = 0; | 78 cursor_ = 0; |
| 80 return; | 79 return; |
| 81 } | 80 } |
| 82 | 81 |
| 83 cursor_ = 0; | 82 cursor_ = 0; |
| 84 started_ = true; | |
| 85 } | 83 } |
| 86 | 84 |
| 85 started_ = true; |
| 87 if (g_audio_source_for_testing) | 86 if (g_audio_source_for_testing) |
| 88 stream_->Start(g_audio_source_for_testing); | 87 stream_->Start(g_audio_source_for_testing); |
| 89 else | 88 else |
| 90 stream_->Start(this); | 89 stream_->Start(this); |
| 91 | 90 |
| 92 if (g_observer_for_testing) | 91 if (g_observer_for_testing) |
| 93 g_observer_for_testing->OnPlay(); | 92 g_observer_for_testing->OnPlay(); |
| 94 } | 93 } |
| 95 | 94 |
| 96 void Stop() { | 95 void Stop() { |
| 97 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); | 96 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); |
| 98 StopStream(); | 97 StopStream(); |
| 99 if (stream_) | 98 if (stream_) |
| 100 stream_->Close(); | 99 stream_->Close(); |
| 101 stream_ = NULL; | 100 stream_ = NULL; |
| 101 stop_closure_.Cancel(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 private: | 104 private: |
| 105 // AudioOutputStream::AudioSourceCallback overrides: | 105 // AudioOutputStream::AudioSourceCallback overrides: |
| 106 // Following methods could be called from *ANY* thread. | 106 // Following methods could be called from *ANY* thread. |
| 107 virtual int OnMoreData(AudioBus* dest, | 107 virtual int OnMoreData(AudioBus* dest, |
| 108 AudioBuffersState /* state */) OVERRIDE { | 108 AudioBuffersState /* state */) OVERRIDE { |
| 109 base::AutoLock al(state_lock_); | 109 base::AutoLock al(state_lock_); |
| 110 size_t bytes_written = 0; | 110 size_t bytes_written = 0; |
| 111 | 111 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 124 return dest->frames(); | 124 return dest->frames(); |
| 125 } | 125 } |
| 126 | 126 |
| 127 virtual void OnError(AudioOutputStream* /* stream */) OVERRIDE { | 127 virtual void OnError(AudioOutputStream* /* stream */) OVERRIDE { |
| 128 LOG(ERROR) << "Error during system sound reproduction."; | 128 LOG(ERROR) << "Error during system sound reproduction."; |
| 129 } | 129 } |
| 130 | 130 |
| 131 void StopStream() { | 131 void StopStream() { |
| 132 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); | 132 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); |
| 133 | 133 |
| 134 base::AutoLock al(state_lock_); | |
| 135 | |
| 136 if (stream_ && started_) { | 134 if (stream_ && started_) { |
| 135 // Do not hold the |state_lock_| while stopping the output stream. |
| 137 stream_->Stop(); | 136 stream_->Stop(); |
| 138 if (g_observer_for_testing) | 137 if (g_observer_for_testing) |
| 139 g_observer_for_testing->OnStop(cursor_); | 138 g_observer_for_testing->OnStop(cursor_); |
| 140 } | 139 } |
| 140 |
| 141 started_ = false; | 141 started_ = false; |
| 142 } | 142 } |
| 143 | 143 |
| 144 // Must only be accessed on the AudioManager::GetTaskRunner() thread. |
| 145 bool started_; |
| 144 AudioOutputStream* stream_; | 146 AudioOutputStream* stream_; |
| 145 | 147 |
| 146 const WavAudioHandler wav_audio_; | 148 // All variables below must be accessed under |state_lock_| when |started_|. |
| 147 | |
| 148 base::Lock state_lock_; | 149 base::Lock state_lock_; |
| 149 size_t cursor_; | 150 size_t cursor_; |
| 150 bool started_; | |
| 151 bool delayed_stop_posted_; | 151 bool delayed_stop_posted_; |
| 152 const WavAudioHandler wav_audio_; |
| 152 base::CancelableClosure stop_closure_; | 153 base::CancelableClosure stop_closure_; |
| 153 | 154 |
| 154 DISALLOW_COPY_AND_ASSIGN(AudioStreamContainer); | 155 DISALLOW_COPY_AND_ASSIGN(AudioStreamContainer); |
| 155 }; | 156 }; |
| 156 | 157 |
| 157 AudioStreamHandler::AudioStreamHandler(const base::StringPiece& wav_data) | 158 AudioStreamHandler::AudioStreamHandler(const base::StringPiece& wav_data) |
| 158 : wav_audio_(wav_data), | 159 : wav_audio_(wav_data), |
| 159 initialized_(false) { | 160 initialized_(false) { |
| 160 AudioManager* manager = AudioManager::Get(); | 161 AudioManager* manager = AudioManager::Get(); |
| 161 if (!manager) { | 162 if (!manager) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 g_observer_for_testing = observer; | 210 g_observer_for_testing = observer; |
| 210 } | 211 } |
| 211 | 212 |
| 212 // static | 213 // static |
| 213 void AudioStreamHandler::SetAudioSourceForTesting( | 214 void AudioStreamHandler::SetAudioSourceForTesting( |
| 214 AudioOutputStream::AudioSourceCallback* source) { | 215 AudioOutputStream::AudioSourceCallback* source) { |
| 215 g_audio_source_for_testing = source; | 216 g_audio_source_for_testing = source; |
| 216 } | 217 } |
| 217 | 218 |
| 218 } // namespace media | 219 } // namespace media |
| OLD | NEW |