Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Side by Side Diff: Source/modules/webaudio/AudioBufferSourceNode.cpp

Issue 1097373003: Fix issue with failing to call AudioBufferSource.onended in some cases (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase and clarify some comments. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ManualTests/webaudio/audiobuffersource-resampling-onended.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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)
OLDNEW
« no previous file with comments | « ManualTests/webaudio/audiobuffersource-resampling-onended.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698