Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: media/audio/sounds/audio_stream_handler.cc

Issue 115693004: Added volume adjust sound behind the flag. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
11 #include "base/synchronization/lock.h"
11 #include "media/audio/audio_manager.h" 12 #include "media/audio/audio_manager.h"
12 #include "media/audio/audio_manager_base.h" 13 #include "media/audio/audio_manager_base.h"
13 #include "media/base/channel_layout.h" 14 #include "media/base/channel_layout.h"
14 15
15 namespace media { 16 namespace media {
16 17
17 namespace { 18 namespace {
18 19
19 // Volume percent. 20 // Volume percent.
20 const double kOutputVolumePercent = 0.8; 21 const double kOutputVolumePercent = 0.8;
21 22
22 // The number of frames each OnMoreData() call will request. 23 // The number of frames each OnMoreData() call will request.
23 const int kDefaultFrameCount = 1024; 24 const int kDefaultFrameCount = 1024;
24 25
25 AudioStreamHandler::TestObserver* g_observer_for_testing = NULL; 26 AudioStreamHandler::TestObserver* g_observer_for_testing = NULL;
26 AudioOutputStream::AudioSourceCallback* g_audio_source_for_testing = NULL; 27 AudioOutputStream::AudioSourceCallback* g_audio_source_for_testing = NULL;
27 28
28 } // namespace 29 } // namespace
29 30
30 class AudioStreamHandler::AudioStreamContainer 31 class AudioStreamHandler::AudioStreamContainer
31 : public AudioOutputStream::AudioSourceCallback { 32 : public AudioOutputStream::AudioSourceCallback {
32 public: 33 public:
33 AudioStreamContainer(const WavAudioHandler& wav_audio, 34 AudioStreamContainer(const WavAudioHandler& wav_audio)
34 const AudioParameters& params)
35 : stream_(NULL), 35 : stream_(NULL),
36 wav_audio_(wav_audio), 36 wav_audio_(wav_audio),
37 params_(params), 37 cursor_(0),
38 cursor_(0) { 38 can_start_(true) {
39 } 39 }
40 40
41 virtual ~AudioStreamContainer() { 41 virtual ~AudioStreamContainer() {
42 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); 42 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
43 } 43 }
44 44
45 void Play() { 45 void Play() {
46 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); 46 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
47 47
48 if (!stream_) { 48 if (!stream_) {
49 stream_ = AudioManager::Get()->MakeAudioOutputStreamProxy(params_, 49 const AudioParameters& p = wav_audio_.params();
50 std::string(), 50 const AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
51 std::string()); 51 p.channel_layout(),
52 p.sample_rate(),
53 p.bits_per_sample(),
54 kDefaultFrameCount);
55 stream_ = AudioManager::Get()->MakeAudioOutputStreamProxy(
56 params, std::string(), std::string());
52 if (!stream_ || !stream_->Open()) { 57 if (!stream_ || !stream_->Open()) {
53 LOG(ERROR) << "Failed to open an output stream."; 58 LOG(ERROR) << "Failed to open an output stream.";
54 return; 59 return;
55 } 60 }
56 stream_->SetVolume(kOutputVolumePercent); 61 stream_->SetVolume(kOutputVolumePercent);
57 } else { 62 } else if (!CanStart()) {
DaleCurtis 2014/01/09 19:58:26 You can simplify this by tracking "started_" inste
ygorshenin1 2014/01/13 10:00:55 Done.
ygorshenin1 2014/01/13 10:00:55 Done.
58 // TODO (ygorshenin@): implement smart stream rewind. 63 return;
59 stream_->Stop();
60 } 64 }
61 65
62 cursor_ = 0; 66 SetCursor(0);
67 SetCanStart(false);
63 if (g_audio_source_for_testing) 68 if (g_audio_source_for_testing)
64 stream_->Start(g_audio_source_for_testing); 69 stream_->Start(g_audio_source_for_testing);
65 else 70 else
66 stream_->Start(this); 71 stream_->Start(this);
67 72
68 if (g_observer_for_testing) 73 if (g_observer_for_testing)
69 g_observer_for_testing->OnPlay(); 74 g_observer_for_testing->OnPlay();
70 } 75 }
71 76
72 void Stop() { 77 void Stop() {
73 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); 78 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread());
74 if (!stream_) 79 StopStream();
75 return; 80 if (stream_)
76 stream_->Stop(); 81 stream_->Close();
77 stream_->Close();
78 stream_ = NULL; 82 stream_ = NULL;
79
80 if (g_observer_for_testing)
81 g_observer_for_testing->OnStop(cursor_);
82 } 83 }
83 84
84 private: 85 private:
85 // AudioOutputStream::AudioSourceCallback overrides: 86 // AudioOutputStream::AudioSourceCallback overrides:
86 // Following methods could be called from *ANY* thread. 87 // Following methods could be called from *ANY* thread.
87 virtual int OnMoreData(AudioBus* dest, 88 virtual int OnMoreData(AudioBus* dest,
88 AudioBuffersState /* state */) OVERRIDE { 89 AudioBuffersState /* state */) OVERRIDE {
89 size_t bytes_written = 0; 90 size_t bytes_written = 0;
90 if (wav_audio_.AtEnd(cursor_) || 91 size_t cursor = GetCursor();
91 !wav_audio_.CopyTo(dest, cursor_, &bytes_written)) { 92 if (wav_audio_.AtEnd(cursor) ||
93 !wav_audio_.CopyTo(dest, cursor, &bytes_written)) {
92 AudioManager::Get()->GetTaskRunner()->PostTask( 94 AudioManager::Get()->GetTaskRunner()->PostTask(
93 FROM_HERE, 95 FROM_HERE,
94 base::Bind(&AudioStreamContainer::Stop, base::Unretained(this))); 96 base::Bind(&AudioStreamContainer::StopStream,
97 base::Unretained(this)));
95 return 0; 98 return 0;
96 } 99 }
97 cursor_ += bytes_written; 100 SetCursor(cursor + bytes_written);
98 101
99 return dest->frames(); 102 return dest->frames();
100 } 103 }
101 104
102 virtual int OnMoreIOData(AudioBus* /* source */, 105 virtual int OnMoreIOData(AudioBus* /* source */,
103 AudioBus* dest, 106 AudioBus* dest,
104 AudioBuffersState state) OVERRIDE { 107 AudioBuffersState state) OVERRIDE {
105 return OnMoreData(dest, state); 108 return OnMoreData(dest, state);
106 } 109 }
107 110
108 virtual void OnError(AudioOutputStream* /* stream */) OVERRIDE { 111 virtual void OnError(AudioOutputStream* /* stream */) OVERRIDE {
109 LOG(ERROR) << "Error during system sound reproduction."; 112 LOG(ERROR) << "Error during system sound reproduction.";
110 } 113 }
111 114
115 void StopStream() {
116 if (stream_)
117 stream_->Stop();
118 if (g_observer_for_testing)
119 g_observer_for_testing->OnStop(GetCursor());
120 SetCanStart(true);
121 }
122
123 size_t GetCursor() {
124 base::AutoLock al(cursor_lock_);
125 return cursor_;
126 }
127
128 void SetCursor(size_t cursor) {
129 base::AutoLock al(cursor_lock_);
130 cursor_ = cursor;
131 }
132
133 bool CanStart() {
134 base::AutoLock al(can_start_lock_);
135 return can_start_;
136 }
137
138 void SetCanStart(bool can_start) {
139 base::AutoLock al(can_start_lock_);
140 can_start_ = can_start;
141 }
142
112 AudioOutputStream* stream_; 143 AudioOutputStream* stream_;
113 144
114 const WavAudioHandler wav_audio_; 145 const WavAudioHandler wav_audio_;
115 const AudioParameters params_;
116 146
147 base::Lock cursor_lock_;
117 size_t cursor_; 148 size_t cursor_;
118 149
150 base::Lock can_start_lock_;
151 bool can_start_;
152
119 DISALLOW_COPY_AND_ASSIGN(AudioStreamContainer); 153 DISALLOW_COPY_AND_ASSIGN(AudioStreamContainer);
120 }; 154 };
121 155
122 AudioStreamHandler::AudioStreamHandler(const base::StringPiece& wav_data) 156 AudioStreamHandler::AudioStreamHandler(const base::StringPiece& wav_data)
123 : wav_audio_(wav_data), 157 : wav_audio_(wav_data),
124 initialized_(false) { 158 initialized_(false) {
125 AudioManager* manager = AudioManager::Get(); 159 AudioManager* manager = AudioManager::Get();
126 if (!manager) { 160 if (!manager) {
127 LOG(ERROR) << "Can't get access to audio manager."; 161 LOG(ERROR) << "Can't get access to audio manager.";
128 return; 162 return;
129 } 163 }
130 AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY, 164 if (!wav_audio_.params().IsValid()) {
131 GuessChannelLayout(wav_audio_.num_channels()),
132 wav_audio_.sample_rate(),
133 wav_audio_.bits_per_sample(),
134 kDefaultFrameCount);
135 if (!params.IsValid()) {
136 LOG(ERROR) << "Audio params are invalid."; 165 LOG(ERROR) << "Audio params are invalid.";
137 return; 166 return;
138 } 167 }
139 stream_.reset(new AudioStreamContainer(wav_audio_, params)); 168 stream_.reset(new AudioStreamContainer(wav_audio_));
140 initialized_ = true; 169 initialized_ = true;
141 } 170 }
142 171
143 AudioStreamHandler::~AudioStreamHandler() { 172 AudioStreamHandler::~AudioStreamHandler() {
144 DCHECK(CalledOnValidThread()); 173 DCHECK(CalledOnValidThread());
145 AudioManager::Get()->GetTaskRunner()->PostTask( 174 AudioManager::Get()->GetTaskRunner()->PostTask(
146 FROM_HERE, 175 FROM_HERE,
147 base::Bind(&AudioStreamContainer::Stop, base::Unretained(stream_.get()))); 176 base::Bind(&AudioStreamContainer::Stop, base::Unretained(stream_.get())));
148 AudioManager::Get()->GetTaskRunner()->DeleteSoon(FROM_HERE, 177 AudioManager::Get()->GetTaskRunner()->DeleteSoon(FROM_HERE,
149 stream_.release()); 178 stream_.release());
(...skipping 29 matching lines...) Expand all
179 g_observer_for_testing = observer; 208 g_observer_for_testing = observer;
180 } 209 }
181 210
182 // static 211 // static
183 void AudioStreamHandler::SetAudioSourceForTesting( 212 void AudioStreamHandler::SetAudioSourceForTesting(
184 AudioOutputStream::AudioSourceCallback* source) { 213 AudioOutputStream::AudioSourceCallback* source) {
185 g_audio_source_for_testing = source; 214 g_audio_source_for_testing = source;
186 } 215 }
187 216
188 } // namespace media 217 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698