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

Side by Side Diff: ppapi/examples/audio_input/audio_input.cc

Issue 9557007: PPB_AudioInput_Dev: support multiple audio input devices - Part 1. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Changes in response to Trung's comments. Created 8 years, 9 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
« no previous file with comments | « ppapi/cpp/dev/audio_input_dev.cc ('k') | ppapi/examples/audio_input/audio_input.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <string.h> 5 #include <string.h>
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <vector>
9 10
10 #include "ppapi/cpp/audio_config.h" 11 #include "ppapi/cpp/audio_config.h"
11 #include "ppapi/cpp/dev/audio_input_dev.h" 12 #include "ppapi/cpp/dev/audio_input_dev.h"
13 #include "ppapi/cpp/dev/device_ref_dev.h"
12 #include "ppapi/cpp/graphics_2d.h" 14 #include "ppapi/cpp/graphics_2d.h"
13 #include "ppapi/cpp/image_data.h" 15 #include "ppapi/cpp/image_data.h"
14 #include "ppapi/cpp/instance.h" 16 #include "ppapi/cpp/instance.h"
15 #include "ppapi/cpp/logging.h" 17 #include "ppapi/cpp/logging.h"
16 #include "ppapi/cpp/module.h" 18 #include "ppapi/cpp/module.h"
17 #include "ppapi/cpp/rect.h" 19 #include "ppapi/cpp/rect.h"
18 #include "ppapi/cpp/size.h" 20 #include "ppapi/cpp/size.h"
19 #include "ppapi/utility/completion_callback_factory.h" 21 #include "ppapi/utility/completion_callback_factory.h"
20 22
21 class MyInstance : public pp::Instance { 23 class MyInstance : public pp::Instance {
22 public: 24 public:
23 explicit MyInstance(PP_Instance instance) 25 explicit MyInstance(PP_Instance instance)
24 : pp::Instance(instance), 26 : pp::Instance(instance),
25 callback_factory_(this), 27 callback_factory_(this),
26 sample_count_(0), 28 sample_count_(0),
27 channel_count_(0), 29 channel_count_(0),
28 samples_(NULL), 30 samples_(NULL),
29 timer_interval_(0), 31 timer_interval_(0),
30 pending_paint_(false), 32 pending_paint_(false),
31 waiting_for_flush_completion_(false) { 33 waiting_for_flush_completion_(false),
34 audio_input_0_1_(0),
35 audio_input_interface_0_1_(NULL) {
32 } 36 }
33 virtual ~MyInstance() { 37 virtual ~MyInstance() {
34 audio_input_.StopCapture(); 38 if (!audio_input_.is_null()) {
39 audio_input_.Close();
40 } else if (audio_input_0_1_ != 0) {
41 audio_input_interface_0_1_->StopCapture(audio_input_0_1_);
42 pp::Module::Get()->core()->ReleaseResource(audio_input_0_1_);
43 }
44
35 delete[] samples_; 45 delete[] samples_;
36 } 46 }
37 47
38 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { 48 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
39 // This sample frequency is guaranteed to work. 49 // This sample frequency is guaranteed to work.
40 const PP_AudioSampleRate kSampleFrequency = PP_AUDIOSAMPLERATE_44100; 50 const PP_AudioSampleRate kSampleFrequency = PP_AUDIOSAMPLERATE_44100;
41 const uint32_t kSampleCount = 1024; 51 const uint32_t kSampleCount = 1024;
42 const uint32_t kChannelCount = 1; 52 const uint32_t kChannelCount = 1;
43 53
44 sample_count_ = pp::AudioConfig::RecommendSampleFrameCount(this, 54 sample_count_ = pp::AudioConfig::RecommendSampleFrameCount(this,
45 kSampleFrequency, 55 kSampleFrequency,
46 kSampleCount); 56 kSampleCount);
47 PP_DCHECK(sample_count_ > 0); 57 PP_DCHECK(sample_count_ > 0);
48 channel_count_ = kChannelCount; 58 channel_count_ = kChannelCount;
49 pp::AudioConfig config = pp::AudioConfig(this, 59 pp::AudioConfig config = pp::AudioConfig(this,
50 kSampleFrequency, 60 kSampleFrequency,
51 sample_count_); 61 sample_count_);
52 samples_ = new int16_t[sample_count_ * channel_count_]; 62 samples_ = new int16_t[sample_count_ * channel_count_];
53 memset(samples_, 0, sample_count_ * channel_count_ * sizeof(int16_t)); 63 memset(samples_, 0, sample_count_ * channel_count_ * sizeof(int16_t));
54 audio_input_ = pp::AudioInput_Dev(this, config, CaptureCallback, this); 64 audio_input_ = pp::AudioInput_Dev(this, config, CaptureCallback, this);
55 if (!audio_input_.StartCapture()) 65
66 audio_input_interface_0_1_ = static_cast<const PPB_AudioInput_Dev_0_1*>(
67 pp::Module::Get()->GetBrowserInterface(
68 PPB_AUDIO_INPUT_DEV_INTERFACE_0_1));
69 if (!audio_input_interface_0_1_)
56 return false; 70 return false;
57 71
58 // Try to ensure that we pick up a new set of samples between each 72 // Try to ensure that we pick up a new set of samples between each
59 // timer-generated repaint. 73 // timer-generated repaint.
60 timer_interval_ = (sample_count_ * 1000) / kSampleFrequency + 5; 74 timer_interval_ = (sample_count_ * 1000) / kSampleFrequency + 5;
61 ScheduleNextTimer(); 75 ScheduleNextTimer();
62 76
63 return true; 77 return true;
64 } 78 }
65 79
66 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) { 80 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
67 if (position.size() == size_) 81 if (position.size() == size_)
68 return; 82 return;
69 83
70 size_ = position.size(); 84 size_ = position.size();
71 device_context_ = pp::Graphics2D(this, size_, false); 85 device_context_ = pp::Graphics2D(this, size_, false);
72 if (!BindGraphics(device_context_)) 86 if (!BindGraphics(device_context_))
73 return; 87 return;
74 88
75 Paint(); 89 Paint();
76 } 90 }
77 91
92 virtual void HandleMessage(const pp::Var& message_data) {
93 if (message_data.is_string()) {
94 std::string event = message_data.AsString();
95 if (event == "PageInitialized") {
96 pp::CompletionCallback callback = callback_factory_.NewCallback(
97 &MyInstance::EnumerateDevicesFinished);
98 int32_t result = audio_input_.EnumerateDevices(&devices_, callback);
99 if (result != PP_OK_COMPLETIONPENDING)
100 PostMessage(pp::Var("EnumerationFailed"));
101 } else if (event == "UseDefault") {
102 Open(pp::DeviceRef_Dev());
103 } else if (event == "UseDefault(v0.1)") {
104 audio_input_0_1_ = audio_input_interface_0_1_->Create(
105 pp_instance(), audio_input_.config().pp_resource(),
106 CaptureCallback, this);
107 if (audio_input_0_1_ != 0) {
108 if (!audio_input_interface_0_1_->StartCapture(audio_input_0_1_))
109 PostMessage(pp::Var("StartFailed"));
110 } else {
111 PostMessage(pp::Var("OpenFailed"));
112 }
113
114 audio_input_ = pp::AudioInput_Dev();
115 } else if (event == "Stop") {
116 Stop();
117 }
118 } else if (message_data.is_number()) {
119 int index = message_data.AsInt();
120 if (index >= 0 && index < static_cast<int>(devices_.size())) {
121 Open(devices_[index]);
122 } else {
123 PP_NOTREACHED();
124 }
125 }
126 }
127
78 private: 128 private:
79 void ScheduleNextTimer() { 129 void ScheduleNextTimer() {
80 PP_DCHECK(timer_interval_ > 0); 130 PP_DCHECK(timer_interval_ > 0);
81 pp::Module::Get()->core()->CallOnMainThread( 131 pp::Module::Get()->core()->CallOnMainThread(
82 timer_interval_, 132 timer_interval_,
83 callback_factory_.NewRequiredCallback(&MyInstance::OnTimer), 133 callback_factory_.NewRequiredCallback(&MyInstance::OnTimer),
84 0); 134 0);
85 } 135 }
86 136
87 void OnTimer(int32_t) { 137 void OnTimer(int32_t) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 // writing to a valid region of memory. 204 // writing to a valid region of memory.
155 static void CaptureCallback(const void* samples, 205 static void CaptureCallback(const void* samples,
156 uint32_t num_bytes, 206 uint32_t num_bytes,
157 void* ctx) { 207 void* ctx) {
158 MyInstance* thiz = static_cast<MyInstance*>(ctx); 208 MyInstance* thiz = static_cast<MyInstance*>(ctx);
159 PP_DCHECK(num_bytes == 209 PP_DCHECK(num_bytes ==
160 thiz->sample_count_ * thiz->channel_count_ * sizeof(int16_t)); 210 thiz->sample_count_ * thiz->channel_count_ * sizeof(int16_t));
161 memcpy(thiz->samples_, samples, num_bytes); 211 memcpy(thiz->samples_, samples, num_bytes);
162 } 212 }
163 213
214 void Open(const pp::DeviceRef_Dev& device) {
215 pp::CompletionCallback callback = callback_factory_.NewCallback(
216 &MyInstance::OpenFinished);
217 int32_t result = audio_input_.Open(device, callback);
218 if (result != PP_OK_COMPLETIONPENDING)
219 PostMessage(pp::Var("OpenFailed"));
220 }
221
222 void Stop() {
223 if (!audio_input_.is_null()) {
224 if (!audio_input_.StopCapture())
225 PostMessage(pp::Var("StopFailed"));
226 } else if (audio_input_0_1_ != 0) {
227 if (!audio_input_interface_0_1_->StopCapture(audio_input_0_1_))
228 PostMessage(pp::Var("StopFailed"));
229 }
230 }
231
232 void EnumerateDevicesFinished(int32_t result) {
233 static const char* const kDelimiter = "#__#";
234
235 if (result == PP_OK) {
236 std::string device_names;
237 for (size_t index = 0; index < devices_.size(); ++index) {
238 pp::Var name = devices_[index].GetName();
239 PP_DCHECK(name.is_string());
240
241 if (index != 0)
242 device_names += kDelimiter;
243 device_names += name.AsString();
244 }
245 PostMessage(pp::Var(device_names));
246 } else {
247 PostMessage(pp::Var("EnumerationFailed"));
248 }
249 }
250
251 void OpenFinished(int32_t result) {
252 if (result == PP_OK) {
253 if (!audio_input_.StartCapture())
254 PostMessage(pp::Var("StartFailed"));
255 } else {
256 PostMessage(pp::Var("OpenFailed"));
257 }
258 }
259
164 pp::CompletionCallbackFactory<MyInstance> callback_factory_; 260 pp::CompletionCallbackFactory<MyInstance> callback_factory_;
165 261
166 uint32_t sample_count_; 262 uint32_t sample_count_;
167 uint32_t channel_count_; 263 uint32_t channel_count_;
168 int16_t* samples_; 264 int16_t* samples_;
169 265
170 int32_t timer_interval_; 266 int32_t timer_interval_;
171 267
172 // Painting stuff. 268 // Painting stuff.
173 pp::Size size_; 269 pp::Size size_;
174 pp::Graphics2D device_context_; 270 pp::Graphics2D device_context_;
175 bool pending_paint_; 271 bool pending_paint_;
176 bool waiting_for_flush_completion_; 272 bool waiting_for_flush_completion_;
177 273
178 pp::AudioInput_Dev audio_input_; 274 pp::AudioInput_Dev audio_input_;
275
276 PP_Resource audio_input_0_1_;
277 const PPB_AudioInput_Dev_0_1* audio_input_interface_0_1_;
278
279 std::vector<pp::DeviceRef_Dev> devices_;
179 }; 280 };
180 281
181 class MyModule : public pp::Module { 282 class MyModule : public pp::Module {
182 public: 283 public:
183 virtual pp::Instance* CreateInstance(PP_Instance instance) { 284 virtual pp::Instance* CreateInstance(PP_Instance instance) {
184 return new MyInstance(instance); 285 return new MyInstance(instance);
185 } 286 }
186 }; 287 };
187 288
188 namespace pp { 289 namespace pp {
189 290
190 // Factory function for your specialization of the Module object. 291 // Factory function for your specialization of the Module object.
191 Module* CreateModule() { 292 Module* CreateModule() {
192 return new MyModule(); 293 return new MyModule();
193 } 294 }
194 295
195 } // namespace pp 296 } // namespace pp
OLDNEW
« no previous file with comments | « ppapi/cpp/dev/audio_input_dev.cc ('k') | ppapi/examples/audio_input/audio_input.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698