OLD | NEW |
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 #include <vector> |
10 | 10 |
11 #include "ppapi/cpp/audio_config.h" | 11 #include "ppapi/cpp/audio_config.h" |
12 #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" | 13 #include "ppapi/cpp/dev/device_ref_dev.h" |
14 #include "ppapi/cpp/graphics_2d.h" | 14 #include "ppapi/cpp/graphics_2d.h" |
15 #include "ppapi/cpp/image_data.h" | 15 #include "ppapi/cpp/image_data.h" |
16 #include "ppapi/cpp/instance.h" | 16 #include "ppapi/cpp/instance.h" |
17 #include "ppapi/cpp/logging.h" | 17 #include "ppapi/cpp/logging.h" |
18 #include "ppapi/cpp/module.h" | 18 #include "ppapi/cpp/module.h" |
19 #include "ppapi/cpp/rect.h" | 19 #include "ppapi/cpp/rect.h" |
20 #include "ppapi/cpp/size.h" | 20 #include "ppapi/cpp/size.h" |
21 #include "ppapi/utility/completion_callback_factory.h" | 21 #include "ppapi/utility/completion_callback_factory.h" |
22 | 22 |
23 // When compiling natively on Windows, PostMessage can be #define-d to | 23 // When compiling natively on Windows, PostMessage can be #define-d to |
24 // something else. | 24 // something else. |
25 #ifdef PostMessage | 25 #ifdef PostMessage |
26 #undef PostMessage | 26 #undef PostMessage |
27 #endif | 27 #endif |
28 | 28 |
| 29 namespace { |
| 30 |
| 31 // This sample frequency is guaranteed to work. |
| 32 const PP_AudioSampleRate kSampleFrequency = PP_AUDIOSAMPLERATE_44100; |
| 33 const uint32_t kSampleCount = 1024; |
| 34 const uint32_t kChannelCount = 1; |
| 35 |
| 36 } // namespace |
| 37 |
29 class MyInstance : public pp::Instance { | 38 class MyInstance : public pp::Instance { |
30 public: | 39 public: |
31 explicit MyInstance(PP_Instance instance) | 40 explicit MyInstance(PP_Instance instance) |
32 : pp::Instance(instance), | 41 : pp::Instance(instance), |
33 callback_factory_(this), | 42 callback_factory_(this), |
34 sample_count_(0), | 43 sample_count_(0), |
35 channel_count_(0), | 44 channel_count_(0), |
36 samples_(NULL), | 45 samples_(NULL), |
37 timer_interval_(0), | 46 timer_interval_(0), |
38 pending_paint_(false), | 47 pending_paint_(false), |
39 waiting_for_flush_completion_(false), | 48 waiting_for_flush_completion_(false) { |
40 audio_input_0_1_(0), | |
41 audio_input_interface_0_1_(NULL) { | |
42 } | 49 } |
43 virtual ~MyInstance() { | 50 virtual ~MyInstance() { |
44 if (!audio_input_.is_null()) { | 51 audio_input_.Close(); |
45 audio_input_.Close(); | |
46 } else if (audio_input_0_1_ != 0) { | |
47 audio_input_interface_0_1_->StopCapture(audio_input_0_1_); | |
48 pp::Module::Get()->core()->ReleaseResource(audio_input_0_1_); | |
49 } | |
50 | 52 |
51 delete[] samples_; | 53 delete[] samples_; |
52 } | 54 } |
53 | 55 |
54 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | 56 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { |
55 // This sample frequency is guaranteed to work. | |
56 const PP_AudioSampleRate kSampleFrequency = PP_AUDIOSAMPLERATE_44100; | |
57 const uint32_t kSampleCount = 1024; | |
58 const uint32_t kChannelCount = 1; | |
59 | |
60 sample_count_ = pp::AudioConfig::RecommendSampleFrameCount(this, | 57 sample_count_ = pp::AudioConfig::RecommendSampleFrameCount(this, |
61 kSampleFrequency, | 58 kSampleFrequency, |
62 kSampleCount); | 59 kSampleCount); |
63 PP_DCHECK(sample_count_ > 0); | 60 PP_DCHECK(sample_count_ > 0); |
64 channel_count_ = kChannelCount; | 61 channel_count_ = kChannelCount; |
65 pp::AudioConfig config = pp::AudioConfig(this, | |
66 kSampleFrequency, | |
67 sample_count_); | |
68 samples_ = new int16_t[sample_count_ * channel_count_]; | 62 samples_ = new int16_t[sample_count_ * channel_count_]; |
69 memset(samples_, 0, sample_count_ * channel_count_ * sizeof(int16_t)); | 63 memset(samples_, 0, sample_count_ * channel_count_ * sizeof(int16_t)); |
70 audio_input_ = pp::AudioInput_Dev(this, config, CaptureCallback, this); | |
71 | 64 |
72 audio_input_interface_0_1_ = static_cast<const PPB_AudioInput_Dev_0_1*>( | 65 audio_input_ = pp::AudioInput_Dev(this); |
73 pp::Module::Get()->GetBrowserInterface( | |
74 PPB_AUDIO_INPUT_DEV_INTERFACE_0_1)); | |
75 if (!audio_input_interface_0_1_) | |
76 return false; | |
77 | 66 |
78 // Try to ensure that we pick up a new set of samples between each | 67 // Try to ensure that we pick up a new set of samples between each |
79 // timer-generated repaint. | 68 // timer-generated repaint. |
80 timer_interval_ = (sample_count_ * 1000) / kSampleFrequency + 5; | 69 timer_interval_ = (sample_count_ * 1000) / kSampleFrequency + 5; |
81 ScheduleNextTimer(); | 70 ScheduleNextTimer(); |
82 | 71 |
83 return true; | 72 return true; |
84 } | 73 } |
85 | 74 |
86 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) { | 75 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) { |
(...skipping 13 matching lines...) Expand all Loading... |
100 std::string event = message_data.AsString(); | 89 std::string event = message_data.AsString(); |
101 if (event == "PageInitialized") { | 90 if (event == "PageInitialized") { |
102 pp::CompletionCallbackWithOutput<std::vector<pp::DeviceRef_Dev> > | 91 pp::CompletionCallbackWithOutput<std::vector<pp::DeviceRef_Dev> > |
103 callback = callback_factory_.NewCallbackWithOutput( | 92 callback = callback_factory_.NewCallbackWithOutput( |
104 &MyInstance::EnumerateDevicesFinished); | 93 &MyInstance::EnumerateDevicesFinished); |
105 int32_t result = audio_input_.EnumerateDevices(callback); | 94 int32_t result = audio_input_.EnumerateDevices(callback); |
106 if (result != PP_OK_COMPLETIONPENDING) | 95 if (result != PP_OK_COMPLETIONPENDING) |
107 PostMessage(pp::Var("EnumerationFailed")); | 96 PostMessage(pp::Var("EnumerationFailed")); |
108 } else if (event == "UseDefault") { | 97 } else if (event == "UseDefault") { |
109 Open(pp::DeviceRef_Dev()); | 98 Open(pp::DeviceRef_Dev()); |
110 } else if (event == "UseDefault(v0.1)") { | |
111 audio_input_0_1_ = audio_input_interface_0_1_->Create( | |
112 pp_instance(), audio_input_.config().pp_resource(), | |
113 CaptureCallback, this); | |
114 if (audio_input_0_1_ != 0) { | |
115 if (!audio_input_interface_0_1_->StartCapture(audio_input_0_1_)) | |
116 PostMessage(pp::Var("StartFailed")); | |
117 } else { | |
118 PostMessage(pp::Var("OpenFailed")); | |
119 } | |
120 | |
121 audio_input_ = pp::AudioInput_Dev(); | |
122 } else if (event == "Stop") { | 99 } else if (event == "Stop") { |
123 Stop(); | 100 Stop(); |
124 } else if (event == "Start") { | 101 } else if (event == "Start") { |
125 Start(); | 102 Start(); |
126 } | 103 } |
127 } else if (message_data.is_number()) { | 104 } else if (message_data.is_number()) { |
128 int index = message_data.AsInt(); | 105 int index = message_data.AsInt(); |
129 if (index >= 0 && index < static_cast<int>(devices_.size())) { | 106 if (index >= 0 && index < static_cast<int>(devices_.size())) { |
130 Open(devices_[index]); | 107 Open(devices_[index]); |
131 } else { | 108 } else { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 uint32_t buffer_size = | 195 uint32_t buffer_size = |
219 thiz->sample_count_ * thiz->channel_count_ * sizeof(int16_t); | 196 thiz->sample_count_ * thiz->channel_count_ * sizeof(int16_t); |
220 PP_DCHECK(num_bytes <= buffer_size); | 197 PP_DCHECK(num_bytes <= buffer_size); |
221 PP_DCHECK(num_bytes % (thiz->channel_count_ * sizeof(int16_t)) == 0); | 198 PP_DCHECK(num_bytes % (thiz->channel_count_ * sizeof(int16_t)) == 0); |
222 memcpy(thiz->samples_, samples, num_bytes); | 199 memcpy(thiz->samples_, samples, num_bytes); |
223 memset(reinterpret_cast<char*>(thiz->samples_) + num_bytes, 0, | 200 memset(reinterpret_cast<char*>(thiz->samples_) + num_bytes, 0, |
224 buffer_size - num_bytes); | 201 buffer_size - num_bytes); |
225 } | 202 } |
226 | 203 |
227 void Open(const pp::DeviceRef_Dev& device) { | 204 void Open(const pp::DeviceRef_Dev& device) { |
| 205 pp::AudioConfig config = pp::AudioConfig(this, |
| 206 kSampleFrequency, |
| 207 sample_count_); |
228 pp::CompletionCallback callback = callback_factory_.NewCallback( | 208 pp::CompletionCallback callback = callback_factory_.NewCallback( |
229 &MyInstance::OpenFinished); | 209 &MyInstance::OpenFinished); |
230 int32_t result = audio_input_.Open(device, callback); | 210 int32_t result = audio_input_.Open(device, config, CaptureCallback, this, |
| 211 callback); |
231 if (result != PP_OK_COMPLETIONPENDING) | 212 if (result != PP_OK_COMPLETIONPENDING) |
232 PostMessage(pp::Var("OpenFailed")); | 213 PostMessage(pp::Var("OpenFailed")); |
233 } | 214 } |
234 | 215 |
235 void Stop() { | 216 void Stop() { |
236 if (!audio_input_.is_null()) { | 217 if (!audio_input_.StopCapture()) |
237 if (!audio_input_.StopCapture()) | 218 PostMessage(pp::Var("StopFailed")); |
238 PostMessage(pp::Var("StopFailed")); | |
239 } else if (audio_input_0_1_ != 0) { | |
240 if (!audio_input_interface_0_1_->StopCapture(audio_input_0_1_)) | |
241 PostMessage(pp::Var("StopFailed")); | |
242 } | |
243 } | 219 } |
244 | 220 |
245 void Start() { | 221 void Start() { |
246 if (!audio_input_.is_null()) { | 222 if (!audio_input_.StartCapture()) |
247 if (!audio_input_.StartCapture()) | 223 PostMessage(pp::Var("StartFailed")); |
248 PostMessage(pp::Var("StartFailed")); | |
249 } else if (audio_input_0_1_ != 0) { | |
250 if (!audio_input_interface_0_1_->StartCapture(audio_input_0_1_)) | |
251 PostMessage(pp::Var("StartFailed")); | |
252 } | |
253 } | 224 } |
254 | 225 |
255 void EnumerateDevicesFinished(int32_t result, | 226 void EnumerateDevicesFinished(int32_t result, |
256 std::vector<pp::DeviceRef_Dev>& devices) { | 227 std::vector<pp::DeviceRef_Dev>& devices) { |
257 static const char* const kDelimiter = "#__#"; | 228 static const char* const kDelimiter = "#__#"; |
258 | 229 |
259 if (result == PP_OK) { | 230 if (result == PP_OK) { |
260 devices_.swap(devices); | 231 devices_.swap(devices); |
261 std::string device_names; | 232 std::string device_names; |
262 for (size_t index = 0; index < devices_.size(); ++index) { | 233 for (size_t index = 0; index < devices_.size(); ++index) { |
(...skipping 28 matching lines...) Expand all Loading... |
291 int32_t timer_interval_; | 262 int32_t timer_interval_; |
292 | 263 |
293 // Painting stuff. | 264 // Painting stuff. |
294 pp::Size size_; | 265 pp::Size size_; |
295 pp::Graphics2D device_context_; | 266 pp::Graphics2D device_context_; |
296 bool pending_paint_; | 267 bool pending_paint_; |
297 bool waiting_for_flush_completion_; | 268 bool waiting_for_flush_completion_; |
298 | 269 |
299 pp::AudioInput_Dev audio_input_; | 270 pp::AudioInput_Dev audio_input_; |
300 | 271 |
301 PP_Resource audio_input_0_1_; | |
302 const PPB_AudioInput_Dev_0_1* audio_input_interface_0_1_; | |
303 | |
304 std::vector<pp::DeviceRef_Dev> devices_; | 272 std::vector<pp::DeviceRef_Dev> devices_; |
305 }; | 273 }; |
306 | 274 |
307 class MyModule : public pp::Module { | 275 class MyModule : public pp::Module { |
308 public: | 276 public: |
309 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 277 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
310 return new MyInstance(instance); | 278 return new MyInstance(instance); |
311 } | 279 } |
312 }; | 280 }; |
313 | 281 |
314 namespace pp { | 282 namespace pp { |
315 | 283 |
316 // Factory function for your specialization of the Module object. | 284 // Factory function for your specialization of the Module object. |
317 Module* CreateModule() { | 285 Module* CreateModule() { |
318 return new MyModule(); | 286 return new MyModule(); |
319 } | 287 } |
320 | 288 |
321 } // namespace pp | 289 } // namespace pp |
OLD | NEW |