| 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 | 
|---|