| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 initialize(); | 72 initialize(); |
| 73 } | 73 } |
| 74 | 74 |
| 75 PassRefPtr<AudioBufferSourceHandler> AudioBufferSourceHandler::create(AudioNode&
node, float sampleRate, AudioParamHandler& playbackRate, AudioParamHandler& det
une) | 75 PassRefPtr<AudioBufferSourceHandler> AudioBufferSourceHandler::create(AudioNode&
node, float sampleRate, AudioParamHandler& playbackRate, AudioParamHandler& det
une) |
| 76 { | 76 { |
| 77 return adoptRef(new AudioBufferSourceHandler(node, sampleRate, playbackRate,
detune)); | 77 return adoptRef(new AudioBufferSourceHandler(node, sampleRate, playbackRate,
detune)); |
| 78 } | 78 } |
| 79 | 79 |
| 80 AudioBufferSourceHandler::~AudioBufferSourceHandler() | 80 AudioBufferSourceHandler::~AudioBufferSourceHandler() |
| 81 { | 81 { |
| 82 clearPannerNode(); | |
| 83 uninitialize(); | 82 uninitialize(); |
| 84 } | 83 } |
| 85 | 84 |
| 86 void AudioBufferSourceHandler::process(size_t framesToProcess) | 85 void AudioBufferSourceHandler::process(size_t framesToProcess) |
| 87 { | 86 { |
| 88 AudioBus* outputBus = output(0).bus(); | 87 AudioBus* outputBus = output(0).bus(); |
| 89 | 88 |
| 90 if (!isInitialized()) { | 89 if (!isInitialized()) { |
| 91 outputBus->zero(); | 90 outputBus->zero(); |
| 92 return; | 91 return; |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 m_startTime = std::max(when, context()->currentTime()); | 499 m_startTime = std::max(when, context()->currentTime()); |
| 501 | 500 |
| 502 if (buffer()) | 501 if (buffer()) |
| 503 clampGrainParameters(buffer()); | 502 clampGrainParameters(buffer()); |
| 504 | 503 |
| 505 setPlaybackState(SCHEDULED_STATE); | 504 setPlaybackState(SCHEDULED_STATE); |
| 506 } | 505 } |
| 507 | 506 |
| 508 double AudioBufferSourceHandler::computePlaybackRate() | 507 double AudioBufferSourceHandler::computePlaybackRate() |
| 509 { | 508 { |
| 510 double dopplerRate = 1; | |
| 511 if (m_pannerNode) | |
| 512 dopplerRate = m_pannerNode->dopplerRate(); | |
| 513 | |
| 514 // Incorporate buffer's sample-rate versus AbstractAudioContext's sample-rat
e. | 509 // Incorporate buffer's sample-rate versus AbstractAudioContext's sample-rat
e. |
| 515 // Normally it's not an issue because buffers are loaded at the | 510 // Normally it's not an issue because buffers are loaded at the |
| 516 // AbstractAudioContext's sample-rate, but we can handle it in any case. | 511 // AbstractAudioContext's sample-rate, but we can handle it in any case. |
| 517 double sampleRateFactor = 1.0; | 512 double sampleRateFactor = 1.0; |
| 518 if (buffer()) { | 513 if (buffer()) { |
| 519 // Use doubles to compute this to full accuracy. | 514 // Use doubles to compute this to full accuracy. |
| 520 sampleRateFactor = buffer()->sampleRate() / static_cast<double>(sampleRa
te()); | 515 sampleRateFactor = buffer()->sampleRate() / static_cast<double>(sampleRa
te()); |
| 521 } | 516 } |
| 522 | 517 |
| 523 // Use finalValue() to incorporate changes of AudioParamTimeline and | 518 // Use finalValue() to incorporate changes of AudioParamTimeline and |
| 524 // AudioSummingJunction from m_playbackRate AudioParam. | 519 // AudioSummingJunction from m_playbackRate AudioParam. |
| 525 double basePlaybackRate = m_playbackRate->finalValue(); | 520 double basePlaybackRate = m_playbackRate->finalValue(); |
| 526 | 521 |
| 527 double finalPlaybackRate = dopplerRate * sampleRateFactor * basePlaybackRate
; | 522 double finalPlaybackRate = sampleRateFactor * basePlaybackRate; |
| 528 | 523 |
| 529 // Take the detune value into account for the final playback rate. | 524 // Take the detune value into account for the final playback rate. |
| 530 finalPlaybackRate *= pow(2, m_detune->finalValue() / 1200); | 525 finalPlaybackRate *= pow(2, m_detune->finalValue() / 1200); |
| 531 | 526 |
| 532 // Sanity check the total rate. It's very important that the resampler not | 527 // Sanity check the total rate. It's very important that the resampler not |
| 533 // get any bad rate values. | 528 // get any bad rate values. |
| 534 finalPlaybackRate = clampTo(finalPlaybackRate, 0.0, MaxRate); | 529 finalPlaybackRate = clampTo(finalPlaybackRate, 0.0, MaxRate); |
| 535 | 530 |
| 536 bool isPlaybackRateValid = !std::isnan(finalPlaybackRate) && !std::isinf(fin
alPlaybackRate); | 531 bool isPlaybackRateValid = !std::isnan(finalPlaybackRate) && !std::isinf(fin
alPlaybackRate); |
| 537 ASSERT(isPlaybackRateValid); | 532 ASSERT(isPlaybackRateValid); |
| 538 | 533 |
| 539 if (!isPlaybackRateValid) | 534 if (!isPlaybackRateValid) |
| 540 finalPlaybackRate = 1.0; | 535 finalPlaybackRate = 1.0; |
| 541 | 536 |
| 542 // Record the minimum playback rate for use by handleStoppableSourceNode. | 537 // Record the minimum playback rate for use by handleStoppableSourceNode. |
| 543 m_minPlaybackRate = std::min(finalPlaybackRate, m_minPlaybackRate); | 538 m_minPlaybackRate = std::min(finalPlaybackRate, m_minPlaybackRate); |
| 544 | 539 |
| 545 return finalPlaybackRate; | 540 return finalPlaybackRate; |
| 546 } | 541 } |
| 547 | 542 |
| 548 bool AudioBufferSourceHandler::propagatesSilence() const | 543 bool AudioBufferSourceHandler::propagatesSilence() const |
| 549 { | 544 { |
| 550 return !isPlayingOrScheduled() || hasFinished() || !m_buffer; | 545 return !isPlayingOrScheduled() || hasFinished() || !m_buffer; |
| 551 } | 546 } |
| 552 | 547 |
| 553 void AudioBufferSourceHandler::setPannerNode(PannerHandler* pannerNode) | |
| 554 { | |
| 555 if (m_pannerNode != pannerNode && !hasFinished()) { | |
| 556 RefPtr<PannerHandler> oldPannerNode(m_pannerNode.release()); | |
| 557 m_pannerNode = pannerNode; | |
| 558 if (pannerNode) | |
| 559 pannerNode->makeConnection(); | |
| 560 if (oldPannerNode) | |
| 561 oldPannerNode->breakConnection(); | |
| 562 } | |
| 563 } | |
| 564 | |
| 565 void AudioBufferSourceHandler::clearPannerNode() | |
| 566 { | |
| 567 if (m_pannerNode) { | |
| 568 m_pannerNode->breakConnection(); | |
| 569 m_pannerNode.clear(); | |
| 570 } | |
| 571 } | |
| 572 | |
| 573 void AudioBufferSourceHandler::handleStoppableSourceNode() | 548 void AudioBufferSourceHandler::handleStoppableSourceNode() |
| 574 { | 549 { |
| 575 // If the source node is not looping, and we have a buffer, we can determine
when the source | 550 // If the source node is not looping, and we have a buffer, we can determine
when the source |
| 576 // would stop playing. This is intended to handle the (uncommon) scenario w
here start() has | 551 // would stop playing. This is intended to handle the (uncommon) scenario w
here start() has |
| 577 // been called but is never connected to the destination (directly or indire
ctly). By stopping | 552 // been called but is never connected to the destination (directly or indire
ctly). By stopping |
| 578 // the node, the node can be collected. Otherwise, the node will never get
collected, leaking | 553 // the node, the node can be collected. Otherwise, the node will never get
collected, leaking |
| 579 // memory. | 554 // memory. |
| 580 // | 555 // |
| 581 // If looping was ever done (m_didSetLooping = true), give up. We can't eas
ily determine how | 556 // If looping was ever done (m_didSetLooping = true), give up. We can't eas
ily determine how |
| 582 // long we looped so we don't know the actual duration thus far, so don't tr
y to do anything | 557 // long we looped so we don't know the actual duration thus far, so don't tr
y to do anything |
| (...skipping 16 matching lines...) Expand all Loading... |
| 599 stopTime += extraStopTime; | 574 stopTime += extraStopTime; |
| 600 if (context()->currentTime() > stopTime) { | 575 if (context()->currentTime() > stopTime) { |
| 601 // The context time has passed the time when the source nodes should
have stopped | 576 // The context time has passed the time when the source nodes should
have stopped |
| 602 // playing. Stop the node now and deref it. (But don't run the onEnd
ed event because the | 577 // playing. Stop the node now and deref it. (But don't run the onEnd
ed event because the |
| 603 // source never actually played.) | 578 // source never actually played.) |
| 604 finishWithoutOnEnded(); | 579 finishWithoutOnEnded(); |
| 605 } | 580 } |
| 606 } | 581 } |
| 607 } | 582 } |
| 608 | 583 |
| 609 void AudioBufferSourceHandler::finish() | |
| 610 { | |
| 611 clearPannerNode(); | |
| 612 ASSERT(!m_pannerNode); | |
| 613 AudioScheduledSourceHandler::finish(); | |
| 614 } | |
| 615 | |
| 616 // ---------------------------------------------------------------- | 584 // ---------------------------------------------------------------- |
| 617 AudioBufferSourceNode::AudioBufferSourceNode(AbstractAudioContext& context, floa
t sampleRate) | 585 AudioBufferSourceNode::AudioBufferSourceNode(AbstractAudioContext& context, floa
t sampleRate) |
| 618 : AudioScheduledSourceNode(context) | 586 : AudioScheduledSourceNode(context) |
| 619 , m_playbackRate(AudioParam::create(context, 1.0)) | 587 , m_playbackRate(AudioParam::create(context, 1.0)) |
| 620 , m_detune(AudioParam::create(context, 0.0)) | 588 , m_detune(AudioParam::create(context, 0.0)) |
| 621 { | 589 { |
| 622 setHandler(AudioBufferSourceHandler::create(*this, sampleRate, m_playbackRat
e->handler(), m_detune->handler())); | 590 setHandler(AudioBufferSourceHandler::create(*this, sampleRate, m_playbackRat
e->handler(), m_detune->handler())); |
| 623 } | 591 } |
| 624 | 592 |
| 625 AudioBufferSourceNode* AudioBufferSourceNode::create(AbstractAudioContext& conte
xt, float sampleRate) | 593 AudioBufferSourceNode* AudioBufferSourceNode::create(AbstractAudioContext& conte
xt, float sampleRate) |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 { | 671 { |
| 704 audioBufferSourceHandler().start(when, grainOffset, exceptionState); | 672 audioBufferSourceHandler().start(when, grainOffset, exceptionState); |
| 705 } | 673 } |
| 706 | 674 |
| 707 void AudioBufferSourceNode::start(double when, double grainOffset, double grainD
uration, ExceptionState& exceptionState) | 675 void AudioBufferSourceNode::start(double when, double grainOffset, double grainD
uration, ExceptionState& exceptionState) |
| 708 { | 676 { |
| 709 audioBufferSourceHandler().start(when, grainOffset, grainDuration, exception
State); | 677 audioBufferSourceHandler().start(when, grainOffset, grainDuration, exception
State); |
| 710 } | 678 } |
| 711 | 679 |
| 712 } // namespace blink | 680 } // namespace blink |
| 713 | |
| OLD | NEW |