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

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScope.cpp

Issue 2793593002: AudioWorklet prototype
Patch Set: Merge changes, AudioParam bug fix Created 3 years, 5 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "modules/webaudio/AudioWorkletGlobalScope.h" 5 #include "modules/webaudio/AudioWorkletGlobalScope.h"
6 6
7 #include "bindings/core/v8/IDLTypes.h" 7 #include "bindings/core/v8/IDLTypes.h"
8 #include "bindings/core/v8/NativeValueTraitsImpl.h" 8 #include "bindings/core/v8/NativeValueTraitsImpl.h"
9 #include "bindings/core/v8/ToV8ForCore.h" 9 #include "bindings/core/v8/ToV8ForCore.h"
10 #include "bindings/core/v8/V8BindingForCore.h" 10 #include "bindings/core/v8/V8BindingForCore.h"
11 #include "bindings/core/v8/V8ObjectBuilder.h"
11 #include "bindings/core/v8/WorkerOrWorkletScriptController.h" 12 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
12 #include "bindings/modules/v8/V8AudioParamDescriptor.h" 13 #include "bindings/modules/v8/V8AudioParamDescriptor.h"
14 #include "core/dom/DOMTypedArray.h"
13 #include "core/dom/ExceptionCode.h" 15 #include "core/dom/ExceptionCode.h"
14 #include "modules/webaudio/AudioBuffer.h" 16 #include "modules/webaudio/AudioBuffer.h"
15 #include "modules/webaudio/AudioParamDescriptor.h" 17 #include "modules/webaudio/AudioParamDescriptor.h"
16 #include "modules/webaudio/AudioWorkletProcessor.h" 18 #include "modules/webaudio/AudioWorkletProcessor.h"
17 #include "modules/webaudio/AudioWorkletProcessorDefinition.h" 19 #include "modules/webaudio/AudioWorkletProcessorDefinition.h"
20 #include "platform/audio/AudioUtilities.h"
18 #include "platform/bindings/V8BindingMacros.h" 21 #include "platform/bindings/V8BindingMacros.h"
19 #include "platform/bindings/V8ObjectConstructor.h" 22 #include "platform/bindings/V8ObjectConstructor.h"
20 #include "platform/weborigin/SecurityOrigin.h" 23 #include "platform/weborigin/SecurityOrigin.h"
21 24
22 namespace blink { 25 namespace blink {
23 26
24 AudioWorkletGlobalScope* AudioWorkletGlobalScope::Create( 27 AudioWorkletGlobalScope* AudioWorkletGlobalScope::Create(
25 const KURL& url, 28 const KURL& url,
26 const String& user_agent, 29 const String& user_agent,
27 PassRefPtr<SecurityOrigin> security_origin, 30 PassRefPtr<SecurityOrigin> security_origin,
28 v8::Isolate* isolate, 31 v8::Isolate* isolate,
29 WorkerThread* thread, 32 WorkerThread* thread,
30 WorkerClients* worker_clients) { 33 WorkerClients* worker_clients) {
34 LOG(INFO) << "AudioWorkletGlobalScope::RegisterProcessor thread = "
35 << thread;
31 return new AudioWorkletGlobalScope(url, user_agent, 36 return new AudioWorkletGlobalScope(url, user_agent,
32 std::move(security_origin), isolate, 37 std::move(security_origin), isolate,
33 thread, worker_clients); 38 thread, worker_clients);
34 } 39 }
35 40
36 AudioWorkletGlobalScope::AudioWorkletGlobalScope( 41 AudioWorkletGlobalScope::AudioWorkletGlobalScope(
37 const KURL& url, 42 const KURL& url,
38 const String& user_agent, 43 const String& user_agent,
39 PassRefPtr<SecurityOrigin> security_origin, 44 PassRefPtr<SecurityOrigin> security_origin,
40 v8::Isolate* isolate, 45 v8::Isolate* isolate,
(...skipping 24 matching lines...) Expand all
65 // TODO(hongchan): this is not stated in the spec, but seems necessary. 70 // TODO(hongchan): this is not stated in the spec, but seems necessary.
66 // https://github.com/WebAudio/web-audio-api/issues/1172 71 // https://github.com/WebAudio/web-audio-api/issues/1172
67 if (name.IsEmpty()) { 72 if (name.IsEmpty()) {
68 exception_state.ThrowTypeError("The empty string is not a valid name."); 73 exception_state.ThrowTypeError("The empty string is not a valid name.");
69 return; 74 return;
70 } 75 }
71 76
72 v8::Isolate* isolate = ScriptController()->GetScriptState()->GetIsolate(); 77 v8::Isolate* isolate = ScriptController()->GetScriptState()->GetIsolate();
73 v8::Local<v8::Context> context = ScriptController()->GetContext(); 78 v8::Local<v8::Context> context = ScriptController()->GetContext();
74 79
80 // Get a handle for the class definition (i.e. constructor)
75 if (!class_definition.V8Value()->IsFunction()) { 81 if (!class_definition.V8Value()->IsFunction()) {
76 exception_state.ThrowTypeError( 82 exception_state.ThrowTypeError(
77 "The processor definition is neither 'class' nor 'function'."); 83 "The processor definition is neither 'class' nor 'function'.");
78 return; 84 return;
79 } 85 }
80 86
81 v8::Local<v8::Function> class_definition_local = 87 v8::Local<v8::Function> class_definition_local =
82 v8::Local<v8::Function>::Cast(class_definition.V8Value()); 88 v8::Local<v8::Function>::Cast(class_definition.V8Value());
83 89
90 // Get a handle for |prototype| object out of class definition.
84 v8::Local<v8::Value> prototype_value_local; 91 v8::Local<v8::Value> prototype_value_local;
85 bool prototype_extracted = 92 bool prototype_extracted =
86 class_definition_local->Get(context, V8String(isolate, "prototype")) 93 class_definition_local->Get(context, V8String(isolate, "prototype"))
87 .ToLocal(&prototype_value_local); 94 .ToLocal(&prototype_value_local);
88 DCHECK(prototype_extracted); 95 DCHECK(prototype_extracted);
89 96
90 v8::Local<v8::Object> prototype_object_local = 97 v8::Local<v8::Object> prototype_object_local =
91 v8::Local<v8::Object>::Cast(prototype_value_local); 98 v8::Local<v8::Object>::Cast(prototype_value_local);
92 99
100 // Extract |process| function.
93 v8::Local<v8::Value> process_value_local; 101 v8::Local<v8::Value> process_value_local;
94 bool process_extracted = 102 bool process_extracted =
95 prototype_object_local->Get(context, V8String(isolate, "process")) 103 prototype_object_local->Get(context, V8String(isolate, "process"))
96 .ToLocal(&process_value_local); 104 .ToLocal(&process_value_local);
97 DCHECK(process_extracted); 105 DCHECK(process_extracted);
98 106
99 if (process_value_local->IsNullOrUndefined()) { 107 if (process_value_local->IsNullOrUndefined()) {
100 exception_state.ThrowTypeError( 108 exception_state.ThrowTypeError(
101 "The 'process' function does not exist in the prototype."); 109 "The 'process' function does not exist in the prototype.");
102 return; 110 return;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 AudioWorkletProcessorDefinition* definition = FindDefinition(name); 159 AudioWorkletProcessorDefinition* definition = FindDefinition(name);
152 if (!definition) 160 if (!definition)
153 return nullptr; 161 return nullptr;
154 162
155 // V8 object instance construction: this construction process is here to make 163 // V8 object instance construction: this construction process is here to make
156 // the AudioWorkletProcessor class a thin wrapper of V8::Object instance. 164 // the AudioWorkletProcessor class a thin wrapper of V8::Object instance.
157 v8::Isolate* isolate = ScriptController()->GetScriptState()->GetIsolate(); 165 v8::Isolate* isolate = ScriptController()->GetScriptState()->GetIsolate();
158 v8::Local<v8::Object> instance_local; 166 v8::Local<v8::Object> instance_local;
159 if (!V8ObjectConstructor::NewInstance(isolate, 167 if (!V8ObjectConstructor::NewInstance(isolate,
160 definition->ConstructorLocal(isolate)) 168 definition->ConstructorLocal(isolate))
161 .ToLocal(&instance_local)) { 169 .ToLocal(&instance_local)) {
162 return nullptr; 170 return nullptr;
163 } 171 }
164 172
165 AudioWorkletProcessor* processor = AudioWorkletProcessor::Create(this, name); 173 AudioWorkletProcessor* processor =
174 AudioWorkletProcessor::Create(this, definition);
166 DCHECK(processor); 175 DCHECK(processor);
167 176
168 processor->SetInstance(isolate, instance_local); 177 processor->SetInstance(isolate, instance_local);
169 processor_instances_.push_back( 178 processor_instances_.push_back(
170 TraceWrapperMember<AudioWorkletProcessor>(this, processor)); 179 TraceWrapperMember<AudioWorkletProcessor>(this, processor));
171 180
172 return processor; 181 return processor;
173 } 182 }
174 183
175 bool AudioWorkletGlobalScope::Process(AudioWorkletProcessor* processor, 184 bool AudioWorkletGlobalScope::Process(
176 AudioBuffer* input_buffer, 185 AudioWorkletProcessor* processor,
177 AudioBuffer* output_buffer) { 186 AudioBuffer* input_buffer,
187 AudioBuffer* output_buffer,
188 HashMap<String, AudioFloatArray*> audio_param_data_map) {
178 CHECK(input_buffer); 189 CHECK(input_buffer);
179 CHECK(output_buffer); 190 CHECK(output_buffer);
180 191
181 ScriptState* script_state = ScriptController()->GetScriptState(); 192 ScriptState* script_state = ScriptController()->GetScriptState();
193 v8::Isolate* isolate = script_state->GetIsolate();
194
182 ScriptState::Scope scope(script_state); 195 ScriptState::Scope scope(script_state);
183 196
184 v8::Isolate* isolate = script_state->GetIsolate();
185 AudioWorkletProcessorDefinition* definition = 197 AudioWorkletProcessorDefinition* definition =
186 FindDefinition(processor->GetName()); 198 FindDefinition(processor->GetName());
187 DCHECK(definition); 199 DCHECK(definition);
188 200
201 V8ObjectBuilder parameters_object(script_state);
202
203 for (const auto& param_name : audio_param_data_map.Keys()) {
204 DOMFloat32Array* param_data_array =
205 DOMFloat32Array::CreateOrNull(AudioUtilities::kRenderQuantumFrames);
206 const float* source = audio_param_data_map.at(param_name)->Data();
207 float* destination = param_data_array->Data();
208
209 memcpy(destination, source,
210 AudioUtilities::kRenderQuantumFrames * sizeof(float));
211
212 parameters_object.Add(
213 StringView(param_name),
214 ToV8(param_data_array, script_state->GetContext()->Global(), isolate));
215 }
216
189 v8::Local<v8::Value> argv[] = { 217 v8::Local<v8::Value> argv[] = {
190 ToV8(input_buffer, script_state->GetContext()->Global(), isolate), 218 ToV8(input_buffer, script_state->GetContext()->Global(), isolate),
191 ToV8(output_buffer, script_state->GetContext()->Global(), isolate)}; 219 ToV8(output_buffer, script_state->GetContext()->Global(), isolate),
220 parameters_object.V8Value()};
192 221
193 // TODO(hongchan): Catch exceptions thrown in the process method. The verbose 222 // TODO(hongchan): Catch exceptions thrown in the process method. The verbose
194 // options forces the TryCatch object to save the exception location. The 223 // options forces the TryCatch object to save the exception location. The
195 // pending exception should be handled later. 224 // pending exception should be handled later.
196 v8::TryCatch block(isolate); 225 v8::TryCatch block(isolate);
197 block.SetVerbose(true); 226 block.SetVerbose(true);
198 227
199 // Perform JS function process() in AudioWorkletProcessor instance. The actual 228 // Perform JS function process() in AudioWorkletProcessor instance. The actual
200 // V8 operation happens here to make the AudioWorkletProcessor class a thin 229 // V8 operation happens here to make the AudioWorkletProcessor class a thin
201 // wrapper of v8::Object instance. 230 // wrapper of v8::Object instance.
(...skipping 19 matching lines...) Expand all
221 for (auto definition : processor_definition_map_) 250 for (auto definition : processor_definition_map_)
222 visitor->TraceWrappers(definition.value); 251 visitor->TraceWrappers(definition.value);
223 252
224 for (auto processor : processor_instances_) 253 for (auto processor : processor_instances_)
225 visitor->TraceWrappers(processor); 254 visitor->TraceWrappers(processor);
226 255
227 ThreadedWorkletGlobalScope::TraceWrappers(visitor); 256 ThreadedWorkletGlobalScope::TraceWrappers(visitor);
228 } 257 }
229 258
230 } // namespace blink 259 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698