| 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 |