| 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 // Constructor for rendering to the audio hardware. | 99 // Constructor for rendering to the audio hardware. |
| 100 AudioContext::AudioContext(Document* document) | 100 AudioContext::AudioContext(Document* document) |
| 101 : ActiveDOMObject(document) | 101 : ActiveDOMObject(document) |
| 102 , m_isStopScheduled(false) | 102 , m_isStopScheduled(false) |
| 103 , m_isCleared(false) | 103 , m_isCleared(false) |
| 104 , m_isInitialized(false) | 104 , m_isInitialized(false) |
| 105 , m_destinationNode(nullptr) | 105 , m_destinationNode(nullptr) |
| 106 , m_isResolvingResumePromises(false) | 106 , m_isResolvingResumePromises(false) |
| 107 , m_automaticPullNodesNeedUpdating(false) | 107 , m_automaticPullNodesNeedUpdating(false) |
| 108 , m_connectionCount(0) | 108 , m_connectionCount(0) |
| 109 , m_didInitializeContextGraphMutex(false) |
| 109 , m_audioThread(0) | 110 , m_audioThread(0) |
| 110 , m_isOfflineContext(false) | 111 , m_isOfflineContext(false) |
| 111 , m_contextState(Suspended) | 112 , m_contextState(Suspended) |
| 112 { | 113 { |
| 113 m_referencedNodes = new HeapVector<Member<AudioNode>>(); | 114 m_didInitializeContextGraphMutex = true; |
| 114 m_destinationNode = DefaultAudioDestinationNode::create(this); | 115 m_destinationNode = DefaultAudioDestinationNode::create(this); |
| 115 | 116 |
| 116 initialize(); | 117 initialize(); |
| 117 #if DEBUG_AUDIONODE_REFERENCES | 118 #if DEBUG_AUDIONODE_REFERENCES |
| 118 fprintf(stderr, "%p: AudioContext::AudioContext() #%u\n", this, AudioContext
::s_hardwareContextCount); | 119 fprintf(stderr, "%p: AudioContext::AudioContext() #%u\n", this, AudioContext
::s_hardwareContextCount); |
| 119 #endif | 120 #endif |
| 120 } | 121 } |
| 121 | 122 |
| 122 // Constructor for offline (non-realtime) rendering. | 123 // Constructor for offline (non-realtime) rendering. |
| 123 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
numberOfFrames, float sampleRate) | 124 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
numberOfFrames, float sampleRate) |
| 124 : ActiveDOMObject(document) | 125 : ActiveDOMObject(document) |
| 125 , m_isStopScheduled(false) | 126 , m_isStopScheduled(false) |
| 126 , m_isCleared(false) | 127 , m_isCleared(false) |
| 127 , m_isInitialized(false) | 128 , m_isInitialized(false) |
| 128 , m_destinationNode(nullptr) | 129 , m_destinationNode(nullptr) |
| 129 , m_isResolvingResumePromises(false) | 130 , m_isResolvingResumePromises(false) |
| 130 , m_automaticPullNodesNeedUpdating(false) | 131 , m_automaticPullNodesNeedUpdating(false) |
| 131 , m_connectionCount(0) | 132 , m_connectionCount(0) |
| 133 , m_didInitializeContextGraphMutex(false) |
| 132 , m_audioThread(0) | 134 , m_audioThread(0) |
| 133 , m_isOfflineContext(true) | 135 , m_isOfflineContext(true) |
| 134 , m_contextState(Suspended) | 136 , m_contextState(Suspended) |
| 135 { | 137 { |
| 136 m_referencedNodes = new HeapVector<Member<AudioNode>>(); | 138 m_didInitializeContextGraphMutex = true; |
| 137 // Create a new destination for offline rendering. | 139 // Create a new destination for offline rendering. |
| 138 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl
eRate); | 140 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl
eRate); |
| 139 if (m_renderTarget.get()) | 141 if (m_renderTarget.get()) |
| 140 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa
rget.get()); | 142 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa
rget.get()); |
| 141 | 143 |
| 142 initialize(); | 144 initialize(); |
| 143 } | 145 } |
| 144 | 146 |
| 145 AudioContext::~AudioContext() | 147 AudioContext::~AudioContext() |
| 146 { | 148 { |
| 147 #if DEBUG_AUDIONODE_REFERENCES | 149 #if DEBUG_AUDIONODE_REFERENCES |
| 148 fprintf(stderr, "%p: AudioContext::~AudioContext()\n", this); | 150 fprintf(stderr, "%p: AudioContext::~AudioContext()\n", this); |
| 149 #endif | 151 #endif |
| 150 // AudioNodes keep a reference to their context, so there should be no way t
o be in the destructor if there are still AudioNodes around. | 152 // AudioNodes keep a reference to their context, so there should be no way t
o be in the destructor if there are still AudioNodes around. |
| 151 ASSERT(!m_isInitialized); | 153 ASSERT(!m_isInitialized); |
| 154 ASSERT(!m_referencedNodes.size()); |
| 152 ASSERT(!m_finishedNodes.size()); | 155 ASSERT(!m_finishedNodes.size()); |
| 153 ASSERT(!m_automaticPullNodes.size()); | 156 ASSERT(!m_automaticPullNodes.size()); |
| 154 if (m_automaticPullNodesNeedUpdating) | 157 if (m_automaticPullNodesNeedUpdating) |
| 155 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); | 158 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); |
| 156 ASSERT(!m_renderingAutomaticPullNodes.size()); | 159 ASSERT(!m_renderingAutomaticPullNodes.size()); |
| 157 ASSERT(!m_suspendResolvers.size()); | 160 ASSERT(!m_suspendResolvers.size()); |
| 158 ASSERT(!m_resumeResolvers.size()); | 161 ASSERT(!m_resumeResolvers.size()); |
| 159 } | 162 } |
| 160 | 163 |
| 161 void AudioContext::initialize() | 164 void AudioContext::initialize() |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 derefNode(m_finishedNodes[i]); | 674 derefNode(m_finishedNodes[i]); |
| 672 | 675 |
| 673 m_finishedNodes.clear(); | 676 m_finishedNodes.clear(); |
| 674 } | 677 } |
| 675 | 678 |
| 676 void AudioContext::refNode(AudioNode* node) | 679 void AudioContext::refNode(AudioNode* node) |
| 677 { | 680 { |
| 678 ASSERT(isMainThread()); | 681 ASSERT(isMainThread()); |
| 679 AutoLocker locker(this); | 682 AutoLocker locker(this); |
| 680 | 683 |
| 681 m_referencedNodes->append(node); | 684 m_referencedNodes.append(node); |
| 682 node->makeConnection(); | 685 node->makeConnection(); |
| 683 } | 686 } |
| 684 | 687 |
| 685 void AudioContext::derefNode(AudioNode* node) | 688 void AudioContext::derefNode(AudioNode* node) |
| 686 { | 689 { |
| 687 ASSERT(isGraphOwner()); | 690 ASSERT(isGraphOwner()); |
| 688 | 691 |
| 689 for (unsigned i = 0; i < m_referencedNodes->size(); ++i) { | 692 for (unsigned i = 0; i < m_referencedNodes.size(); ++i) { |
| 690 if (node == m_referencedNodes->at(i).get()) { | 693 if (node == m_referencedNodes.at(i).get()) { |
| 691 node->breakConnection(); | 694 node->breakConnection(); |
| 692 m_referencedNodes->remove(i); | 695 m_referencedNodes.remove(i); |
| 693 break; | 696 break; |
| 694 } | 697 } |
| 695 } | 698 } |
| 696 } | 699 } |
| 697 | 700 |
| 698 void AudioContext::derefUnfinishedSourceNodes() | 701 void AudioContext::derefUnfinishedSourceNodes() |
| 699 { | 702 { |
| 700 ASSERT(isMainThread()); | 703 ASSERT(isMainThread()); |
| 701 for (unsigned i = 0; i < m_referencedNodes->size(); ++i) | 704 for (unsigned i = 0; i < m_referencedNodes.size(); ++i) |
| 702 m_referencedNodes->at(i)->breakConnection(); | 705 m_referencedNodes.at(i)->breakConnection(); |
| 703 | 706 |
| 704 m_referencedNodes->clear(); | 707 m_referencedNodes.clear(); |
| 705 } | 708 } |
| 706 | 709 |
| 707 void AudioContext::lock() | 710 void AudioContext::lock() |
| 708 { | 711 { |
| 709 // Don't allow regular lock in real-time audio thread. | 712 // Don't allow regular lock in real-time audio thread. |
| 710 ASSERT(isMainThread()); | 713 ASSERT(isMainThread()); |
| 711 m_contextGraphMutex.lock(); | 714 m_contextGraphMutex.lock(); |
| 712 } | 715 } |
| 713 | 716 |
| 714 bool AudioContext::tryLock() | 717 bool AudioContext::tryLock() |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 dispatchEvent(OfflineAudioCompletionEvent::create(renderedBuffer)); | 1074 dispatchEvent(OfflineAudioCompletionEvent::create(renderedBuffer)); |
| 1072 } | 1075 } |
| 1073 } | 1076 } |
| 1074 | 1077 |
| 1075 void AudioContext::trace(Visitor* visitor) | 1078 void AudioContext::trace(Visitor* visitor) |
| 1076 { | 1079 { |
| 1077 visitor->trace(m_renderTarget); | 1080 visitor->trace(m_renderTarget); |
| 1078 visitor->trace(m_destinationNode); | 1081 visitor->trace(m_destinationNode); |
| 1079 visitor->trace(m_listener); | 1082 visitor->trace(m_listener); |
| 1080 // trace() can be called in AudioContext constructor, and | 1083 // trace() can be called in AudioContext constructor, and |
| 1081 // m_contextGraphMutex might be unavailable. We can use m_contextGraphMutex | 1084 // m_contextGraphMutex might be unavailable. |
| 1082 // if m_referencedNodes is not null because m_referencedNodes is initialized | 1085 if (m_didInitializeContextGraphMutex) { |
| 1083 // after m_contextGraphMutex. | |
| 1084 if (m_referencedNodes) { | |
| 1085 AutoLocker lock(this); | 1086 AutoLocker lock(this); |
| 1086 visitor->trace(m_referencedNodes); | 1087 visitor->trace(m_referencedNodes); |
| 1088 } else { |
| 1089 visitor->trace(m_referencedNodes); |
| 1087 } | 1090 } |
| 1088 visitor->trace(m_liveNodes); | 1091 visitor->trace(m_liveNodes); |
| 1089 visitor->trace(m_liveAudioSummingJunctions); | 1092 visitor->trace(m_liveAudioSummingJunctions); |
| 1090 EventTargetWithInlineData::trace(visitor); | 1093 EventTargetWithInlineData::trace(visitor); |
| 1091 } | 1094 } |
| 1092 | 1095 |
| 1093 void AudioContext::addChangedChannelCountMode(AudioNode* node) | 1096 void AudioContext::addChangedChannelCountMode(AudioNode* node) |
| 1094 { | 1097 { |
| 1095 ASSERT(isGraphOwner()); | 1098 ASSERT(isGraphOwner()); |
| 1096 ASSERT(isMainThread()); | 1099 ASSERT(isMainThread()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1110 | 1113 |
| 1111 for (HashSet<AudioNode*>::iterator k = m_deferredCountModeChange.begin(); k
!= m_deferredCountModeChange.end(); ++k) | 1114 for (HashSet<AudioNode*>::iterator k = m_deferredCountModeChange.begin(); k
!= m_deferredCountModeChange.end(); ++k) |
| 1112 (*k)->updateChannelCountMode(); | 1115 (*k)->updateChannelCountMode(); |
| 1113 | 1116 |
| 1114 m_deferredCountModeChange.clear(); | 1117 m_deferredCountModeChange.clear(); |
| 1115 } | 1118 } |
| 1116 | 1119 |
| 1117 } // namespace blink | 1120 } // namespace blink |
| 1118 | 1121 |
| 1119 #endif // ENABLE(WEB_AUDIO) | 1122 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |