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 |