| 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 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 namespace blink { | 41 namespace blink { |
| 42 | 42 |
| 43 const double DefaultGrainDuration = 0.020; // 20ms | 43 const double DefaultGrainDuration = 0.020; // 20ms |
| 44 | 44 |
| 45 // Arbitrary upper limit on playback rate. | 45 // Arbitrary upper limit on playback rate. |
| 46 // Higher than expected rates can be useful when playing back oversampled buffer
s | 46 // Higher than expected rates can be useful when playing back oversampled buffer
s |
| 47 // to minimize linear interpolation aliasing. | 47 // to minimize linear interpolation aliasing. |
| 48 const double MaxRate = 1024; | 48 const double MaxRate = 1024; |
| 49 | 49 |
| 50 // Number of extra frames to use when determining if a source node can be stoppe
d. This should be |
| 51 // at least one rendering quantum, but we add one more quantum for good measure.
This doesn't need |
| 52 // to be extra precise, just more than one rendering quantum. See |handleStoppa
bleSourceNode()|. |
| 53 // FIXME: Expose the rendering quantum somehow instead of hardwiring a value her
e. |
| 54 const int kExtraStopFrames = 256; |
| 55 |
| 50 AudioBufferSourceHandler::AudioBufferSourceHandler(AudioNode& node, float sample
Rate, AudioParamHandler& playbackRate, AudioParamHandler& detune) | 56 AudioBufferSourceHandler::AudioBufferSourceHandler(AudioNode& node, float sample
Rate, AudioParamHandler& playbackRate, AudioParamHandler& detune) |
| 51 : AudioScheduledSourceHandler(NodeTypeAudioBufferSource, node, sampleRate) | 57 : AudioScheduledSourceHandler(NodeTypeAudioBufferSource, node, sampleRate) |
| 52 , m_buffer(nullptr) | 58 , m_buffer(nullptr) |
| 53 , m_playbackRate(playbackRate) | 59 , m_playbackRate(playbackRate) |
| 54 , m_detune(detune) | 60 , m_detune(detune) |
| 55 , m_isLooping(false) | 61 , m_isLooping(false) |
| 56 , m_loopStart(0) | 62 , m_loopStart(0) |
| 57 , m_loopEnd(0) | 63 , m_loopEnd(0) |
| 58 , m_virtualReadIndex(0) | 64 , m_virtualReadIndex(0) |
| 59 , m_isGrain(false) | 65 , m_isGrain(false) |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 double AudioBufferSourceHandler::computePlaybackRate() | 489 double AudioBufferSourceHandler::computePlaybackRate() |
| 484 { | 490 { |
| 485 double dopplerRate = 1; | 491 double dopplerRate = 1; |
| 486 if (m_pannerNode) | 492 if (m_pannerNode) |
| 487 dopplerRate = m_pannerNode->dopplerRate(); | 493 dopplerRate = m_pannerNode->dopplerRate(); |
| 488 | 494 |
| 489 // Incorporate buffer's sample-rate versus AudioContext's sample-rate. | 495 // Incorporate buffer's sample-rate versus AudioContext's sample-rate. |
| 490 // Normally it's not an issue because buffers are loaded at the | 496 // Normally it's not an issue because buffers are loaded at the |
| 491 // AudioContext's sample-rate, but we can handle it in any case. | 497 // AudioContext's sample-rate, but we can handle it in any case. |
| 492 double sampleRateFactor = 1.0; | 498 double sampleRateFactor = 1.0; |
| 493 if (buffer()) | 499 if (buffer()) { |
| 494 sampleRateFactor = buffer()->sampleRate() / sampleRate(); | 500 // Use doubles to compute this to full accuracy. |
| 501 sampleRateFactor = buffer()->sampleRate() / static_cast<double>(sampleRa
te()); |
| 502 } |
| 495 | 503 |
| 496 // Use finalValue() to incorporate changes of AudioParamTimeline and | 504 // Use finalValue() to incorporate changes of AudioParamTimeline and |
| 497 // AudioSummingJunction from m_playbackRate AudioParam. | 505 // AudioSummingJunction from m_playbackRate AudioParam. |
| 498 double basePlaybackRate = m_playbackRate->finalValue(); | 506 double basePlaybackRate = m_playbackRate->finalValue(); |
| 499 | 507 |
| 500 double finalPlaybackRate = dopplerRate * sampleRateFactor * basePlaybackRate
; | 508 double finalPlaybackRate = dopplerRate * sampleRateFactor * basePlaybackRate
; |
| 501 | 509 |
| 502 // Take the detune value into account for the final playback rate. | 510 // Take the detune value into account for the final playback rate. |
| 503 finalPlaybackRate *= pow(2, m_detune->finalValue() / 1200); | 511 finalPlaybackRate *= pow(2, m_detune->finalValue() / 1200); |
| 504 | 512 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 535 void AudioBufferSourceHandler::clearPannerNode() | 543 void AudioBufferSourceHandler::clearPannerNode() |
| 536 { | 544 { |
| 537 if (m_pannerNode) { | 545 if (m_pannerNode) { |
| 538 m_pannerNode->breakConnection(); | 546 m_pannerNode->breakConnection(); |
| 539 m_pannerNode.clear(); | 547 m_pannerNode.clear(); |
| 540 } | 548 } |
| 541 } | 549 } |
| 542 | 550 |
| 543 void AudioBufferSourceHandler::handleStoppableSourceNode() | 551 void AudioBufferSourceHandler::handleStoppableSourceNode() |
| 544 { | 552 { |
| 545 // If the source node is not looping, and we have a buffer, we can determine
when the | 553 // If the source node is not looping, and we have a buffer, we can determine
when the source |
| 546 // source would stop playing. | 554 // would stop playing. This is intended to handle the (uncommon) scenario w
here start() has |
| 555 // been called but is never connected to the destination (directly or indire
ctly). By stopping |
| 556 // the node, the node can be collected. Otherwise, the node will never get
collected, leaking |
| 557 // memory. |
| 547 if (!loop() && buffer() && isPlayingOrScheduled()) { | 558 if (!loop() && buffer() && isPlayingOrScheduled()) { |
| 548 double stopTime = m_startTime + buffer()->duration(); | 559 // See crbug.com/478301. If a source node is started via start(), the so
urce may not start |
| 560 // at that time but one quantum (128 frames) later. But we compute the
stop time based on |
| 561 // the start time and the duration, so we end up stopping one quantum ea
rly. Thus, add a |
| 562 // little extra time; we just need to stop the source sometime after it
should have stopped |
| 563 // if it hadn't already. We don't need to be super precise on when to s
top. |
| 564 double extraStopTime = kExtraStopFrames / static_cast<double>(context()-
>sampleRate()); |
| 565 double stopTime = m_startTime + buffer()->duration() + extraStopTime; |
| 566 |
| 549 if (context()->currentTime() > stopTime) { | 567 if (context()->currentTime() > stopTime) { |
| 550 // The context time has passed the time when the source nodes should
have stopped | 568 // The context time has passed the time when the source nodes should
have stopped |
| 551 // playing. Stop the node now and deref it. (But don't run the onEnd
ed event because the | 569 // playing. Stop the node now and deref it. (But don't run the onEnd
ed event because the |
| 552 // source never actually played.) | 570 // source never actually played.) |
| 553 finishWithoutOnEnded(); | 571 finishWithoutOnEnded(); |
| 554 } | 572 } |
| 555 } | 573 } |
| 556 } | 574 } |
| 557 | 575 |
| 558 void AudioBufferSourceHandler::finish() | 576 void AudioBufferSourceHandler::finish() |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 } | 672 } |
| 655 | 673 |
| 656 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) |
| 657 { | 675 { |
| 658 audioBufferSourceHandler().start(when, grainOffset, grainDuration, exception
State); | 676 audioBufferSourceHandler().start(when, grainOffset, grainDuration, exception
State); |
| 659 } | 677 } |
| 660 | 678 |
| 661 } // namespace blink | 679 } // namespace blink |
| 662 | 680 |
| 663 #endif // ENABLE(WEB_AUDIO) | 681 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |