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

Side by Side Diff: media/audio/fake_audio_input_stream.cc

Issue 260073013: Added automatic mode to FakeInputAudioStream to generate automatic beeps (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 6 years, 7 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/fake_audio_input_stream.h" 5 #include "media/audio/fake_audio_input_stream.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
9 #include "media/audio/audio_manager_base.h" 9 #include "media/audio/audio_manager_base.h"
10 10
11 using base::TimeTicks; 11 using base::TimeTicks;
12 using base::TimeDelta; 12 using base::TimeDelta;
13 13
14 namespace media { 14 namespace media {
15 15
16 namespace { 16 namespace {
17 17
18 // These values are based on experiments for local-to-local 18 // These values are based on experiments for local-to-local
19 // PeerConnection to demonstrate audio/video synchronization. 19 // PeerConnection to demonstrate audio/video synchronization.
20 const int kBeepDurationMilliseconds = 20; 20 const int kBeepDurationMilliseconds = 20;
21 const int kBeepFrequency = 400; 21 const int kBeepFrequency = 400;
22 22
23 // Intervals between two automatic beeps.
24 const int kAutomaticBeepIntervalInMs = 500;
25
26 // Automatic beep will be triggered every |kAutomaticBeepIntervalInMs| unless
27 // users explicitly call BeepOnce(), which will disable the automatic beep.
23 struct BeepContext { 28 struct BeepContext {
24 BeepContext() : beep_once(false) {} 29 BeepContext() : beep_once(false), automatic(true) {}
DaleCurtis 2014/04/29 17:30:56 Shouldn't this default to false? Isn't this used i
no longer working on chromium 2014/05/02 14:30:47 That is good point, I honestly have no idea how th
25 base::Lock beep_lock; 30 base::Lock beep_lock;
26 bool beep_once; 31 bool beep_once;
32 bool automatic;
27 }; 33 };
28 34
29 static base::LazyInstance<BeepContext> g_beep_context = 35 static base::LazyInstance<BeepContext> g_beep_context =
30 LAZY_INSTANCE_INITIALIZER; 36 LAZY_INSTANCE_INITIALIZER;
31 37
32 } // namespace 38 } // namespace
33 39
34 AudioInputStream* FakeAudioInputStream::MakeFakeStream( 40 AudioInputStream* FakeAudioInputStream::MakeFakeStream(
35 AudioManagerBase* manager, 41 AudioManagerBase* manager,
36 const AudioParameters& params) { 42 const AudioParameters& params) {
(...skipping 24 matching lines...) Expand all
61 buffer_.reset(new uint8[buffer_size_]); 67 buffer_.reset(new uint8[buffer_size_]);
62 memset(buffer_.get(), 0, buffer_size_); 68 memset(buffer_.get(), 0, buffer_size_);
63 return true; 69 return true;
64 } 70 }
65 71
66 void FakeAudioInputStream::Start(AudioInputCallback* callback) { 72 void FakeAudioInputStream::Start(AudioInputCallback* callback) {
67 DCHECK(!thread_.IsRunning()); 73 DCHECK(!thread_.IsRunning());
68 DCHECK(!callback_); 74 DCHECK(!callback_);
69 callback_ = callback; 75 callback_ = callback;
70 last_callback_time_ = TimeTicks::Now(); 76 last_callback_time_ = TimeTicks::Now();
71 thread_.Start(); 77 thread_.Start();
DaleCurtis 2014/04/29 17:30:56 Just an FYI, but this whole thing could be switche
no longer working on chromium 2014/05/02 14:30:47 Sounds great.
72 thread_.message_loop()->PostDelayedTask( 78 thread_.message_loop()->PostDelayedTask(
73 FROM_HERE, 79 FROM_HERE,
74 base::Bind(&FakeAudioInputStream::DoCallback, base::Unretained(this)), 80 base::Bind(&FakeAudioInputStream::DoCallback, base::Unretained(this)),
75 callback_interval_); 81 callback_interval_);
76 } 82 }
77 83
78 void FakeAudioInputStream::DoCallback() { 84 void FakeAudioInputStream::DoCallback() {
79 DCHECK(callback_); 85 DCHECK(callback_);
80 86
87 const TimeTicks now = TimeTicks::Now();
88 base::TimeDelta next_callback_time =
89 last_callback_time_ + callback_interval_ * 2 - now;
90
91 // If we are falling behind, try to catch up as much as we can in the next
92 // callback.
93 if (next_callback_time < base::TimeDelta())
94 next_callback_time = base::TimeDelta();
95
96 // Accumulate the time from the last beep.
97 interval_from_last_beep_ += now - last_callback_time_;
98
99 last_callback_time_ = now;
100
81 memset(buffer_.get(), 0, buffer_size_); 101 memset(buffer_.get(), 0, buffer_size_);
82 102
83 bool should_beep = false; 103 bool should_beep = false;
84 { 104 {
85 BeepContext* beep_context = g_beep_context.Pointer(); 105 BeepContext* beep_context = g_beep_context.Pointer();
86 base::AutoLock auto_lock(beep_context->beep_lock); 106 base::AutoLock auto_lock(beep_context->beep_lock);
87 should_beep = beep_context->beep_once; 107 if (beep_context->automatic) {
88 beep_context->beep_once = false; 108 int delta_ms = interval_from_last_beep_.InMilliseconds() -
109 kAutomaticBeepIntervalInMs;
110 if (delta_ms > 0) {
DaleCurtis 2014/04/29 17:30:56 just use > base::TimeDelta to avoid converting bac
no longer working on chromium 2014/05/02 14:30:47 Done.
111 should_beep = true;
112 interval_from_last_beep_ = TimeDelta::FromMilliseconds(delta_ms);
113 }
114 } else {
115 should_beep = beep_context->beep_once;
116 beep_context->beep_once = false;
117 }
89 } 118 }
90 119
91 // If this object was instructed to generate a beep or has started to 120 // If this object was instructed to generate a beep or has started to
92 // generate a beep sound. 121 // generate a beep sound.
93 if (should_beep || beep_generated_in_buffers_) { 122 if (should_beep || beep_generated_in_buffers_) {
94 // Compute the number of frames to output high value. Then compute the 123 // Compute the number of frames to output high value. Then compute the
95 // number of bytes based on channels and bits per channel. 124 // number of bytes based on channels and bits per channel.
96 int high_frames = beep_period_in_frames_ / 2; 125 int high_frames = beep_period_in_frames_ / 2;
97 int high_bytes = high_frames * params_.bits_per_sample() * 126 int high_bytes = high_frames * params_.bits_per_sample() *
98 params_.channels() / 8; 127 params_.channels() / 8;
99 128
100 // Separate high and low with the same number of bytes to generate a 129 // Separate high and low with the same number of bytes to generate a
101 // square wave. 130 // square wave.
102 int position = 0; 131 int position = 0;
103 while (position + high_bytes <= buffer_size_) { 132 while (position + high_bytes <= buffer_size_) {
104 // Write high values first. 133 // Write high values first.
105 memset(buffer_.get() + position, 128, high_bytes); 134 memset(buffer_.get() + position, 128, high_bytes);
106
107 // Then leave low values in the buffer with |high_bytes|. 135 // Then leave low values in the buffer with |high_bytes|.
108 position += high_bytes * 2; 136 position += high_bytes * 2;
109 } 137 }
110 138
111 ++beep_generated_in_buffers_; 139 ++beep_generated_in_buffers_;
112 if (beep_generated_in_buffers_ >= beep_duration_in_buffers_) 140 if (beep_generated_in_buffers_ >= beep_duration_in_buffers_)
113 beep_generated_in_buffers_ = 0; 141 beep_generated_in_buffers_ = 0;
114 } 142 }
115 143
116 callback_->OnData(this, buffer_.get(), buffer_size_, buffer_size_, 1.0); 144 callback_->OnData(this, buffer_.get(), buffer_size_, buffer_size_, 1.0);
117 frames_elapsed_ += params_.frames_per_buffer(); 145 frames_elapsed_ += params_.frames_per_buffer();
118 146
119 const TimeTicks now = TimeTicks::Now();
120 base::TimeDelta next_callback_time =
121 last_callback_time_ + callback_interval_ * 2 - now;
122
123 // If we are falling behind, try to catch up as much as we can in the next
124 // callback.
125 if (next_callback_time < base::TimeDelta())
126 next_callback_time = base::TimeDelta();
127
128 last_callback_time_ = now;
129 thread_.message_loop()->PostDelayedTask( 147 thread_.message_loop()->PostDelayedTask(
130 FROM_HERE, 148 FROM_HERE,
131 base::Bind(&FakeAudioInputStream::DoCallback, base::Unretained(this)), 149 base::Bind(&FakeAudioInputStream::DoCallback, base::Unretained(this)),
132 next_callback_time); 150 next_callback_time);
133 } 151 }
134 152
135 void FakeAudioInputStream::Stop() { 153 void FakeAudioInputStream::Stop() {
136 thread_.Stop(); 154 thread_.Stop();
137 callback_ = NULL; 155 callback_ = NULL;
138 } 156 }
(...skipping 17 matching lines...) Expand all
156 174
157 bool FakeAudioInputStream::GetAutomaticGainControl() { 175 bool FakeAudioInputStream::GetAutomaticGainControl() {
158 return true; 176 return true;
159 } 177 }
160 178
161 // static 179 // static
162 void FakeAudioInputStream::BeepOnce() { 180 void FakeAudioInputStream::BeepOnce() {
163 BeepContext* beep_context = g_beep_context.Pointer(); 181 BeepContext* beep_context = g_beep_context.Pointer();
164 base::AutoLock auto_lock(beep_context->beep_lock); 182 base::AutoLock auto_lock(beep_context->beep_lock);
165 beep_context->beep_once = true; 183 beep_context->beep_once = true;
184 beep_context->automatic = false;
166 } 185 }
167 186
168 } // namespace media 187 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698