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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 unsigned AudioContext::s_hardwareContextCount = 0; | 84 unsigned AudioContext::s_hardwareContextCount = 0; |
85 unsigned AudioContext::s_contextId = 0; | 85 unsigned AudioContext::s_contextId = 0; |
86 | 86 |
87 AudioContext* AudioContext::create(Document& document, ExceptionState& exception
State) | 87 AudioContext* AudioContext::create(Document& document, ExceptionState& exception
State) |
88 { | 88 { |
89 ASSERT(isMainThread()); | 89 ASSERT(isMainThread()); |
90 if (s_hardwareContextCount >= MaxHardwareContexts) { | 90 if (s_hardwareContextCount >= MaxHardwareContexts) { |
91 exceptionState.throwDOMException( | 91 exceptionState.throwDOMException( |
92 SyntaxError, | 92 SyntaxError, |
93 "number of hardware contexts reached maximum (" + String::number(Max
HardwareContexts) + ")."); | 93 "number of hardware contexts reached maximum (" + String::number(Max
HardwareContexts) + ")."); |
94 return 0; | 94 return nullptr; |
95 } | 95 } |
96 | 96 |
97 AudioContext* audioContext = new AudioContext(&document); | 97 AudioContext* audioContext = new AudioContext(&document); |
98 audioContext->suspendIfNeeded(); | 98 audioContext->suspendIfNeeded(); |
99 return audioContext; | 99 return audioContext; |
100 } | 100 } |
101 | 101 |
102 // Constructor for rendering to the audio hardware. | 102 // Constructor for rendering to the audio hardware. |
103 AudioContext::AudioContext(Document* document) | 103 AudioContext::AudioContext(Document* document) |
104 : ActiveDOMObject(document) | 104 : ActiveDOMObject(document) |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 313 |
314 if (isContextClosed()) { | 314 if (isContextClosed()) { |
315 throwExceptionForClosedState(exceptionState); | 315 throwExceptionForClosedState(exceptionState); |
316 return nullptr; | 316 return nullptr; |
317 } | 317 } |
318 | 318 |
319 if (!mediaElement) { | 319 if (!mediaElement) { |
320 exceptionState.throwDOMException( | 320 exceptionState.throwDOMException( |
321 InvalidStateError, | 321 InvalidStateError, |
322 "invalid HTMLMedialElement."); | 322 "invalid HTMLMedialElement."); |
323 return 0; | 323 return nullptr; |
324 } | 324 } |
325 | 325 |
326 // First check if this media element already has a source node. | 326 // First check if this media element already has a source node. |
327 if (mediaElement->audioSourceNode()) { | 327 if (mediaElement->audioSourceNode()) { |
328 exceptionState.throwDOMException( | 328 exceptionState.throwDOMException( |
329 InvalidStateError, | 329 InvalidStateError, |
330 "HTMLMediaElement already connected previously to a different MediaE
lementSourceNode."); | 330 "HTMLMediaElement already connected previously to a different MediaE
lementSourceNode."); |
331 return 0; | 331 return nullptr; |
332 } | 332 } |
333 | 333 |
334 MediaElementAudioSourceNode* node = MediaElementAudioSourceNode::create(this
, mediaElement); | 334 MediaElementAudioSourceNode* node = MediaElementAudioSourceNode::create(this
, mediaElement); |
335 | 335 |
336 mediaElement->setAudioSourceNode(node); | 336 mediaElement->setAudioSourceNode(node); |
337 | 337 |
338 refNode(node); // context keeps reference until node is disconnected | 338 refNode(node); // context keeps reference until node is disconnected |
339 return node; | 339 return node; |
340 } | 340 } |
341 | 341 |
342 MediaStreamAudioSourceNode* AudioContext::createMediaStreamSource(MediaStream* m
ediaStream, ExceptionState& exceptionState) | 342 MediaStreamAudioSourceNode* AudioContext::createMediaStreamSource(MediaStream* m
ediaStream, ExceptionState& exceptionState) |
343 { | 343 { |
344 ASSERT(isMainThread()); | 344 ASSERT(isMainThread()); |
345 | 345 |
346 if (isContextClosed()) { | 346 if (isContextClosed()) { |
347 throwExceptionForClosedState(exceptionState); | 347 throwExceptionForClosedState(exceptionState); |
348 return nullptr; | 348 return nullptr; |
349 } | 349 } |
350 | 350 |
351 if (!mediaStream) { | 351 if (!mediaStream) { |
352 exceptionState.throwDOMException( | 352 exceptionState.throwDOMException( |
353 InvalidStateError, | 353 InvalidStateError, |
354 "invalid MediaStream source"); | 354 "invalid MediaStream source"); |
355 return 0; | 355 return nullptr; |
356 } | 356 } |
357 | 357 |
358 MediaStreamTrackVector audioTracks = mediaStream->getAudioTracks(); | 358 MediaStreamTrackVector audioTracks = mediaStream->getAudioTracks(); |
359 if (audioTracks.isEmpty()) { | 359 if (audioTracks.isEmpty()) { |
360 exceptionState.throwDOMException( | 360 exceptionState.throwDOMException( |
361 InvalidStateError, | 361 InvalidStateError, |
362 "MediaStream has no audio track"); | 362 "MediaStream has no audio track"); |
363 return 0; | 363 return nullptr; |
364 } | 364 } |
365 | 365 |
366 // Use the first audio track in the media stream. | 366 // Use the first audio track in the media stream. |
367 MediaStreamTrack* audioTrack = audioTracks[0]; | 367 MediaStreamTrack* audioTrack = audioTracks[0]; |
368 OwnPtr<AudioSourceProvider> provider = audioTrack->createWebAudioSource(); | 368 OwnPtr<AudioSourceProvider> provider = audioTrack->createWebAudioSource(); |
369 MediaStreamAudioSourceNode* node = MediaStreamAudioSourceNode::create(this,
mediaStream, audioTrack, provider.release()); | 369 MediaStreamAudioSourceNode* node = MediaStreamAudioSourceNode::create(this,
mediaStream, audioTrack, provider.release()); |
370 | 370 |
371 // FIXME: Only stereo streams are supported right now. We should be able to
accept multi-channel streams. | 371 // FIXME: Only stereo streams are supported right now. We should be able to
accept multi-channel streams. |
372 node->setFormat(2, sampleRate()); | 372 node->setFormat(2, sampleRate()); |
373 | 373 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 IndexSizeError, | 446 IndexSizeError, |
447 "number of output channels (" + String::number(numberOfInputChan
nels) | 447 "number of output channels (" + String::number(numberOfInputChan
nels) |
448 + ") exceeds maximum (" | 448 + ") exceeds maximum (" |
449 + String::number(AudioContext::maxNumberOfChannels()) + ")."); | 449 + String::number(AudioContext::maxNumberOfChannels()) + ")."); |
450 } else { | 450 } else { |
451 exceptionState.throwDOMException( | 451 exceptionState.throwDOMException( |
452 IndexSizeError, | 452 IndexSizeError, |
453 "buffer size (" + String::number(bufferSize) | 453 "buffer size (" + String::number(bufferSize) |
454 + ") must be a power of two between 256 and 16384."); | 454 + ") must be a power of two between 256 and 16384."); |
455 } | 455 } |
456 return 0; | 456 return nullptr; |
457 } | 457 } |
458 | 458 |
459 refNode(node); // context keeps reference until we stop making javascript re
ndering callbacks | 459 refNode(node); // context keeps reference until we stop making javascript re
ndering callbacks |
460 return node; | 460 return node; |
461 } | 461 } |
462 | 462 |
463 StereoPannerNode* AudioContext::createStereoPanner(ExceptionState& exceptionStat
e) | 463 StereoPannerNode* AudioContext::createStereoPanner(ExceptionState& exceptionStat
e) |
464 { | 464 { |
465 ASSERT(isMainThread()); | 465 ASSERT(isMainThread()); |
466 if (isContextClosed()) { | 466 if (isContextClosed()) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 DelayNode* AudioContext::createDelay(double maxDelayTime, ExceptionState& except
ionState) | 562 DelayNode* AudioContext::createDelay(double maxDelayTime, ExceptionState& except
ionState) |
563 { | 563 { |
564 ASSERT(isMainThread()); | 564 ASSERT(isMainThread()); |
565 if (isContextClosed()) { | 565 if (isContextClosed()) { |
566 throwExceptionForClosedState(exceptionState); | 566 throwExceptionForClosedState(exceptionState); |
567 return nullptr; | 567 return nullptr; |
568 } | 568 } |
569 | 569 |
570 DelayNode* node = DelayNode::create(this, m_destinationNode->sampleRate(), m
axDelayTime, exceptionState); | 570 DelayNode* node = DelayNode::create(this, m_destinationNode->sampleRate(), m
axDelayTime, exceptionState); |
571 if (exceptionState.hadException()) | 571 if (exceptionState.hadException()) |
572 return 0; | 572 return nullptr; |
573 return node; | 573 return node; |
574 } | 574 } |
575 | 575 |
576 ChannelSplitterNode* AudioContext::createChannelSplitter(ExceptionState& excepti
onState) | 576 ChannelSplitterNode* AudioContext::createChannelSplitter(ExceptionState& excepti
onState) |
577 { | 577 { |
578 if (isContextClosed()) { | 578 if (isContextClosed()) { |
579 throwExceptionForClosedState(exceptionState); | 579 throwExceptionForClosedState(exceptionState); |
580 return nullptr; | 580 return nullptr; |
581 } | 581 } |
582 | 582 |
(...skipping 11 matching lines...) Expand all Loading... |
594 } | 594 } |
595 | 595 |
596 ChannelSplitterNode* node = ChannelSplitterNode::create(this, m_destinationN
ode->sampleRate(), numberOfOutputs); | 596 ChannelSplitterNode* node = ChannelSplitterNode::create(this, m_destinationN
ode->sampleRate(), numberOfOutputs); |
597 | 597 |
598 if (!node) { | 598 if (!node) { |
599 exceptionState.throwDOMException( | 599 exceptionState.throwDOMException( |
600 IndexSizeError, | 600 IndexSizeError, |
601 "number of outputs (" + String::number(numberOfOutputs) | 601 "number of outputs (" + String::number(numberOfOutputs) |
602 + ") must be between 1 and " | 602 + ") must be between 1 and " |
603 + String::number(AudioContext::maxNumberOfChannels()) + "."); | 603 + String::number(AudioContext::maxNumberOfChannels()) + "."); |
604 return 0; | 604 return nullptr; |
605 } | 605 } |
606 | 606 |
607 return node; | 607 return node; |
608 } | 608 } |
609 | 609 |
610 ChannelMergerNode* AudioContext::createChannelMerger(ExceptionState& exceptionSt
ate) | 610 ChannelMergerNode* AudioContext::createChannelMerger(ExceptionState& exceptionSt
ate) |
611 { | 611 { |
612 if (isContextClosed()) { | 612 if (isContextClosed()) { |
613 throwExceptionForClosedState(exceptionState); | 613 throwExceptionForClosedState(exceptionState); |
614 return nullptr; | 614 return nullptr; |
(...skipping 12 matching lines...) Expand all Loading... |
627 } | 627 } |
628 | 628 |
629 ChannelMergerNode* node = ChannelMergerNode::create(this, m_destinationNode-
>sampleRate(), numberOfInputs); | 629 ChannelMergerNode* node = ChannelMergerNode::create(this, m_destinationNode-
>sampleRate(), numberOfInputs); |
630 | 630 |
631 if (!node) { | 631 if (!node) { |
632 exceptionState.throwDOMException( | 632 exceptionState.throwDOMException( |
633 IndexSizeError, | 633 IndexSizeError, |
634 "number of inputs (" + String::number(numberOfInputs) | 634 "number of inputs (" + String::number(numberOfInputs) |
635 + ") must be between 1 and " | 635 + ") must be between 1 and " |
636 + String::number(AudioContext::maxNumberOfChannels()) + "."); | 636 + String::number(AudioContext::maxNumberOfChannels()) + "."); |
637 return 0; | 637 return nullptr; |
638 } | 638 } |
639 | 639 |
640 return node; | 640 return node; |
641 } | 641 } |
642 | 642 |
643 OscillatorNode* AudioContext::createOscillator(ExceptionState& exceptionState) | 643 OscillatorNode* AudioContext::createOscillator(ExceptionState& exceptionState) |
644 { | 644 { |
645 ASSERT(isMainThread()); | 645 ASSERT(isMainThread()); |
646 if (isContextClosed()) { | 646 if (isContextClosed()) { |
647 throwExceptionForClosedState(exceptionState); | 647 throwExceptionForClosedState(exceptionState); |
(...skipping 14 matching lines...) Expand all Loading... |
662 | 662 |
663 if (isContextClosed()) { | 663 if (isContextClosed()) { |
664 throwExceptionForClosedState(exceptionState); | 664 throwExceptionForClosedState(exceptionState); |
665 return nullptr; | 665 return nullptr; |
666 } | 666 } |
667 | 667 |
668 if (!real) { | 668 if (!real) { |
669 exceptionState.throwDOMException( | 669 exceptionState.throwDOMException( |
670 SyntaxError, | 670 SyntaxError, |
671 "invalid real array"); | 671 "invalid real array"); |
672 return 0; | 672 return nullptr; |
673 } | 673 } |
674 | 674 |
675 if (!imag) { | 675 if (!imag) { |
676 exceptionState.throwDOMException( | 676 exceptionState.throwDOMException( |
677 SyntaxError, | 677 SyntaxError, |
678 "invalid imaginary array"); | 678 "invalid imaginary array"); |
679 return 0; | 679 return nullptr; |
680 } | 680 } |
681 | 681 |
682 if (real->length() > PeriodicWave::kMaxPeriodicWaveArraySize) { | 682 if (real->length() > PeriodicWave::kMaxPeriodicWaveArraySize) { |
683 exceptionState.throwDOMException( | 683 exceptionState.throwDOMException( |
684 IndexSizeError, | 684 IndexSizeError, |
685 ExceptionMessages::indexOutsideRange( | 685 ExceptionMessages::indexOutsideRange( |
686 "length of the real part array", | 686 "length of the real part array", |
687 real->length(), | 687 real->length(), |
688 1u, | 688 1u, |
689 ExceptionMessages::InclusiveBound, | 689 ExceptionMessages::InclusiveBound, |
690 PeriodicWave::kMaxPeriodicWaveArraySize, | 690 PeriodicWave::kMaxPeriodicWaveArraySize, |
691 ExceptionMessages::InclusiveBound)); | 691 ExceptionMessages::InclusiveBound)); |
692 return 0; | 692 return nullptr; |
693 } | 693 } |
694 | 694 |
695 if (imag->length() > PeriodicWave::kMaxPeriodicWaveArraySize) { | 695 if (imag->length() > PeriodicWave::kMaxPeriodicWaveArraySize) { |
696 exceptionState.throwDOMException( | 696 exceptionState.throwDOMException( |
697 IndexSizeError, | 697 IndexSizeError, |
698 ExceptionMessages::indexOutsideRange( | 698 ExceptionMessages::indexOutsideRange( |
699 "length of the imaginary part array", | 699 "length of the imaginary part array", |
700 imag->length(), | 700 imag->length(), |
701 1u, | 701 1u, |
702 ExceptionMessages::InclusiveBound, | 702 ExceptionMessages::InclusiveBound, |
703 PeriodicWave::kMaxPeriodicWaveArraySize, | 703 PeriodicWave::kMaxPeriodicWaveArraySize, |
704 ExceptionMessages::InclusiveBound)); | 704 ExceptionMessages::InclusiveBound)); |
705 return 0; | 705 return nullptr; |
706 } | 706 } |
707 | 707 |
708 if (real->length() != imag->length()) { | 708 if (real->length() != imag->length()) { |
709 exceptionState.throwDOMException( | 709 exceptionState.throwDOMException( |
710 IndexSizeError, | 710 IndexSizeError, |
711 "length of real array (" + String::number(real->length()) | 711 "length of real array (" + String::number(real->length()) |
712 + ") and length of imaginary array (" + String::number(imag->length
()) | 712 + ") and length of imaginary array (" + String::number(imag->length
()) |
713 + ") must match."); | 713 + ") must match."); |
714 return 0; | 714 return nullptr; |
715 } | 715 } |
716 | 716 |
717 return PeriodicWave::create(sampleRate(), real, imag); | 717 return PeriodicWave::create(sampleRate(), real, imag); |
718 } | 718 } |
719 | 719 |
720 size_t AudioContext::cachedSampleFrame() const | 720 size_t AudioContext::cachedSampleFrame() const |
721 { | 721 { |
722 ASSERT(isMainThread()); | 722 ASSERT(isMainThread()); |
723 | 723 |
724 return m_cachedSampleFrame; | 724 return m_cachedSampleFrame; |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 // the destination node can GCed if JS has no references. stop() will also r
esolve the Promise | 1361 // the destination node can GCed if JS has no references. stop() will also r
esolve the Promise |
1362 // created here. | 1362 // created here. |
1363 stop(); | 1363 stop(); |
1364 | 1364 |
1365 return promise; | 1365 return promise; |
1366 } | 1366 } |
1367 | 1367 |
1368 } // namespace blink | 1368 } // namespace blink |
1369 | 1369 |
1370 #endif // ENABLE(WEB_AUDIO) | 1370 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |