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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 // Don't allow more than this number of simultaneous AudioContexts talking to ha
rdware. | 86 // Don't allow more than this number of simultaneous AudioContexts talking to ha
rdware. |
87 const unsigned MaxHardwareContexts = 4; | 87 const unsigned MaxHardwareContexts = 4; |
88 unsigned AudioContext::s_hardwareContextCount = 0; | 88 unsigned AudioContext::s_hardwareContextCount = 0; |
89 | 89 |
90 PassRefPtr<AudioContext> AudioContext::create(Document* document) | 90 PassRefPtr<AudioContext> AudioContext::create(Document* document) |
91 { | 91 { |
92 ASSERT(document); | 92 ASSERT(document); |
93 ASSERT(isMainThread()); | 93 ASSERT(isMainThread()); |
94 if (s_hardwareContextCount >= MaxHardwareContexts) | 94 if (s_hardwareContextCount >= MaxHardwareContexts) |
95 return 0; | 95 return 0; |
96 | |
97 ++s_hardwareContextCount; | |
98 | 96 |
99 return adoptRef(new AudioContext(document)); | 97 return adoptRef(new AudioContext(document)); |
100 } | 98 } |
101 | 99 |
102 PassRefPtr<AudioContext> AudioContext::createOfflineContext(Document* document,
unsigned numberOfChannels, size_t numberOfFrames, double sampleRate, ExceptionCo
de& ec) | 100 PassRefPtr<AudioContext> AudioContext::createOfflineContext(Document* document,
unsigned numberOfChannels, size_t numberOfFrames, double sampleRate, ExceptionCo
de& ec) |
103 { | 101 { |
104 ASSERT(document); | 102 ASSERT(document); |
105 | 103 |
106 // FIXME: offline contexts have limitations on supported sample-rates. | 104 // FIXME: offline contexts have limitations on supported sample-rates. |
107 // Currently all AudioContexts must have the same sample-rate. | 105 // Currently all AudioContexts must have the same sample-rate. |
(...skipping 20 matching lines...) Expand all Loading... |
128 { | 126 { |
129 constructCommon(); | 127 constructCommon(); |
130 | 128 |
131 m_destinationNode = DefaultAudioDestinationNode::create(this); | 129 m_destinationNode = DefaultAudioDestinationNode::create(this); |
132 | 130 |
133 // This sets in motion an asynchronous loading mechanism on another thread. | 131 // This sets in motion an asynchronous loading mechanism on another thread. |
134 // We can check m_hrtfDatabaseLoader->isLoaded() to find out whether or not
it has been fully loaded. | 132 // We can check m_hrtfDatabaseLoader->isLoaded() to find out whether or not
it has been fully loaded. |
135 // It's not that useful to have a callback function for this since the audio
thread automatically starts rendering on the graph | 133 // It's not that useful to have a callback function for this since the audio
thread automatically starts rendering on the graph |
136 // when this has finished (see AudioDestinationNode). | 134 // when this has finished (see AudioDestinationNode). |
137 m_hrtfDatabaseLoader = HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNece
ssary(sampleRate()); | 135 m_hrtfDatabaseLoader = HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNece
ssary(sampleRate()); |
138 | |
139 // FIXME: for now default AudioContext does not need an explicit startRender
ing() call. | |
140 // We may want to consider requiring it for symmetry with OfflineAudioContex
t | |
141 m_destinationNode->startRendering(); | |
142 } | 136 } |
143 | 137 |
144 // Constructor for offline (non-realtime) rendering. | 138 // Constructor for offline (non-realtime) rendering. |
145 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
numberOfFrames, double sampleRate) | 139 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
numberOfFrames, double sampleRate) |
146 : ActiveDOMObject(document, this) | 140 : ActiveDOMObject(document, this) |
147 , m_isInitialized(false) | 141 , m_isInitialized(false) |
148 , m_isAudioThreadFinished(false) | 142 , m_isAudioThreadFinished(false) |
149 , m_document(document) | 143 , m_document(document) |
150 , m_destinationNode(0) | 144 , m_destinationNode(0) |
151 , m_connectionCount(0) | 145 , m_connectionCount(0) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 ASSERT(!m_finishedNodes.size()); | 181 ASSERT(!m_finishedNodes.size()); |
188 } | 182 } |
189 | 183 |
190 void AudioContext::lazyInitialize() | 184 void AudioContext::lazyInitialize() |
191 { | 185 { |
192 if (!m_isInitialized) { | 186 if (!m_isInitialized) { |
193 // Don't allow the context to initialize a second time after it's alread
y been explicitly uninitialized. | 187 // Don't allow the context to initialize a second time after it's alread
y been explicitly uninitialized. |
194 ASSERT(!m_isAudioThreadFinished); | 188 ASSERT(!m_isAudioThreadFinished); |
195 if (!m_isAudioThreadFinished) { | 189 if (!m_isAudioThreadFinished) { |
196 if (m_destinationNode.get()) { | 190 if (m_destinationNode.get()) { |
197 // This starts the audio thread. The destination node's provide
Input() method will now be called repeatedly to render audio. | |
198 // Each time provideInput() is called, a portion of the audio st
ream is rendered. Let's call this time period a "render quantum". | |
199 m_destinationNode->initialize(); | 191 m_destinationNode->initialize(); |
| 192 |
| 193 if (!isOfflineContext()) { |
| 194 // This starts the audio thread. The destination node's prov
ideInput() method will now be called repeatedly to render audio. |
| 195 // Each time provideInput() is called, a portion of the audi
o stream is rendered. Let's call this time period a "render quantum". |
| 196 // NOTE: for now default AudioContext does not need an expli
cit startRendering() call from JavaScript. |
| 197 // We may want to consider requiring it for symmetry with Of
flineAudioContext. |
| 198 m_destinationNode->startRendering(); |
| 199 ++s_hardwareContextCount; |
| 200 } |
| 201 |
200 } | 202 } |
201 m_isInitialized = true; | 203 m_isInitialized = true; |
202 } | 204 } |
203 } | 205 } |
204 } | 206 } |
205 | 207 |
206 void AudioContext::uninitialize() | 208 void AudioContext::uninitialize() |
207 { | 209 { |
208 ASSERT(isMainThread()); | 210 ASSERT(isMainThread()); |
209 | 211 |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 // Avoid firing the event if the document has already gone away. | 686 // Avoid firing the event if the document has already gone away. |
685 if (hasDocument()) { | 687 if (hasDocument()) { |
686 // Call the offline rendering completion event listener. | 688 // Call the offline rendering completion event listener. |
687 dispatchEvent(OfflineAudioCompletionEvent::create(renderedBuffer)); | 689 dispatchEvent(OfflineAudioCompletionEvent::create(renderedBuffer)); |
688 } | 690 } |
689 } | 691 } |
690 | 692 |
691 } // namespace WebCore | 693 } // namespace WebCore |
692 | 694 |
693 #endif // ENABLE(WEB_AUDIO) | 695 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |