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

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

Issue 8662020: Pepper: Add an example/test plugin for audio input (a.k.a. microphone). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: oops Created 9 years 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 | « no previous file | 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
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <string.h>
6
7 #include <algorithm>
8 #include <limits>
9
10 #include "ppapi/cpp/audio_config.h"
11 #include "ppapi/cpp/completion_callback.h"
12 #include "ppapi/cpp/dev/audio_input_dev.h"
13 #include "ppapi/cpp/graphics_2d.h"
14 #include "ppapi/cpp/image_data.h"
15 #include "ppapi/cpp/instance.h"
16 #include "ppapi/cpp/logging.h"
17 #include "ppapi/cpp/module.h"
18 #include "ppapi/cpp/rect.h"
19 #include "ppapi/cpp/size.h"
20
21 class MyInstance : public pp::Instance {
22 public:
23 explicit MyInstance(PP_Instance instance)
24 : pp::Instance(instance),
25 callback_factory_(this),
26 sample_count_(0),
27 channel_count_(0),
28 samples_(NULL),
29 timer_interval_(0),
30 pending_paint_(false),
31 waiting_for_flush_completion_(false) {
32 }
33 virtual ~MyInstance() {
34 audio_input_.StopCapture();
35 delete[] samples_;
36 }
37
38 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
39 // This sample frequency is guaranteed to work.
40 const PP_AudioSampleRate kSampleFrequency = PP_AUDIOSAMPLERATE_44100;
41 const uint32_t kSampleCount = 1024;
42 const uint32_t kChannelCount = 1;
43
44 sample_count_ = pp::AudioConfig::RecommendSampleFrameCount(kSampleFrequency,
45 kSampleCount);
46 PP_DCHECK(sample_count_ > 0);
47 channel_count_ = kChannelCount;
48 pp::AudioConfig config = pp::AudioConfig(this,
49 kSampleFrequency,
50 sample_count_);
51 samples_ = new int16_t[sample_count_ * channel_count_];
52 memset(samples_, 0, sample_count_ * channel_count_ * sizeof(int16_t));
53 audio_input_ = pp::AudioInput_Dev(this, config, CaptureCallback, this);
54 if (!audio_input_.StartCapture())
55 return false;
56
57 // Try to ensure that we pick up a new set of samples between each
58 // timer-generated repaint.
59 timer_interval_ = (sample_count_ * 1000) / kSampleFrequency + 5;
60 ScheduleNextTimer();
61
62 return true;
63 }
64
65 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
66 if (position.size() == size_)
67 return;
68
69 size_ = position.size();
70 device_context_ = pp::Graphics2D(this, size_, false);
71 if (!BindGraphics(device_context_))
72 return;
73
74 Paint();
75 }
76
77 private:
78 void ScheduleNextTimer() {
79 PP_DCHECK(timer_interval_ > 0);
80 pp::Module::Get()->core()->CallOnMainThread(
81 timer_interval_,
82 callback_factory_.NewRequiredCallback(&MyInstance::OnTimer),
83 0);
84 }
85
86 void OnTimer(int32_t) {
87 ScheduleNextTimer();
88 Paint();
89 }
90
91 void DidFlush(int32_t result) {
92 waiting_for_flush_completion_ = false;
93 if (pending_paint_)
94 Paint();
95 }
96
97 void Paint() {
98 if (waiting_for_flush_completion_) {
99 pending_paint_ = true;
100 return;
101 }
102
103 pending_paint_ = false;
104
105 if (size_.IsEmpty())
106 return; // Nothing to do.
107
108 pp::ImageData image = PaintImage(size_);
109 if (!image.is_null()) {
110 device_context_.ReplaceContents(&image);
111 waiting_for_flush_completion_ = true;
112 device_context_.Flush(
113 callback_factory_.NewRequiredCallback(&MyInstance::DidFlush));
114 }
115 }
116
117 pp::ImageData PaintImage(const pp::Size& size) {
118 pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, false);
119 if (image.is_null())
120 return image;
121
122 // Clear to dark grey.
123 for (int y = 0; y < size.height(); y++) {
124 for (int x = 0; x < size.width(); x++)
125 *image.GetAddr32(pp::Point(x, y)) = 0xff202020;
126 }
127
128 int mid_height = size.height() / 2;
129 int max_amplitude = size.height() * 4 / 10;
130
131 // Draw some lines.
132 for (int x = 0; x < size.width(); x++) {
133 *image.GetAddr32(pp::Point(x, mid_height)) = 0xff606060;
134 *image.GetAddr32(pp::Point(x, mid_height + max_amplitude)) = 0xff404040;
135 *image.GetAddr32(pp::Point(x, mid_height - max_amplitude)) = 0xff404040;
136 }
137
138 // Draw our samples.
139 for (int x = 0, i = 0;
140 x < std::min(size.width(), static_cast<int>(sample_count_));
141 x++, i += channel_count_) {
142 int y = samples_[i] * max_amplitude /
143 (std::numeric_limits<int16_t>::max() + 1) + mid_height;
144 *image.GetAddr32(pp::Point(x, y)) = 0xffffffff;
145 }
146
147 return image;
148 }
149
150 // TODO(viettrungluu): Danger! We really should lock, but which thread
151 // primitives to use? In any case, the |StopCapture()| in the destructor
152 // shouldn't return until this callback is done, so at least we should be
153 // writing to a valid region of memory.
154 static void CaptureCallback(const void* samples,
155 uint32_t num_bytes,
156 void* ctx) {
157 MyInstance* thiz = static_cast<MyInstance*>(ctx);
158 PP_DCHECK(num_bytes ==
159 thiz->sample_count_ * thiz->channel_count_ * sizeof(int16_t));
160 memcpy(thiz->samples_, samples, num_bytes);
161 }
162
163 pp::CompletionCallbackFactory<MyInstance> callback_factory_;
164
165 uint32_t sample_count_;
166 uint32_t channel_count_;
167 int16_t* samples_;
168
169 int32_t timer_interval_;
170
171 // Painting stuff.
172 pp::Size size_;
173 pp::Graphics2D device_context_;
174 bool pending_paint_;
175 bool waiting_for_flush_completion_;
176
177 pp::AudioInput_Dev audio_input_;
178 };
179
180 class MyModule : public pp::Module {
181 public:
182 virtual pp::Instance* CreateInstance(PP_Instance instance) {
183 return new MyInstance(instance);
184 }
185 };
186
187 namespace pp {
188
189 // Factory function for your specialization of the Module object.
190 Module* CreateModule() {
191 return new MyModule();
192 }
193
194 } // namespace pp
OLDNEW
« no previous file with comments | « no previous file | ppapi/examples/audio_input/audio_input.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698