Chromium Code Reviews| 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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 , m_isInitialized(false) | 112 , m_isInitialized(false) |
| 113 , m_isAudioThreadFinished(false) | 113 , m_isAudioThreadFinished(false) |
| 114 , m_destinationNode(nullptr) | 114 , m_destinationNode(nullptr) |
| 115 , m_isDeletionScheduled(false) | 115 , m_isDeletionScheduled(false) |
| 116 , m_automaticPullNodesNeedUpdating(false) | 116 , m_automaticPullNodesNeedUpdating(false) |
| 117 , m_connectionCount(0) | 117 , m_connectionCount(0) |
| 118 , m_audioThread(0) | 118 , m_audioThread(0) |
| 119 , m_graphOwnerThread(UndefinedThreadIdentifier) | 119 , m_graphOwnerThread(UndefinedThreadIdentifier) |
| 120 , m_isOfflineContext(false) | 120 , m_isOfflineContext(false) |
| 121 { | 121 { |
| 122 m_destinationNode = DefaultAudioDestinationNode::create(this); | |
| 123 | |
| 122 constructCommon(); | 124 constructCommon(); |
| 123 | |
| 124 m_destinationNode = DefaultAudioDestinationNode::create(this); | |
|
Raymond Toy
2014/05/27 17:49:45
Why are these two lines swapped?
KhNo
2014/05/28 14:39:51
It must be initialized after creating m_destinatio
| |
| 125 } | 125 } |
| 126 | 126 |
| 127 // Constructor for offline (non-realtime) rendering. | 127 // Constructor for offline (non-realtime) rendering. |
| 128 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate) | 128 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate) |
| 129 : ActiveDOMObject(document) | 129 : ActiveDOMObject(document) |
| 130 , m_isStopScheduled(false) | 130 , m_isStopScheduled(false) |
| 131 , m_isCleared(false) | 131 , m_isCleared(false) |
| 132 , m_isInitialized(false) | 132 , m_isInitialized(false) |
| 133 , m_isAudioThreadFinished(false) | 133 , m_isAudioThreadFinished(false) |
| 134 , m_destinationNode(nullptr) | 134 , m_destinationNode(nullptr) |
| 135 , m_automaticPullNodesNeedUpdating(false) | 135 , m_automaticPullNodesNeedUpdating(false) |
| 136 , m_connectionCount(0) | 136 , m_connectionCount(0) |
| 137 , m_audioThread(0) | 137 , m_audioThread(0) |
| 138 , m_graphOwnerThread(UndefinedThreadIdentifier) | 138 , m_graphOwnerThread(UndefinedThreadIdentifier) |
| 139 , m_isOfflineContext(true) | 139 , m_isOfflineContext(true) |
| 140 { | 140 { |
| 141 constructCommon(); | |
| 142 | |
| 143 // Create a new destination for offline rendering. | 141 // Create a new destination for offline rendering. |
| 144 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl eRate); | 142 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl eRate); |
| 145 if (m_renderTarget.get()) | 143 if (m_renderTarget.get()) |
| 146 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa rget.get()); | 144 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa rget.get()); |
| 145 | |
| 146 constructCommon(); | |
|
Raymond Toy
2014/05/27 17:49:45
Why is this moved from the beginning to the end?
KhNo
2014/05/28 14:39:51
It must be initialized after creating m_destinatio
| |
| 147 } | 147 } |
| 148 | 148 |
| 149 void AudioContext::constructCommon() | 149 void AudioContext::constructCommon() |
| 150 { | 150 { |
| 151 ScriptWrappable::init(this); | 151 ScriptWrappable::init(this); |
| 152 | 152 |
| 153 FFTFrame::initialize(); | 153 FFTFrame::initialize(); |
| 154 | 154 |
| 155 m_listener = AudioListener::create(); | 155 m_listener = AudioListener::create(); |
| 156 | |
| 157 initialize(); | |
| 156 } | 158 } |
| 157 | 159 |
| 158 AudioContext::~AudioContext() | 160 AudioContext::~AudioContext() |
| 159 { | 161 { |
| 160 #if DEBUG_AUDIONODE_REFERENCES | 162 #if DEBUG_AUDIONODE_REFERENCES |
| 161 fprintf(stderr, "%p: AudioContext::~AudioContext()\n", this); | 163 fprintf(stderr, "%p: AudioContext::~AudioContext()\n", this); |
| 162 #endif | 164 #endif |
| 163 // 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. | 165 // 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. |
| 164 ASSERT(!m_isInitialized); | 166 ASSERT(!m_isInitialized); |
| 165 ASSERT(!m_nodesToDelete.size()); | 167 ASSERT(!m_nodesToDelete.size()); |
| 166 ASSERT(!m_referencedNodes.size()); | 168 ASSERT(!m_referencedNodes.size()); |
| 167 ASSERT(!m_finishedNodes.size()); | 169 ASSERT(!m_finishedNodes.size()); |
| 168 ASSERT(!m_automaticPullNodes.size()); | 170 ASSERT(!m_automaticPullNodes.size()); |
| 169 if (m_automaticPullNodesNeedUpdating) | 171 if (m_automaticPullNodesNeedUpdating) |
| 170 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); | 172 m_renderingAutomaticPullNodes.resize(m_automaticPullNodes.size()); |
| 171 ASSERT(!m_renderingAutomaticPullNodes.size()); | 173 ASSERT(!m_renderingAutomaticPullNodes.size()); |
| 172 } | 174 } |
| 173 | 175 |
| 174 void AudioContext::lazyInitialize() | 176 void AudioContext::initialize() |
| 175 { | 177 { |
| 176 if (!m_isInitialized) { | 178 // Don't allow the context to initialize a second time after it's already be en explicitly uninitialized. |
| 177 // Don't allow the context to initialize a second time after it's alread y been explicitly uninitialized. | 179 if (isInitialized()) |
| 178 ASSERT(!m_isAudioThreadFinished); | 180 return; |
| 179 if (!m_isAudioThreadFinished) { | |
| 180 // Creation of a destination node should not start the audio HW. The | |
| 181 // creation of any other AudioNode will initialize the audio HW and start processing | |
| 182 if (m_destinationNode.get()) { | |
| 183 m_destinationNode->initialize(); | |
| 184 | 181 |
| 185 if (!isOfflineContext()) { | 182 if (m_destinationNode) { |
| 186 // This starts the audio thread. The destination node's prov ideInput() method will now be called repeatedly to render audio. | 183 if (!isOfflineContext()) |
| 187 // Each time provideInput() is called, a portion of the audi o stream is rendered. Let's call this time period a "render quantum". | 184 ++s_hardwareContextCount; |
| 188 // NOTE: for now default AudioContext does not need an expli cit startRendering() call from JavaScript. | |
| 189 // We may want to consider requiring it for symmetry with Of flineAudioContext. | |
| 190 m_destinationNode->startRendering(); | |
|
Raymond Toy
2014/05/27 17:49:45
Don't we still need to call startRendering()?
KhNo
2014/05/28 14:39:51
This is my big mistake. Sorry about it. It must be
| |
| 191 ++s_hardwareContextCount; | |
| 192 } | |
| 193 | 185 |
| 194 m_isInitialized = true; | 186 m_destinationNode->initialize(); |
| 195 } | 187 m_isInitialized = true; |
| 196 } | |
| 197 } | 188 } |
| 198 } | 189 } |
| 199 | 190 |
| 200 void AudioContext::clear() | 191 void AudioContext::clear() |
| 201 { | 192 { |
| 202 // We have to release our reference to the destination node before the conte xt will ever be deleted since the destination node holds a reference to the cont ext. | 193 // We have to release our reference to the destination node before the conte xt will ever be deleted since the destination node holds a reference to the cont ext. |
| 203 if (m_destinationNode) | 194 if (m_destinationNode) |
| 204 m_destinationNode.clear(); | 195 m_destinationNode.clear(); |
| 205 | 196 |
| 206 // Audio thread is dead. Nobody will schedule node deletion action. Let's do it ourselves. | 197 // Audio thread is dead. Nobody will schedule node deletion action. Let's do it ourselves. |
| (...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 971 { | 962 { |
| 972 visitor->trace(m_renderTarget); | 963 visitor->trace(m_renderTarget); |
| 973 visitor->trace(m_destinationNode); | 964 visitor->trace(m_destinationNode); |
| 974 visitor->trace(m_listener); | 965 visitor->trace(m_listener); |
| 975 visitor->trace(m_dirtySummingJunctions); | 966 visitor->trace(m_dirtySummingJunctions); |
| 976 } | 967 } |
| 977 | 968 |
| 978 } // namespace WebCore | 969 } // namespace WebCore |
| 979 | 970 |
| 980 #endif // ENABLE(WEB_AUDIO) | 971 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |