| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010, Google Inc. All rights reserved. | 2 * Copyright (C) 2010, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 , m_orientation(1, 0, 0) | 55 , m_orientation(1, 0, 0) |
| 56 , m_velocity(0, 0, 0) | 56 , m_velocity(0, 0, 0) |
| 57 , m_isAzimuthElevationDirty(true) | 57 , m_isAzimuthElevationDirty(true) |
| 58 , m_isDistanceConeGainDirty(true) | 58 , m_isDistanceConeGainDirty(true) |
| 59 , m_isDopplerRateDirty(true) | 59 , m_isDopplerRateDirty(true) |
| 60 , m_lastGain(-1.0) | 60 , m_lastGain(-1.0) |
| 61 , m_cachedAzimuth(0) | 61 , m_cachedAzimuth(0) |
| 62 , m_cachedElevation(0) | 62 , m_cachedElevation(0) |
| 63 , m_cachedDistanceConeGain(1.0f) | 63 , m_cachedDistanceConeGain(1.0f) |
| 64 , m_cachedDopplerRate(1) | 64 , m_cachedDopplerRate(1) |
| 65 , m_connectionCount(0) | |
| 66 { | 65 { |
| 67 // Load the HRTF database asynchronously so we don't block the Javascript th
read while creating the HRTF database. | 66 // Load the HRTF database asynchronously so we don't block the Javascript th
read while creating the HRTF database. |
| 68 // The HRTF panner will return zeroes until the database is loaded. | 67 // The HRTF panner will return zeroes until the database is loaded. |
| 69 listener()->createAndLoadHRTFDatabaseLoader(context->sampleRate()); | 68 listener()->createAndLoadHRTFDatabaseLoader(context->sampleRate()); |
| 70 | 69 |
| 71 addInput(); | 70 addInput(); |
| 72 addOutput(AudioNodeOutput::create(this, 2)); | 71 addOutput(AudioNodeOutput::create(this, 2)); |
| 73 | 72 |
| 74 // Node-specific default mixing rules. | 73 // Node-specific default mixing rules. |
| 75 m_channelCount = 2; | 74 m_channelCount = 2; |
| 76 m_channelCountMode = ClampedMax; | 75 m_channelCountMode = ClampedMax; |
| 77 m_channelInterpretation = AudioBus::Speakers; | 76 m_channelInterpretation = AudioBus::Speakers; |
| 78 | 77 |
| 79 setNodeType(NodeTypePanner); | 78 setNodeType(NodeTypePanner); |
| 80 | 79 |
| 81 initialize(); | 80 initialize(); |
| 82 } | 81 } |
| 83 | 82 |
| 84 PannerNode::~PannerNode() | 83 PannerNode::~PannerNode() |
| 85 { | 84 { |
| 86 ASSERT(!isInitialized()); | 85 ASSERT(!isInitialized()); |
| 87 } | 86 } |
| 88 | 87 |
| 89 void PannerNode::dispose() | 88 void PannerNode::dispose() |
| 90 { | 89 { |
| 91 uninitialize(); | 90 uninitialize(); |
| 92 AudioNode::dispose(); | 91 AudioNode::dispose(); |
| 93 } | 92 } |
| 94 | 93 |
| 95 void PannerNode::pullInputs(size_t framesToProcess) | |
| 96 { | |
| 97 // We override pullInputs(), so we can detect new AudioSourceNodes which hav
e connected to us when new connections are made. | |
| 98 // These AudioSourceNodes need to be made aware of our existence in order to
handle doppler shift pitch changes. | |
| 99 if (m_connectionCount != context()->connectionCount()) { | |
| 100 m_connectionCount = context()->connectionCount(); | |
| 101 | |
| 102 // A map for keeping track if we have visited a node or not. This preven
ts feedback loops | |
| 103 // from recursing infinitely. See crbug.com/331446. | |
| 104 HashMap<AudioNode*, bool> visitedNodes; | |
| 105 | |
| 106 // Recursively go through all nodes connected to us | |
| 107 notifyAudioSourcesConnectedToNode(this, visitedNodes); | |
| 108 } | |
| 109 | |
| 110 AudioNode::pullInputs(framesToProcess); | |
| 111 } | |
| 112 | |
| 113 void PannerNode::process(size_t framesToProcess) | 94 void PannerNode::process(size_t framesToProcess) |
| 114 { | 95 { |
| 115 AudioBus* destination = output(0)->bus(); | 96 AudioBus* destination = output(0)->bus(); |
| 116 | 97 |
| 117 if (!isInitialized() || !input(0)->isConnected() || !m_panner.get()) { | 98 if (!isInitialized() || !input(0)->isConnected() || !m_panner.get()) { |
| 118 destination->zero(); | 99 destination->zero(); |
| 119 return; | 100 return; |
| 120 } | 101 } |
| 121 | 102 |
| 122 AudioBus* source = input(0)->bus(); | 103 AudioBus* source = input(0)->bus(); |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 if (dirty & PannerNode::AzimuthElevationDirty) | 524 if (dirty & PannerNode::AzimuthElevationDirty) |
| 544 m_isAzimuthElevationDirty = true; | 525 m_isAzimuthElevationDirty = true; |
| 545 | 526 |
| 546 if (dirty & PannerNode::DistanceConeGainDirty) | 527 if (dirty & PannerNode::DistanceConeGainDirty) |
| 547 m_isDistanceConeGainDirty = true; | 528 m_isDistanceConeGainDirty = true; |
| 548 | 529 |
| 549 if (dirty & PannerNode::DopplerRateDirty) | 530 if (dirty & PannerNode::DopplerRateDirty) |
| 550 m_isDopplerRateDirty = true; | 531 m_isDopplerRateDirty = true; |
| 551 } | 532 } |
| 552 | 533 |
| 553 void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node, HashMap<Audi
oNode*, bool>& visitedNodes) | |
| 554 { | |
| 555 ASSERT(node); | |
| 556 if (!node) | |
| 557 return; | |
| 558 | |
| 559 // 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. | |
| 560 if (node->nodeType() == NodeTypeAudioBufferSource) { | |
| 561 AudioBufferSourceNode* bufferSourceNode = static_cast<AudioBufferSourceN
ode*>(node); | |
| 562 bufferSourceNode->setPannerNode(this); | |
| 563 } else { | |
| 564 // Go through all inputs to this node. | |
| 565 for (unsigned i = 0; i < node->numberOfInputs(); ++i) { | |
| 566 AudioNodeInput* input = node->input(i); | |
| 567 | |
| 568 // For each input, go through all of its connections, looking for Au
dioBufferSourceNodes. | |
| 569 for (unsigned j = 0; j < input->numberOfRenderingConnections(); ++j)
{ | |
| 570 AudioNodeOutput* connectedOutput = input->renderingOutput(j); | |
| 571 AudioNode* connectedNode = connectedOutput->node(); | |
| 572 HashMap<AudioNode*, bool>::iterator iterator = visitedNodes.find
(connectedNode); | |
| 573 | |
| 574 // If we've seen this node already, we don't need to process it
again. Otherwise, | |
| 575 // mark it as visited and recurse through the node looking for s
ources. | |
| 576 if (iterator == visitedNodes.end()) { | |
| 577 visitedNodes.set(connectedNode, true); | |
| 578 notifyAudioSourcesConnectedToNode(connectedNode, visitedNode
s); // recurse | |
| 579 } | |
| 580 } | |
| 581 } | |
| 582 } | |
| 583 } | |
| 584 | |
| 585 void PannerNode::setChannelCount(unsigned long channelCount, ExceptionState& exc
eptionState) | 534 void PannerNode::setChannelCount(unsigned long channelCount, ExceptionState& exc
eptionState) |
| 586 { | 535 { |
| 587 ASSERT(isMainThread()); | 536 ASSERT(isMainThread()); |
| 588 AudioContext::AutoLocker locker(context()); | 537 AudioContext::AutoLocker locker(context()); |
| 589 | 538 |
| 590 // A PannerNode only supports 1 or 2 channels | 539 // A PannerNode only supports 1 or 2 channels |
| 591 if (channelCount > 0 && channelCount <= 2) { | 540 if (channelCount > 0 && channelCount <= 2) { |
| 592 if (m_channelCount != channelCount) { | 541 if (m_channelCount != channelCount) { |
| 593 m_channelCount = channelCount; | 542 m_channelCount = channelCount; |
| 594 if (m_channelCountMode != Max) | 543 if (m_channelCountMode != Max) |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 | 587 |
| 639 void PannerNode::trace(Visitor* visitor) | 588 void PannerNode::trace(Visitor* visitor) |
| 640 { | 589 { |
| 641 visitor->trace(m_panner); | 590 visitor->trace(m_panner); |
| 642 AudioNode::trace(visitor); | 591 AudioNode::trace(visitor); |
| 643 } | 592 } |
| 644 | 593 |
| 645 } // namespace blink | 594 } // namespace blink |
| 646 | 595 |
| 647 #endif // ENABLE(WEB_AUDIO) | 596 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |