Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/AudioContext.cpp

Issue 2060833002: Implementation of 'AudioContext.getOutputTimestamp' method (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added implementation for ALSA. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/webaudio/AudioContext.h" 5 #include "modules/webaudio/AudioContext.h"
6 6
7 #include "bindings/core/v8/ExceptionMessages.h" 7 #include "bindings/core/v8/ExceptionMessages.h"
8 #include "bindings/core/v8/ExceptionState.h" 8 #include "bindings/core/v8/ExceptionState.h"
9 #include "bindings/core/v8/ScriptPromiseResolver.h" 9 #include "bindings/core/v8/ScriptPromiseResolver.h"
10 #include "core/dom/DOMException.h" 10 #include "core/dom/DOMException.h"
11 #include "core/dom/ExceptionCode.h" 11 #include "core/dom/ExceptionCode.h"
12 #include "core/frame/LocalDOMWindow.h"
13 #include "core/timing/DOMWindowPerformance.h"
14 #include "core/timing/Performance.h"
12 #include "modules/webaudio/AudioBufferCallback.h" 15 #include "modules/webaudio/AudioBufferCallback.h"
16 #include "modules/webaudio/AudioTimestamp.h"
13 #include "platform/Histogram.h" 17 #include "platform/Histogram.h"
14 #include "platform/audio/AudioUtilities.h" 18 #include "platform/audio/AudioUtilities.h"
15 19
16 #if DEBUG_AUDIONODE_REFERENCES 20 #if DEBUG_AUDIONODE_REFERENCES
17 #include <stdio.h> 21 #include <stdio.h>
18 #endif 22 #endif
19 23
20 namespace blink { 24 namespace blink {
21 25
22 // Don't allow more than this number of simultaneous AudioContexts 26 // Don't allow more than this number of simultaneous AudioContexts
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 ("WebAudio.AudioContext.HardwareSampleRate")); 77 ("WebAudio.AudioContext.HardwareSampleRate"));
74 maxChannelCountHistogram.sample(audioContext->destination()->maxChannelCount ()); 78 maxChannelCountHistogram.sample(audioContext->destination()->maxChannelCount ());
75 sampleRateHistogram.sample(audioContext->sampleRate()); 79 sampleRateHistogram.sample(audioContext->sampleRate());
76 80
77 return audioContext; 81 return audioContext;
78 } 82 }
79 83
80 AudioContext::AudioContext(Document& document) 84 AudioContext::AudioContext(Document& document)
81 : AbstractAudioContext(&document) 85 : AbstractAudioContext(&document)
82 , m_contextId(s_contextId++) 86 , m_contextId(s_contextId++)
87 , m_outputTimestampFramesOrigin(0)
83 { 88 {
84 } 89 }
85 90
86 AudioContext::~AudioContext() 91 AudioContext::~AudioContext()
87 { 92 {
88 #if DEBUG_AUDIONODE_REFERENCES 93 #if DEBUG_AUDIONODE_REFERENCES
89 fprintf(stderr, "%p: AudioContext::~AudioContext(): %u\n", this, m_contextId ); 94 fprintf(stderr, "%p: AudioContext::~AudioContext(): %u\n", this, m_contextId );
90 #endif 95 #endif
91 } 96 }
92 97
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 InvalidAccessError, 136 InvalidAccessError,
132 "cannot resume a closed AudioContext")); 137 "cannot resume a closed AudioContext"));
133 } 138 }
134 139
135 recordUserGestureState(); 140 recordUserGestureState();
136 141
137 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 142 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
138 ScriptPromise promise = resolver->promise(); 143 ScriptPromise promise = resolver->promise();
139 144
140 // Restart the destination node to pull on the audio graph. 145 // Restart the destination node to pull on the audio graph.
141 if (destination()) 146 if (destination()) {
147 m_outputTimestampFramesOrigin = currentSampleFrame();
142 startRendering(); 148 startRendering();
149 }
143 150
144 // Save the resolver which will get resolved when the destination node start s pulling on the 151 // Save the resolver which will get resolved when the destination node start s pulling on the
145 // graph again. 152 // graph again.
146 { 153 {
147 AutoLocker locker(this); 154 AutoLocker locker(this);
148 m_resumeResolvers.append(resolver); 155 m_resumeResolvers.append(resolver);
149 } 156 }
150 157
151 return promise; 158 return promise;
152 } 159 }
153 160
161 static double toPerformanceTime(ExecutionContext* context, double seconds)
162 {
163 if (!context)
164 return 0.0;
165
166 LocalDOMWindow* window = context->executingWindow();
167 if (!window)
168 return 0.0;
169
170 Performance* performance = DOMWindowPerformance::performance(*window);
171 if (!performance)
172 return 0.0;
173
174 return performance->monotonicTimeToDOMHighResTimeStamp(seconds);
175 }
176
177 void AudioContext::getOutputTimestamp(AudioTimestamp& result)
178 {
179 DCHECK(isMainThread());
180 if (!destination()) {
181 result.setContextTime(0.0);
182 result.setPerformanceTime(0.0);
183 return;
184 }
185
186 WebAudioTimestamp timestamp = outputTimestamp();
187 double sampleRate = destination()->audioDestinationHandler().sampleRate();
188 double contextTime = (m_outputTimestampFramesOrigin + timestamp.frames) / sa mpleRate;
189 double performanceTime = timestamp.seconds ? toPerformanceTime(getExecutionC ontext(), timestamp.seconds) : 0.0;
190
191 result.setContextTime(contextTime);
192 result.setPerformanceTime(performanceTime);
193 }
194
154 ScriptPromise AudioContext::closeContext(ScriptState* scriptState) 195 ScriptPromise AudioContext::closeContext(ScriptState* scriptState)
155 { 196 {
156 if (isContextClosed()) { 197 if (isContextClosed()) {
157 // We've already closed the context previously, but it hasn't yet been r esolved, so just 198 // We've already closed the context previously, but it hasn't yet been r esolved, so just
158 // create a new promise and reject it. 199 // create a new promise and reject it.
159 return ScriptPromise::rejectWithDOMException( 200 return ScriptPromise::rejectWithDOMException(
160 scriptState, 201 scriptState,
161 DOMException::create(InvalidStateError, 202 DOMException::create(InvalidStateError,
162 "Cannot close a context that is being closed or has already been closed.")); 203 "Cannot close a context that is being closed or has already been closed."));
163 } 204 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 ASSERT(destination()); 242 ASSERT(destination());
202 243
203 if (contextState() == Running) { 244 if (contextState() == Running) {
204 destination()->audioDestinationHandler().stopRendering(); 245 destination()->audioDestinationHandler().stopRendering();
205 setContextState(Suspended); 246 setContextState(Suspended);
206 deferredTaskHandler().clearHandlersToBeDeleted(); 247 deferredTaskHandler().clearHandlersToBeDeleted();
207 } 248 }
208 } 249 }
209 250
210 } // namespace blink 251 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698