| 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 |
| 11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
| 12 * | 12 * |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN
Y | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN
Y |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN
Y | 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN
Y |
| 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N | 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N |
| 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 23 */ | 23 */ |
| 24 | 24 |
| 25 #include "modules/webaudio/AudioBufferSourceNode.h" | 25 #include "modules/webaudio/AudioBufferSourceNode.h" |
| 26 #include "bindings/core/v8/ExceptionMessages.h" | 26 #include "bindings/core/v8/ExceptionMessages.h" |
| 27 #include "bindings/core/v8/ExceptionState.h" | 27 #include "bindings/core/v8/ExceptionState.h" |
| 28 #include "core/dom/ExceptionCode.h" | 28 #include "core/dom/ExceptionCode.h" |
| 29 #include "core/frame/UseCounter.h" | 29 #include "core/frame/UseCounter.h" |
| 30 #include "modules/webaudio/AbstractAudioContext.h" | |
| 31 #include "modules/webaudio/AudioNodeOutput.h" | 30 #include "modules/webaudio/AudioNodeOutput.h" |
| 31 #include "modules/webaudio/BaseAudioContext.h" |
| 32 #include "platform/FloatConversion.h" | 32 #include "platform/FloatConversion.h" |
| 33 #include "platform/audio/AudioUtilities.h" | 33 #include "platform/audio/AudioUtilities.h" |
| 34 #include "wtf/MathExtras.h" | 34 #include "wtf/MathExtras.h" |
| 35 #include <algorithm> | 35 #include <algorithm> |
| 36 | 36 |
| 37 namespace blink { | 37 namespace blink { |
| 38 | 38 |
| 39 const double DefaultGrainDuration = 0.020; // 20ms | 39 const double DefaultGrainDuration = 0.020; // 20ms |
| 40 | 40 |
| 41 // Arbitrary upper limit on playback rate. | 41 // Arbitrary upper limit on playback rate. |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 ASSERT(isMainThread()); | 336 ASSERT(isMainThread()); |
| 337 | 337 |
| 338 if (m_buffer) { | 338 if (m_buffer) { |
| 339 exceptionState.throwDOMException( | 339 exceptionState.throwDOMException( |
| 340 InvalidStateError, | 340 InvalidStateError, |
| 341 "Cannot set buffer after it has been already been set"); | 341 "Cannot set buffer after it has been already been set"); |
| 342 return; | 342 return; |
| 343 } | 343 } |
| 344 | 344 |
| 345 // The context must be locked since changing the buffer can re-configure the
number of channels that are output. | 345 // The context must be locked since changing the buffer can re-configure the
number of channels that are output. |
| 346 AbstractAudioContext::AutoLocker contextLocker(context()); | 346 BaseAudioContext::AutoLocker contextLocker(context()); |
| 347 | 347 |
| 348 // This synchronizes with process(). | 348 // This synchronizes with process(). |
| 349 MutexLocker processLocker(m_processLock); | 349 MutexLocker processLocker(m_processLock); |
| 350 | 350 |
| 351 if (buffer) { | 351 if (buffer) { |
| 352 // Do any necesssary re-configuration to the buffer's number of channels
. | 352 // Do any necesssary re-configuration to the buffer's number of channels
. |
| 353 unsigned numberOfChannels = buffer->numberOfChannels(); | 353 unsigned numberOfChannels = buffer->numberOfChannels(); |
| 354 | 354 |
| 355 // This should not be possible since AudioBuffers can't be created with
too many channels | 355 // This should not be possible since AudioBuffers can't be created with
too many channels |
| 356 // either. | 356 // either. |
| 357 if (numberOfChannels > AbstractAudioContext::maxNumberOfChannels()) { | 357 if (numberOfChannels > BaseAudioContext::maxNumberOfChannels()) { |
| 358 exceptionState.throwDOMException( | 358 exceptionState.throwDOMException( |
| 359 NotSupportedError, | 359 NotSupportedError, |
| 360 ExceptionMessages::indexOutsideRange( | 360 ExceptionMessages::indexOutsideRange( |
| 361 "number of input channels", | 361 "number of input channels", |
| 362 numberOfChannels, | 362 numberOfChannels, |
| 363 1u, | 363 1u, |
| 364 ExceptionMessages::InclusiveBound, | 364 ExceptionMessages::InclusiveBound, |
| 365 AbstractAudioContext::maxNumberOfChannels(), | 365 BaseAudioContext::maxNumberOfChannels(), |
| 366 ExceptionMessages::InclusiveBound)); | 366 ExceptionMessages::InclusiveBound)); |
| 367 return; | 367 return; |
| 368 } | 368 } |
| 369 | 369 |
| 370 output(0).setNumberOfChannels(numberOfChannels); | 370 output(0).setNumberOfChannels(numberOfChannels); |
| 371 | 371 |
| 372 m_sourceChannels = adoptArrayPtr(new const float* [numberOfChannels]); | 372 m_sourceChannels = adoptArrayPtr(new const float* [numberOfChannels]); |
| 373 m_destinationChannels = adoptArrayPtr(new float* [numberOfChannels]); | 373 m_destinationChannels = adoptArrayPtr(new float* [numberOfChannels]); |
| 374 | 374 |
| 375 for (unsigned i = 0; i < numberOfChannels; ++i) | 375 for (unsigned i = 0; i < numberOfChannels; ++i) |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 m_startTime = std::max(when, context()->currentTime()); | 498 m_startTime = std::max(when, context()->currentTime()); |
| 499 | 499 |
| 500 if (buffer()) | 500 if (buffer()) |
| 501 clampGrainParameters(buffer()); | 501 clampGrainParameters(buffer()); |
| 502 | 502 |
| 503 setPlaybackState(SCHEDULED_STATE); | 503 setPlaybackState(SCHEDULED_STATE); |
| 504 } | 504 } |
| 505 | 505 |
| 506 double AudioBufferSourceHandler::computePlaybackRate() | 506 double AudioBufferSourceHandler::computePlaybackRate() |
| 507 { | 507 { |
| 508 // Incorporate buffer's sample-rate versus AbstractAudioContext's sample-rat
e. | 508 // Incorporate buffer's sample-rate versus BaseAudioContext's sample-rate. |
| 509 // Normally it's not an issue because buffers are loaded at the | 509 // Normally it's not an issue because buffers are loaded at the |
| 510 // AbstractAudioContext's sample-rate, but we can handle it in any case. | 510 // BaseAudioContext's sample-rate, but we can handle it in any case. |
| 511 double sampleRateFactor = 1.0; | 511 double sampleRateFactor = 1.0; |
| 512 if (buffer()) { | 512 if (buffer()) { |
| 513 // Use doubles to compute this to full accuracy. | 513 // Use doubles to compute this to full accuracy. |
| 514 sampleRateFactor = buffer()->sampleRate() / static_cast<double>(sampleRa
te()); | 514 sampleRateFactor = buffer()->sampleRate() / static_cast<double>(sampleRa
te()); |
| 515 } | 515 } |
| 516 | 516 |
| 517 // Use finalValue() to incorporate changes of AudioParamTimeline and | 517 // Use finalValue() to incorporate changes of AudioParamTimeline and |
| 518 // AudioSummingJunction from m_playbackRate AudioParam. | 518 // AudioSummingJunction from m_playbackRate AudioParam. |
| 519 double basePlaybackRate = m_playbackRate->finalValue(); | 519 double basePlaybackRate = m_playbackRate->finalValue(); |
| 520 | 520 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 if (context()->currentTime() > stopTime) { | 574 if (context()->currentTime() > stopTime) { |
| 575 // The context time has passed the time when the source nodes should
have stopped | 575 // The context time has passed the time when the source nodes should
have stopped |
| 576 // playing. Stop the node now and deref it. (But don't run the onEnd
ed event because the | 576 // playing. Stop the node now and deref it. (But don't run the onEnd
ed event because the |
| 577 // source never actually played.) | 577 // source never actually played.) |
| 578 finishWithoutOnEnded(); | 578 finishWithoutOnEnded(); |
| 579 } | 579 } |
| 580 } | 580 } |
| 581 } | 581 } |
| 582 | 582 |
| 583 // ---------------------------------------------------------------- | 583 // ---------------------------------------------------------------- |
| 584 AudioBufferSourceNode::AudioBufferSourceNode(AbstractAudioContext& context, floa
t sampleRate) | 584 AudioBufferSourceNode::AudioBufferSourceNode(BaseAudioContext& context, float sa
mpleRate) |
| 585 : AudioScheduledSourceNode(context) | 585 : AudioScheduledSourceNode(context) |
| 586 , m_playbackRate(AudioParam::create(context, 1.0)) | 586 , m_playbackRate(AudioParam::create(context, 1.0)) |
| 587 , m_detune(AudioParam::create(context, 0.0)) | 587 , m_detune(AudioParam::create(context, 0.0)) |
| 588 { | 588 { |
| 589 setHandler(AudioBufferSourceHandler::create(*this, sampleRate, m_playbackRat
e->handler(), m_detune->handler())); | 589 setHandler(AudioBufferSourceHandler::create(*this, sampleRate, m_playbackRat
e->handler(), m_detune->handler())); |
| 590 } | 590 } |
| 591 | 591 |
| 592 AudioBufferSourceNode* AudioBufferSourceNode::create(AbstractAudioContext& conte
xt, float sampleRate) | 592 AudioBufferSourceNode* AudioBufferSourceNode::create(BaseAudioContext& context,
float sampleRate) |
| 593 { | 593 { |
| 594 return new AudioBufferSourceNode(context, sampleRate); | 594 return new AudioBufferSourceNode(context, sampleRate); |
| 595 } | 595 } |
| 596 | 596 |
| 597 DEFINE_TRACE(AudioBufferSourceNode) | 597 DEFINE_TRACE(AudioBufferSourceNode) |
| 598 { | 598 { |
| 599 visitor->trace(m_playbackRate); | 599 visitor->trace(m_playbackRate); |
| 600 visitor->trace(m_detune); | 600 visitor->trace(m_detune); |
| 601 AudioScheduledSourceNode::trace(visitor); | 601 AudioScheduledSourceNode::trace(visitor); |
| 602 } | 602 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 { | 670 { |
| 671 audioBufferSourceHandler().start(when, grainOffset, exceptionState); | 671 audioBufferSourceHandler().start(when, grainOffset, exceptionState); |
| 672 } | 672 } |
| 673 | 673 |
| 674 void AudioBufferSourceNode::start(double when, double grainOffset, double grainD
uration, ExceptionState& exceptionState) | 674 void AudioBufferSourceNode::start(double when, double grainOffset, double grainD
uration, ExceptionState& exceptionState) |
| 675 { | 675 { |
| 676 audioBufferSourceHandler().start(when, grainOffset, grainDuration, exception
State); | 676 audioBufferSourceHandler().start(when, grainOffset, grainDuration, exception
State); |
| 677 } | 677 } |
| 678 | 678 |
| 679 } // namespace blink | 679 } // namespace blink |
| OLD | NEW |