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

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: address review comments 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 pending_paint_ = false;
yzshen1 2011/11/23 21:21:17 nit: it might be better to make Paint() the only o
viettrungluu 2011/11/23 21:31:30 Done.
95 Paint();
96 }
97 }
98
99 void Paint() {
100 if (size_.IsEmpty()) {
101 pending_paint_ = false;
102 return;
103 }
104
105 if (waiting_for_flush_completion_) {
106 pending_paint_ = true;
107 return;
108 }
109
110 pp::ImageData image = PaintImage(size_);
111 if (!image.is_null()) {
112 device_context_.ReplaceContents(&image);
113 waiting_for_flush_completion_ = true;
114 device_context_.Flush(
115 callback_factory_.NewRequiredCallback(&MyInstance::DidFlush));
116 }
117 }
118
119 pp::ImageData PaintImage(const pp::Size& size) {
120 pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, false);
121 if (image.is_null())
122 return image;
123
124 // Clear to dark grey.
125 for (int y = 0; y < size.height(); y++) {
126 for (int x = 0; x < size.width(); x++)
127 *image.GetAddr32(pp::Point(x, y)) = 0xff202020;
128 }
129
130 int mid_height = size.height() / 2;
131 int max_amplitude = size.height() * 4 / 10;
132
133 // Draw some lines.
134 for (int x = 0; x < size.width(); x++) {
135 *image.GetAddr32(pp::Point(x, mid_height)) = 0xff606060;
136 *image.GetAddr32(pp::Point(x, mid_height + max_amplitude)) = 0xff404040;
137 *image.GetAddr32(pp::Point(x, mid_height - max_amplitude)) = 0xff404040;
138 }
139
140 // Draw our samples.
141 for (int x = 0, i = 0;
142 x < std::min(size.width(), static_cast<int>(sample_count_));
143 x++, i += channel_count_) {
144 int y = samples_[i] * max_amplitude /
145 (std::numeric_limits<int16_t>::max() + 1) + mid_height;
146 *image.GetAddr32(pp::Point(x, y)) = 0xffffffff;
147 }
148
149 return image;
150 }
151
152 // TODO(viettrungluu): Danger! We really should lock, but which thread
153 // primitives to use? In any case, the |StopCapture()| in the destructor
154 // shouldn't return until this callback is done, so at least we should be
155 // writing to a valid region of memory.
156 static void CaptureCallback(const void* samples,
157 uint32_t num_bytes,
158 void* ctx) {
159 MyInstance* thiz = static_cast<MyInstance*>(ctx);
160 PP_DCHECK(num_bytes ==
161 thiz->sample_count_ * channel_count_ * sizeof(int16_t));
yzshen1 2011/11/23 21:21:17 channel_count_ should be thiz->channel_count_, rig
viettrungluu 2011/11/23 21:31:30 Yes. I don't know how it managed to compile for me
162 memcpy(thiz->samples_, samples, num_bytes);
163 }
164
165 pp::CompletionCallbackFactory<MyInstance> callback_factory_;
166
167 uint32_t sample_count_;
168 uint32_t channel_count_;
169 int16_t* samples_;
170
171 int32_t timer_interval_;
172
173 // Painting stuff.
174 pp::Size size_;
175 pp::Graphics2D device_context_;
176 bool pending_paint_;
177 bool waiting_for_flush_completion_;
178
179
180 // Allocated in |Init()|, freed on destruction.
181 pp::AudioInput_Dev audio_input_;
182 };
183
184 class MyModule : public pp::Module {
185 public:
186 virtual pp::Instance* CreateInstance(PP_Instance instance) {
187 return new MyInstance(instance);
188 }
189 };
190
191 namespace pp {
192
193 // Factory function for your specialization of the Module object.
194 Module* CreateModule() {
195 return new MyModule();
196 }
197
198 } // 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