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

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

Issue 1952793002: Move the exception logic to the AudioNode creator (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 7 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 /* 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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 if (isDestinationInitialized()) 134 if (isDestinationInitialized())
135 return; 135 return;
136 136
137 FFTFrame::initialize(); 137 FFTFrame::initialize();
138 138
139 if (m_destinationNode) { 139 if (m_destinationNode) {
140 m_destinationNode->handler().initialize(); 140 m_destinationNode->handler().initialize();
141 // The AudioParams in the listener need access to the destination node, so only create the 141 // The AudioParams in the listener need access to the destination node, so only create the
142 // listener if the destination node exists. 142 // listener if the destination node exists.
143 m_listener = AudioListener::create(*this); 143 m_listener = AudioListener::create(*this);
144 } 144 }
hongchan 2016/05/20 21:28:32 Just curious: when m_destinationNode is not valid,
Raymond Toy 2016/05/20 21:46:10 If m_destination doesn't exist, the AudioParams in
hongchan 2016/05/20 22:57:48 Okay, I like to throw more questions here but I do
145 } 145 }
146 146
147 void AbstractAudioContext::clear() 147 void AbstractAudioContext::clear()
148 { 148 {
149 m_destinationNode.clear(); 149 m_destinationNode.clear();
150 // The audio rendering thread is dead. Nobody will schedule AudioHandler 150 // The audio rendering thread is dead. Nobody will schedule AudioHandler
151 // deletion. Let's do it ourselves. 151 // deletion. Let's do it ourselves.
152 deferredTaskHandler().clearHandlersToBeDeleted(); 152 deferredTaskHandler().clearHandlersToBeDeleted();
153 m_isCleared = true; 153 m_isCleared = true;
154 } 154 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 246
247 // We've resolved the promise. Remove it now. 247 // We've resolved the promise. Remove it now.
248 ASSERT(m_decodeAudioResolvers.contains(resolver)); 248 ASSERT(m_decodeAudioResolvers.contains(resolver));
249 m_decodeAudioResolvers.remove(resolver); 249 m_decodeAudioResolvers.remove(resolver);
250 } 250 }
251 251
252 AudioBufferSourceNode* AbstractAudioContext::createBufferSource(ExceptionState& exceptionState) 252 AudioBufferSourceNode* AbstractAudioContext::createBufferSource(ExceptionState& exceptionState)
253 { 253 {
254 ASSERT(isMainThread()); 254 ASSERT(isMainThread());
255 255
256 if (isContextClosed()) { 256 AudioBufferSourceNode* node = AudioBufferSourceNode::create(*this, exception State);
257 throwExceptionForClosedState(exceptionState);
258 return nullptr;
259 }
260
261 AudioBufferSourceNode* node = AudioBufferSourceNode::create(*this, sampleRat e());
262 257
263 // Do not add a reference to this source node now. The reference will be add ed when start() is 258 // Do not add a reference to this source node now. The reference will be add ed when start() is
264 // called. 259 // called.
265 260
266 return node; 261 return node;
267 } 262 }
268 263
269 MediaElementAudioSourceNode* AbstractAudioContext::createMediaElementSource(HTML MediaElement* mediaElement, ExceptionState& exceptionState) 264 MediaElementAudioSourceNode* AbstractAudioContext::createMediaElementSource(HTML MediaElement* mediaElement, ExceptionState& exceptionState)
270 { 265 {
271 ASSERT(isMainThread()); 266 ASSERT(isMainThread());
272 267
273 if (isContextClosed()) { 268 return MediaElementAudioSourceNode::create(*this, *mediaElement, exceptionSt ate);
274 throwExceptionForClosedState(exceptionState);
275 return nullptr;
276 }
277
278 // First check if this media element already has a source node.
279 if (mediaElement->audioSourceNode()) {
280 exceptionState.throwDOMException(
281 InvalidStateError,
282 "HTMLMediaElement already connected previously to a different MediaE lementSourceNode.");
283 return nullptr;
284 }
285
286 MediaElementAudioSourceNode* node = MediaElementAudioSourceNode::create(*thi s, *mediaElement);
287
288 mediaElement->setAudioSourceNode(node);
289
290 notifySourceNodeStartedProcessing(node); // context keeps reference until no de is disconnected
291 return node;
292 } 269 }
293 270
294 MediaStreamAudioSourceNode* AbstractAudioContext::createMediaStreamSource(MediaS tream* mediaStream, ExceptionState& exceptionState) 271 MediaStreamAudioSourceNode* AbstractAudioContext::createMediaStreamSource(MediaS tream* mediaStream, ExceptionState& exceptionState)
295 { 272 {
296 ASSERT(isMainThread()); 273 ASSERT(isMainThread());
297 274
298 if (isContextClosed()) { 275 return MediaStreamAudioSourceNode::create(*this, *mediaStream, exceptionStat e);
299 throwExceptionForClosedState(exceptionState);
300 return nullptr;
301 }
302
303 MediaStreamTrackVector audioTracks = mediaStream->getAudioTracks();
304 if (audioTracks.isEmpty()) {
305 exceptionState.throwDOMException(
306 InvalidStateError,
307 "MediaStream has no audio track");
308 return nullptr;
309 }
310
311 // Use the first audio track in the media stream.
312 MediaStreamTrack* audioTrack = audioTracks[0];
313 OwnPtr<AudioSourceProvider> provider = audioTrack->createWebAudioSource();
314 MediaStreamAudioSourceNode* node = MediaStreamAudioSourceNode::create(*this, *mediaStream, audioTrack, std::move(provider));
315
316 // FIXME: Only stereo streams are supported right now. We should be able to accept multi-channel streams.
317 node->setFormat(2, sampleRate());
318
319 notifySourceNodeStartedProcessing(node); // context keeps reference until no de is disconnected
320 return node;
321 } 276 }
322 277
323 MediaStreamAudioDestinationNode* AbstractAudioContext::createMediaStreamDestinat ion(ExceptionState& exceptionState) 278 MediaStreamAudioDestinationNode* AbstractAudioContext::createMediaStreamDestinat ion(ExceptionState& exceptionState)
324 { 279 {
325 if (isContextClosed()) { 280 DCHECK(isMainThread());
326 throwExceptionForClosedState(exceptionState);
327 return nullptr;
328 }
329 281
330 // Set number of output channels to stereo by default. 282 // Set number of output channels to stereo by default.
331 return MediaStreamAudioDestinationNode::create(*this, 2); 283 return MediaStreamAudioDestinationNode::create(*this, 2, exceptionState);
332 } 284 }
333 285
334 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(ExceptionState& exceptionState) 286 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(ExceptionState& exceptionState)
335 { 287 {
336 // Set number of input/output channels to stereo by default. 288 DCHECK(isMainThread());
337 return createScriptProcessor(0, 2, 2, exceptionState); 289
290 return ScriptProcessorNode::create(*this, exceptionState);
338 } 291 }
339 292
340 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi ze, ExceptionState& exceptionState) 293 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi ze, ExceptionState& exceptionState)
341 { 294 {
342 // Set number of input/output channels to stereo by default. 295 DCHECK(isMainThread());
343 return createScriptProcessor(bufferSize, 2, 2, exceptionState); 296
297 return ScriptProcessorNode::create(*this, bufferSize, exceptionState);
344 } 298 }
345 299
346 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi ze, size_t numberOfInputChannels, ExceptionState& exceptionState) 300 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi ze, size_t numberOfInputChannels, ExceptionState& exceptionState)
347 { 301 {
348 // Set number of output channels to stereo by default. 302 DCHECK(isMainThread());
349 return createScriptProcessor(bufferSize, numberOfInputChannels, 2, exception State); 303
304 return ScriptProcessorNode::create(*this, bufferSize, numberOfInputChannels, exceptionState);
350 } 305 }
351 306
352 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi ze, size_t numberOfInputChannels, size_t numberOfOutputChannels, ExceptionState& exceptionState) 307 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi ze, size_t numberOfInputChannels, size_t numberOfOutputChannels, ExceptionState& exceptionState)
353 { 308 {
354 ASSERT(isMainThread()); 309 ASSERT(isMainThread());
355 310
356 if (isContextClosed()) { 311 return ScriptProcessorNode::create(
357 throwExceptionForClosedState(exceptionState); 312 *this,
358 return nullptr; 313 bufferSize,
359 } 314 numberOfInputChannels,
360 315 numberOfOutputChannels,
361 ScriptProcessorNode* node = ScriptProcessorNode::create(*this, sampleRate(), bufferSize, numberOfInputChannels, numberOfOutputChannels); 316 exceptionState);
362
363 if (!node) {
364 if (!numberOfInputChannels && !numberOfOutputChannels) {
365 exceptionState.throwDOMException(
366 IndexSizeError,
367 "number of input channels and output channels cannot both be zer o.");
368 } else if (numberOfInputChannels > AbstractAudioContext::maxNumberOfChan nels()) {
369 exceptionState.throwDOMException(
370 IndexSizeError,
371 "number of input channels (" + String::number(numberOfInputChann els)
372 + ") exceeds maximum ("
373 + String::number(AbstractAudioContext::maxNumberOfChannels()) + ").");
374 } else if (numberOfOutputChannels > AbstractAudioContext::maxNumberOfCha nnels()) {
375 exceptionState.throwDOMException(
376 IndexSizeError,
377 "number of output channels (" + String::number(numberOfInputChan nels)
378 + ") exceeds maximum ("
379 + String::number(AbstractAudioContext::maxNumberOfChannels()) + ").");
380 } else {
381 exceptionState.throwDOMException(
382 IndexSizeError,
383 "buffer size (" + String::number(bufferSize)
384 + ") must be a power of two between 256 and 16384.");
385 }
386 return nullptr;
387 }
388
389 notifySourceNodeStartedProcessing(node); // context keeps reference until we stop making javascript rendering callbacks
390 return node;
391 } 317 }
392 318
393 StereoPannerNode* AbstractAudioContext::createStereoPanner(ExceptionState& excep tionState) 319 StereoPannerNode* AbstractAudioContext::createStereoPanner(ExceptionState& excep tionState)
394 { 320 {
395 ASSERT(isMainThread()); 321 ASSERT(isMainThread());
396 if (isContextClosed()) {
397 throwExceptionForClosedState(exceptionState);
398 return nullptr;
399 }
400 322
401 return StereoPannerNode::create(*this, sampleRate()); 323 return StereoPannerNode::create(*this, exceptionState);
402 } 324 }
403 325
404 BiquadFilterNode* AbstractAudioContext::createBiquadFilter(ExceptionState& excep tionState) 326 BiquadFilterNode* AbstractAudioContext::createBiquadFilter(ExceptionState& excep tionState)
405 { 327 {
406 ASSERT(isMainThread()); 328 ASSERT(isMainThread());
407 if (isContextClosed()) {
408 throwExceptionForClosedState(exceptionState);
409 return nullptr;
410 }
411 329
412 return BiquadFilterNode::create(*this, sampleRate()); 330 return BiquadFilterNode::create(*this, exceptionState);
413 } 331 }
414 332
415 WaveShaperNode* AbstractAudioContext::createWaveShaper(ExceptionState& exception State) 333 WaveShaperNode* AbstractAudioContext::createWaveShaper(ExceptionState& exception State)
416 { 334 {
417 ASSERT(isMainThread()); 335 ASSERT(isMainThread());
418 if (isContextClosed()) {
419 throwExceptionForClosedState(exceptionState);
420 return nullptr;
421 }
422 336
423 return WaveShaperNode::create(*this); 337 return WaveShaperNode::create(*this, exceptionState);
424 } 338 }
425 339
426 PannerNode* AbstractAudioContext::createPanner(ExceptionState& exceptionState) 340 PannerNode* AbstractAudioContext::createPanner(ExceptionState& exceptionState)
427 { 341 {
428 ASSERT(isMainThread()); 342 ASSERT(isMainThread());
429 if (isContextClosed()) {
430 throwExceptionForClosedState(exceptionState);
431 return nullptr;
432 }
433 343
434 return PannerNode::create(*this, sampleRate()); 344 return PannerNode::create(*this, exceptionState);
435 } 345 }
436 346
437 ConvolverNode* AbstractAudioContext::createConvolver(ExceptionState& exceptionSt ate) 347 ConvolverNode* AbstractAudioContext::createConvolver(ExceptionState& exceptionSt ate)
438 { 348 {
439 ASSERT(isMainThread()); 349 ASSERT(isMainThread());
440 if (isContextClosed()) {
441 throwExceptionForClosedState(exceptionState);
442 return nullptr;
443 }
444 350
445 return ConvolverNode::create(*this, sampleRate()); 351 return ConvolverNode::create(*this, exceptionState);
446 } 352 }
447 353
448 DynamicsCompressorNode* AbstractAudioContext::createDynamicsCompressor(Exception State& exceptionState) 354 DynamicsCompressorNode* AbstractAudioContext::createDynamicsCompressor(Exception State& exceptionState)
449 { 355 {
450 ASSERT(isMainThread()); 356 ASSERT(isMainThread());
451 if (isContextClosed()) {
452 throwExceptionForClosedState(exceptionState);
453 return nullptr;
454 }
455 357
456 return DynamicsCompressorNode::create(*this, sampleRate()); 358 return DynamicsCompressorNode::create(*this, exceptionState);
457 } 359 }
458 360
459 AnalyserNode* AbstractAudioContext::createAnalyser(ExceptionState& exceptionStat e) 361 AnalyserNode* AbstractAudioContext::createAnalyser(ExceptionState& exceptionStat e)
460 { 362 {
461 ASSERT(isMainThread()); 363 ASSERT(isMainThread());
462 if (isContextClosed()) {
463 throwExceptionForClosedState(exceptionState);
464 return nullptr;
465 }
466 364
467 return AnalyserNode::create(*this, sampleRate()); 365 return AnalyserNode::create(*this, exceptionState);
468 } 366 }
469 367
470 GainNode* AbstractAudioContext::createGain(ExceptionState& exceptionState) 368 GainNode* AbstractAudioContext::createGain(ExceptionState& exceptionState)
471 { 369 {
472 ASSERT(isMainThread()); 370 ASSERT(isMainThread());
473 if (isContextClosed()) {
474 throwExceptionForClosedState(exceptionState);
475 return nullptr;
476 }
477 371
478 return GainNode::create(*this, sampleRate()); 372 return GainNode::create(*this, exceptionState);
479 } 373 }
480 374
481 DelayNode* AbstractAudioContext::createDelay(ExceptionState& exceptionState) 375 DelayNode* AbstractAudioContext::createDelay(ExceptionState& exceptionState)
482 { 376 {
483 const double defaultMaxDelayTime = 1; 377 DCHECK(isMainThread());
484 return createDelay(defaultMaxDelayTime, exceptionState); 378
379 return DelayNode::create(*this, exceptionState);
485 } 380 }
486 381
487 DelayNode* AbstractAudioContext::createDelay(double maxDelayTime, ExceptionState & exceptionState) 382 DelayNode* AbstractAudioContext::createDelay(double maxDelayTime, ExceptionState & exceptionState)
488 { 383 {
489 ASSERT(isMainThread()); 384 ASSERT(isMainThread());
490 if (isContextClosed()) {
491 throwExceptionForClosedState(exceptionState);
492 return nullptr;
493 }
494 385
495 return DelayNode::create(*this, sampleRate(), maxDelayTime, exceptionState); 386 return DelayNode::create(*this, maxDelayTime, exceptionState);
496 } 387 }
497 388
498 ChannelSplitterNode* AbstractAudioContext::createChannelSplitter(ExceptionState& exceptionState) 389 ChannelSplitterNode* AbstractAudioContext::createChannelSplitter(ExceptionState& exceptionState)
499 { 390 {
500 const unsigned ChannelSplitterDefaultNumberOfOutputs = 6; 391 DCHECK(isMainThread());
501 return createChannelSplitter(ChannelSplitterDefaultNumberOfOutputs, exceptio nState); 392
393 return ChannelSplitterNode::create(*this, exceptionState);
502 } 394 }
503 395
504 ChannelSplitterNode* AbstractAudioContext::createChannelSplitter(size_t numberOf Outputs, ExceptionState& exceptionState) 396 ChannelSplitterNode* AbstractAudioContext::createChannelSplitter(size_t numberOf Outputs, ExceptionState& exceptionState)
505 { 397 {
506 ASSERT(isMainThread()); 398 ASSERT(isMainThread());
507 399
508 if (isContextClosed()) { 400 return ChannelSplitterNode::create(*this, numberOfOutputs, exceptionState);
509 throwExceptionForClosedState(exceptionState);
510 return nullptr;
511 }
512
513 ChannelSplitterNode* node = ChannelSplitterNode::create(*this, sampleRate(), numberOfOutputs);
514
515 if (!node) {
516 exceptionState.throwDOMException(
517 IndexSizeError,
518 "number of outputs (" + String::number(numberOfOutputs)
519 + ") must be between 1 and "
520 + String::number(AbstractAudioContext::maxNumberOfChannels()) + ".") ;
521 return nullptr;
522 }
523
524 return node;
525 } 401 }
526 402
527 ChannelMergerNode* AbstractAudioContext::createChannelMerger(ExceptionState& exc eptionState) 403 ChannelMergerNode* AbstractAudioContext::createChannelMerger(ExceptionState& exc eptionState)
528 { 404 {
529 const unsigned ChannelMergerDefaultNumberOfInputs = 6; 405 DCHECK(isMainThread());
530 return createChannelMerger(ChannelMergerDefaultNumberOfInputs, exceptionStat e); 406
407 return ChannelMergerNode::create(*this, exceptionState);
531 } 408 }
532 409
533 ChannelMergerNode* AbstractAudioContext::createChannelMerger(size_t numberOfInpu ts, ExceptionState& exceptionState) 410 ChannelMergerNode* AbstractAudioContext::createChannelMerger(size_t numberOfInpu ts, ExceptionState& exceptionState)
534 { 411 {
535 ASSERT(isMainThread()); 412 ASSERT(isMainThread());
536 if (isContextClosed()) {
537 throwExceptionForClosedState(exceptionState);
538 return nullptr;
539 }
540 413
541 ChannelMergerNode* node = ChannelMergerNode::create(*this, sampleRate(), num berOfInputs); 414 return ChannelMergerNode::create(*this, numberOfInputs, exceptionState);
542
543 if (!node) {
544 exceptionState.throwDOMException(
545 IndexSizeError,
546 ExceptionMessages::indexOutsideRange<size_t>(
547 "number of inputs",
548 numberOfInputs,
549 1,
550 ExceptionMessages::InclusiveBound,
551 AbstractAudioContext::maxNumberOfChannels(),
552 ExceptionMessages::InclusiveBound));
553 return nullptr;
554 }
555
556 return node;
557 } 415 }
558 416
559 OscillatorNode* AbstractAudioContext::createOscillator(ExceptionState& exception State) 417 OscillatorNode* AbstractAudioContext::createOscillator(ExceptionState& exception State)
560 { 418 {
561 ASSERT(isMainThread()); 419 ASSERT(isMainThread());
562 if (isContextClosed()) {
563 throwExceptionForClosedState(exceptionState);
564 return nullptr;
565 }
566 420
567 OscillatorNode* node = OscillatorNode::create(*this, sampleRate()); 421 return OscillatorNode::create(*this, exceptionState);
568
569 // Do not add a reference to this source node now. The reference will be add ed when start() is
570 // called.
571
572 return node;
573 } 422 }
574 423
575 PeriodicWave* AbstractAudioContext::createPeriodicWave(DOMFloat32Array* real, DO MFloat32Array* imag, ExceptionState& exceptionState) 424 PeriodicWave* AbstractAudioContext::createPeriodicWave(DOMFloat32Array* real, DO MFloat32Array* imag, ExceptionState& exceptionState)
576 { 425 {
577 return PeriodicWave::create(sampleRate(), real, imag, false); 426 DCHECK(isMainThread());
427
428 return PeriodicWave::create(*this, real, imag, false, exceptionState);
578 } 429 }
579 430
580 PeriodicWave* AbstractAudioContext::createPeriodicWave(DOMFloat32Array* real, DO MFloat32Array* imag, const PeriodicWaveConstraints& options, ExceptionState& exc eptionState) 431 PeriodicWave* AbstractAudioContext::createPeriodicWave(DOMFloat32Array* real, DO MFloat32Array* imag, const PeriodicWaveConstraints& options, ExceptionState& exc eptionState)
581 { 432 {
582 ASSERT(isMainThread()); 433 ASSERT(isMainThread());
583 434
584 if (isContextClosed()) {
585 throwExceptionForClosedState(exceptionState);
586 return nullptr;
587 }
588
589 if (real->length() != imag->length()) {
590 exceptionState.throwDOMException(
591 IndexSizeError,
592 "length of real array (" + String::number(real->length())
593 + ") and length of imaginary array (" + String::number(imag->length ())
594 + ") must match.");
595 return nullptr;
596 }
597
598 bool disable = options.hasDisableNormalization() ? options.disableNormalizat ion() : false; 435 bool disable = options.hasDisableNormalization() ? options.disableNormalizat ion() : false;
599 436
600 return PeriodicWave::create(sampleRate(), real, imag, disable); 437 return PeriodicWave::create(*this, real, imag, disable, exceptionState);
601 } 438 }
602 439
603 IIRFilterNode* AbstractAudioContext::createIIRFilter(Vector<double> feedforwardC oef, Vector<double> feedbackCoef, ExceptionState& exceptionState) 440 IIRFilterNode* AbstractAudioContext::createIIRFilter(Vector<double> feedforwardC oef, Vector<double> feedbackCoef, ExceptionState& exceptionState)
604 { 441 {
605 ASSERT(isMainThread()); 442 ASSERT(isMainThread());
606 443
607 if (isContextClosed()) { 444 return IIRFilterNode::create(*this, feedforwardCoef, feedbackCoef, exception State);
608 throwExceptionForClosedState(exceptionState);
609 return nullptr;
610 }
611
612 if (feedbackCoef.size() == 0 || (feedbackCoef.size() > IIRFilter::kMaxOrder + 1)) {
613 exceptionState.throwDOMException(
614 NotSupportedError,
615 ExceptionMessages::indexOutsideRange<size_t>(
616 "number of feedback coefficients",
617 feedbackCoef.size(),
618 1,
619 ExceptionMessages::InclusiveBound,
620 IIRFilter::kMaxOrder + 1,
621 ExceptionMessages::InclusiveBound));
622 return nullptr;
623 }
624
625 if (feedforwardCoef.size() == 0 || (feedforwardCoef.size() > IIRFilter::kMax Order + 1)) {
626 exceptionState.throwDOMException(
627 NotSupportedError,
628 ExceptionMessages::indexOutsideRange<size_t>(
629 "number of feedforward coefficients",
630 feedforwardCoef.size(),
631 1,
632 ExceptionMessages::InclusiveBound,
633 IIRFilter::kMaxOrder + 1,
634 ExceptionMessages::InclusiveBound));
635 return nullptr;
636 }
637
638 if (feedbackCoef[0] == 0) {
639 exceptionState.throwDOMException(
640 InvalidStateError,
641 "First feedback coefficient cannot be zero.");
642 return nullptr;
643 }
644
645 bool hasNonZeroCoef = false;
646
647 for (size_t k = 0; k < feedforwardCoef.size(); ++k) {
648 if (feedforwardCoef[k] != 0) {
649 hasNonZeroCoef = true;
650 break;
651 }
652 }
653
654 if (!hasNonZeroCoef) {
655 exceptionState.throwDOMException(
656 InvalidStateError,
657 "At least one feedforward coefficient must be non-zero.");
658 return nullptr;
659 }
660
661 // Make sure all coefficents are finite.
662 for (size_t k = 0; k < feedforwardCoef.size(); ++k) {
663 double c = feedforwardCoef[k];
664 if (!std::isfinite(c)) {
665 String name = "feedforward coefficient " + String::number(k);
666 exceptionState.throwDOMException(
667 InvalidStateError,
668 ExceptionMessages::notAFiniteNumber(c, name.ascii().data()));
669 return nullptr;
670 }
671 }
672
673 for (size_t k = 0; k < feedbackCoef.size(); ++k) {
674 double c = feedbackCoef[k];
675 if (!std::isfinite(c)) {
676 String name = "feedback coefficient " + String::number(k);
677 exceptionState.throwDOMException(
678 InvalidStateError,
679 ExceptionMessages::notAFiniteNumber(c, name.ascii().data()));
680 return nullptr;
681 }
682 }
683
684 return IIRFilterNode::create(*this, sampleRate(), feedforwardCoef, feedbackC oef);
685 } 445 }
686 446
687 PeriodicWave* AbstractAudioContext::periodicWave(int type) 447 PeriodicWave* AbstractAudioContext::periodicWave(int type)
688 { 448 {
689 switch (type) { 449 switch (type) {
690 case OscillatorHandler::SINE: 450 case OscillatorHandler::SINE:
691 // Initialize the table if necessary 451 // Initialize the table if necessary
692 if (!m_periodicWaveSine) 452 if (!m_periodicWaveSine)
693 m_periodicWaveSine = PeriodicWave::createSine(sampleRate()); 453 m_periodicWaveSine = PeriodicWave::createSine(sampleRate());
694 return m_periodicWaveSine; 454 return m_periodicWaveSine;
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 741
982 SecurityOrigin* AbstractAudioContext::getSecurityOrigin() const 742 SecurityOrigin* AbstractAudioContext::getSecurityOrigin() const
983 { 743 {
984 if (getExecutionContext()) 744 if (getExecutionContext())
985 return getExecutionContext()->getSecurityOrigin(); 745 return getExecutionContext()->getSecurityOrigin();
986 746
987 return nullptr; 747 return nullptr;
988 } 748 }
989 749
990 } // namespace blink 750 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698