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 |