void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node, HashMap<AudioNode*, bool>& visitedNodes) { ASSERT(node); if (!node) return; // First check if this node is an AudioBufferSourceNode. If so, let it know about us so that doppler shift pitch can be taken into account. if (node->nodeType() == NodeTypeAudioBufferSource) { AudioBufferSourceNode* bufferSourceNode = static_cast<AudioBufferSourceNode*>(node); bufferSourceNode->setPannerNode(this); } else { // Go through all inputs to this node. for (unsigned i = 0; i < node->numberOfInputs(); ++i) { AudioNodeInput* input = node->input(i); // For each input, go through all of its connections, looking for AudioBufferSourceNodes. for (unsigned j = 0; j < input->numberOfRenderingConnections(); ++j) { AudioNodeOutput* connectedOutput = input->renderingOutput(j); AudioNode* connectedNode = connectedOutput->node(); HashMap<AudioNode*, bool>::iterator iterator = visitedNodes.find(connectedNode); // If we've seen this node already, we don't need to process it again. Otherwise, // mark it as visited and recurse through the node looking for sources. if (iterator == visitedNodes.end()) { visitedNodes.set(connectedNode, true); notifyAudioSourcesConnectedToNode(connectedNode, visitedNodes); // recurse } } } } }
void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node, HashSet<AudioNode*>& visitedNodes) { ASSERT(node); if (!node) return; // First check if this node is an AudioBufferSourceNode. If so, let it know about us so that doppler shift pitch can be taken into account. if (node->nodeType() == NodeTypeAudioBufferSource) { AudioBufferSourceNode* bufferSourceNode = reinterpret_cast<AudioBufferSourceNode*>(node); bufferSourceNode->setPannerNode(this); } else { // Go through all inputs to this node. for (unsigned i = 0; i < node->numberOfInputs(); ++i) { AudioNodeInput* input = node->input(i); // For each input, go through all of its connections, looking for AudioBufferSourceNodes. for (unsigned j = 0; j < input->numberOfRenderingConnections(); ++j) { AudioNodeOutput* connectedOutput = input->renderingOutput(j); AudioNode* connectedNode = connectedOutput->node(); if (visitedNodes.contains(connectedNode)) continue; visitedNodes.add(connectedNode); notifyAudioSourcesConnectedToNode(connectedNode, visitedNodes); } } } }
static void loopAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(info.Holder()); bool v = value->BooleanValue(); imp->setLoop(v); return; }
void PannerNode::notifyAudioSourcesConnectedToNode(ContextRenderLock& r, AudioNode* node) { ASSERT(node); if (!node) return; // First check if this node is an AudioBufferSourceNode. If so, let it know about us so that doppler shift pitch can be taken into account. if (node->nodeType() == NodeTypeAudioBufferSource) { AudioBufferSourceNode* bufferSourceNode = reinterpret_cast<AudioBufferSourceNode*>(node); bufferSourceNode->setPannerNode(this); } else { // Go through all inputs to this node. for (unsigned i = 0; i < node->numberOfInputs(); ++i) { auto input = node->input(i); // For each input, go through all of its connections, looking for AudioBufferSourceNodes. for (unsigned j = 0; j < input->numberOfRenderingConnections(r); ++j) { auto connectedOutput = input->renderingOutput(r, j); AudioNode* connectedNode = connectedOutput->node(); notifyAudioSourcesConnectedToNode(r, connectedNode); // recurse } } } }
static void loopEndAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(info.Holder()); double v = static_cast<double>(value->NumberValue()); imp->setLoopEnd(v); return; }
void PannerNode::FindConnectedSources(AudioNode* aNode, nsTArray<AudioBufferSourceNode*>& aSources, std::set<AudioNode*>& aNodesSeen) { if (!aNode) { return; } const nsTArray<InputNode>& inputNodes = aNode->InputNodes(); for(unsigned i = 0; i < inputNodes.Length(); i++) { // Return if we find a node that we have seen already. if (aNodesSeen.find(inputNodes[i].mInputNode) != aNodesSeen.end()) { return; } aNodesSeen.insert(inputNodes[i].mInputNode); // Recurse FindConnectedSources(inputNodes[i].mInputNode, aSources, aNodesSeen); // Check if this node is an AudioBufferSourceNode that still have a stream, // which means it has not finished playing. AudioBufferSourceNode* node = inputNodes[i].mInputNode->AsAudioBufferSourceNode(); if (node && node->GetStream()) { aSources.AppendElement(node); } } }
JSValue jsAudioBufferSourceNodePlaybackRate(ExecState* exec, JSValue slotBase, const Identifier&) { JSAudioBufferSourceNode* castedThis = static_cast<JSAudioBufferSourceNode*>(asObject(slotBase)); UNUSED_PARAM(exec); AudioBufferSourceNode* imp = static_cast<AudioBufferSourceNode*>(castedThis->impl()); JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->playbackRate())); return result; }
JSValue jsAudioBufferSourceNodeLooping(ExecState* exec, JSValue slotBase, const Identifier&) { JSAudioBufferSourceNode* castedThis = static_cast<JSAudioBufferSourceNode*>(asObject(slotBase)); UNUSED_PARAM(exec); AudioBufferSourceNode* imp = static_cast<AudioBufferSourceNode*>(castedThis->impl()); JSValue result = jsBoolean(imp->looping()); return result; }
static v8::Handle<v8::Value> noteOffCallback(const v8::Arguments& args) { if (args.Length() < 1) return throwNotEnoughArgumentsError(args.GetIsolate()); AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(args.Holder()); V8TRYCATCH(double, when, static_cast<double>(MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined)->NumberValue())); imp->noteOff(when); return v8Undefined(); }
static v8::Handle<v8::Value> noteOffCallback(const v8::Arguments& args) { INC_STATS("DOM.AudioBufferSourceNode.noteOff"); if (args.Length() < 1) return throwError("Not enough arguments", V8Proxy::TypeError); AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(args.Holder()); EXCEPTION_BLOCK(float, when, static_cast<float>(MAYBE_MISSING_PARAMETER(args, 0, MissingIsUndefined)->NumberValue())); imp->noteOff(when); return v8::Handle<v8::Value>(); }
static v8::Handle<v8::Value> noteOnCallback(const v8::Arguments& args) { FeatureObserver::observe(activeDOMWindow(BindingState::instance()), FeatureObserver::LegacyWebAudio); if (args.Length() < 1) return throwNotEnoughArgumentsError(args.GetIsolate()); AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(args.Holder()); V8TRYCATCH(double, when, static_cast<double>(MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined)->NumberValue())); imp->noteOn(when); return v8Undefined(); }
static v8::Handle<v8::Value> playbackRateAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(info.Holder()); RefPtr<AudioParam> result = imp->playbackRate(); v8::Handle<v8::Value> wrapper = result.get() ? v8::Handle<v8::Value>(DOMDataStore::getWrapper(result.get(), info.GetIsolate())) : v8Undefined(); if (wrapper.IsEmpty()) { wrapper = toV8(result.get(), info.Holder(), info.GetIsolate()); if (!wrapper.IsEmpty()) V8DOMWrapper::setNamedHiddenReference(info.Holder(), "playbackRate", wrapper); } return wrapper; }
void AbstractAudioContext::handleStoppableSourceNodes() { ASSERT(isGraphOwner()); // Find AudioBufferSourceNodes to see if we can stop playing them. for (AudioNode* node : m_activeSourceNodes) { if (node->handler().nodeType() == AudioHandler::NodeTypeAudioBufferSource) { AudioBufferSourceNode* sourceNode = static_cast<AudioBufferSourceNode*>(node); sourceNode->audioBufferSourceHandler().handleStoppableSourceNode(); } } }
void JSAudioBufferSourceNode::setBuffer(ExecState* exec, JSValue value) { AudioBufferSourceNode* imp = static_cast<AudioBufferSourceNode*>(impl()); AudioBuffer* buffer = toAudioBuffer(value); if (!buffer) { throwError(exec, createSyntaxError(exec, "Value is not of type AudioBuffer")); return; } if (!imp->setBuffer(buffer)) throwError(exec, createSyntaxError(exec, "AudioBuffer unsupported number of channels")); }
static v8::Handle<v8::Value> playbackRateAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.AudioBufferSourceNode.playbackRate._get"); AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(info.Holder()); RefPtr<AudioParam> result = imp->playbackRate(); v8::Handle<v8::Value> wrapper = result.get() ? getDOMObjectMap().get(result.get()) : v8::Handle<v8::Value>(); if (wrapper.IsEmpty()) { wrapper = toV8(result.get()); if (!wrapper.IsEmpty()) V8DOMWrapper::setNamedHiddenReference(info.Holder(), "playbackRate", wrapper); } return wrapper; }
void AudioContext::handleStoppableSourceNodes() { ASSERT(isGraphOwner()); // Find AudioBufferSourceNodes to see if we can stop playing them. for (unsigned i = 0; i < m_referencedNodes.size(); ++i) { AudioNode* node = m_referencedNodes.at(i).get(); if (node->handler().nodeType() == AudioHandler::NodeTypeAudioBufferSource) { AudioBufferSourceNode* sourceNode = static_cast<AudioBufferSourceNode*>(node); sourceNode->audioBufferSourceHandler().handleStoppableSourceNode(); } } }
EncodedJSValue JSC_HOST_CALL jsAudioBufferSourceNodePrototypeFunctionNoteOff(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSAudioBufferSourceNode::s_info)) return throwVMTypeError(exec); JSAudioBufferSourceNode* castedThis = static_cast<JSAudioBufferSourceNode*>(asObject(thisValue)); ASSERT_GC_OBJECT_INHERITS(castedThis, &JSAudioBufferSourceNode::s_info); AudioBufferSourceNode* imp = static_cast<AudioBufferSourceNode*>(castedThis->impl()); if (exec->argumentCount() < 1) return throwVMError(exec, createTypeError(exec, "Not enough arguments")); float when(exec->argument(0).toFloat(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); imp->noteOff(when); return JSValue::encode(jsUndefined()); }
void V8AudioBufferSourceNode::bufferAttrSetterCustom(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { v8::Handle<v8::Object> holder = info.Holder(); AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(holder); AudioBuffer* buffer = 0; if (V8AudioBuffer::HasInstance(value, info.GetIsolate(), worldType(info.GetIsolate()))) { buffer = V8AudioBuffer::toNative(value->ToObject()); if (buffer && !imp->setBuffer(buffer)) { throwTypeError("AudioBuffer unsupported number of channels", info.GetIsolate()); return; } } if (!buffer) { throwTypeError("Value is not of type AudioBuffer", info.GetIsolate()); return; } }
void V8AudioBufferSourceNode::bufferAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.AudioBufferSourceNode.buffer._set"); v8::Handle<v8::Object> holder = info.Holder(); AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(holder); AudioBuffer* buffer = 0; if (V8AudioBuffer::HasInstance(value)) { buffer = V8AudioBuffer::toNative(value->ToObject()); if (buffer && !imp->setBuffer(buffer)) { throwError("AudioBuffer unsupported number of channels"); return; } } if (!buffer) { throwError("Value is not of type AudioBuffer"); return; } }
static v8::Handle<v8::Value> loopEndAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(info.Holder()); return v8::Number::New(imp->loopEnd()); }
static v8::Handle<v8::Value> bufferAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(info.Holder()); return toV8Fast(imp->buffer(), info, imp); }
static v8::Handle<v8::Value> playbackStateAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(info.Holder()); return v8Integer(imp->playbackState(), info.GetIsolate()); }
void setJSAudioBufferSourceNodeLooping(ExecState* exec, JSObject* thisObject, JSValue value) { JSAudioBufferSourceNode* castedThis = static_cast<JSAudioBufferSourceNode*>(thisObject); AudioBufferSourceNode* imp = static_cast<AudioBufferSourceNode*>(castedThis->impl()); imp->setLooping(value.toBoolean(exec)); }
static v8::Handle<v8::Value> loopAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(info.Holder()); return v8Boolean(imp->loop(), info.GetIsolate()); }
void JSAudioBufferSourceNode::setBuffer(ExecState*, JSValue value) { AudioBufferSourceNode* imp = static_cast<AudioBufferSourceNode*>(impl()); imp->setBuffer(toAudioBuffer(value)); }
static v8::Handle<v8::Value> loopAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.AudioBufferSourceNode.loop._get"); AudioBufferSourceNode* imp = V8AudioBufferSourceNode::toNative(info.Holder()); return v8Boolean(imp->loop()); }