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

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: Update according to review 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
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) 56 AudioBufferSourceHandler::AudioBufferSourceHandler(AudioNode& node, float sample Rate, AudioParamHandler& playbackRate)
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_isLooping(false) 60 , m_isLooping(false)
55 , m_loopStart(0) 61 , m_loopStart(0)
56 , m_loopEnd(0) 62 , m_loopEnd(0)
57 , m_virtualReadIndex(0) 63 , m_virtualReadIndex(0)
58 , m_isGrain(false) 64 , m_isGrain(false)
59 , m_grainOffset(0.0) 65 , m_grainOffset(0.0)
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 double AudioBufferSourceHandler::computePlaybackRate() 488 double AudioBufferSourceHandler::computePlaybackRate()
483 { 489 {
484 double dopplerRate = 1.0; 490 double dopplerRate = 1.0;
485 if (m_pannerNode) 491 if (m_pannerNode)
486 dopplerRate = m_pannerNode->dopplerRate(); 492 dopplerRate = m_pannerNode->dopplerRate();
487 493
488 // Incorporate buffer's sample-rate versus AudioContext's sample-rate. 494 // Incorporate buffer's sample-rate versus AudioContext's sample-rate.
489 // Normally it's not an issue because buffers are loaded at the 495 // Normally it's not an issue because buffers are loaded at the
490 // AudioContext's sample-rate, but we can handle it in any case. 496 // AudioContext's sample-rate, but we can handle it in any case.
491 double sampleRateFactor = 1.0; 497 double sampleRateFactor = 1.0;
492 if (buffer()) 498 if (buffer()) {
493 sampleRateFactor = buffer()->sampleRate() / sampleRate(); 499 // Use doubles to compute this to full accuracy.
500 sampleRateFactor = buffer()->sampleRate() / static_cast<double>(sampleRa te());
501 }
494 502
495 // Use finalValue() to incorporate changes of AudioParamTimeline and 503 // Use finalValue() to incorporate changes of AudioParamTimeline and
496 // AudioSummingJunction from m_playbackRate AudioParam. 504 // AudioSummingJunction from m_playbackRate AudioParam.
497 double basePlaybackRate = m_playbackRate->finalValue(); 505 double basePlaybackRate = m_playbackRate->finalValue();
498 506
499 double finalPlaybackRate = dopplerRate * sampleRateFactor * basePlaybackRate ; 507 double finalPlaybackRate = dopplerRate * sampleRateFactor * basePlaybackRate ;
500 508
501 // Sanity check the total rate. It's very important that the resampler not 509 // Sanity check the total rate. It's very important that the resampler not
502 // get any bad rate values. 510 // get any bad rate values.
503 finalPlaybackRate = clampTo(finalPlaybackRate, 0.0, MaxRate); 511 finalPlaybackRate = clampTo(finalPlaybackRate, 0.0, MaxRate);
(...skipping 30 matching lines...) Expand all
534 m_pannerNode->breakConnection(); 542 m_pannerNode->breakConnection();
535 m_pannerNode.clear(); 543 m_pannerNode.clear();
536 } 544 }
537 } 545 }
538 546
539 void AudioBufferSourceHandler::handleStoppableSourceNode() 547 void AudioBufferSourceHandler::handleStoppableSourceNode()
540 { 548 {
541 // If the source node is not looping, and we have a buffer, we can determine when the 549 // If the source node is not looping, and we have a buffer, we can determine when the
542 // source would stop playing. 550 // source would stop playing.
543 if (!loop() && buffer() && isPlayingOrScheduled()) { 551 if (!loop() && buffer() && isPlayingOrScheduled()) {
544 double stopTime = m_startTime + buffer()->duration(); 552 // See crbug.com/478301. If a source node is started via start(), the so urce won't start at
553 // that time but one quantum (128 frames) later. But we compute the sto p time based on the
554 // start time and the duration, so we end up stopping one quantum early. Thus, add a little
555 // extra time; we just need to stop the source sometime after it should have stopped if it
556 // hadn't already.
557 double extraStopTime = kExtraStopFrames / static_cast<double>(context()- >sampleRate());
558 double stopTime = m_startTime + buffer()->duration() + extraStopTime;
Ken Russell (switch to Gerrit) 2015/04/22 19:01:50 This seems like a classic rounding error. Does the
Raymond Toy 2015/04/22 20:19:45 Without this fix, it's the last few frames for the
559
545 if (context()->currentTime() > stopTime) { 560 if (context()->currentTime() > stopTime) {
546 // The context time has passed the time when the source nodes should have stopped 561 // The context time has passed the time when the source nodes should have stopped
547 // playing. Stop the node now and deref it. (But don't run the onEnd ed event because the 562 // playing. Stop the node now and deref it. (But don't run the onEnd ed event because the
548 // source never actually played.) 563 // source never actually played.)
549 finishWithoutOnEnded(); 564 finishWithoutOnEnded();
550 } 565 }
551 } 566 }
552 } 567 }
553 568
554 void AudioBufferSourceHandler::finish() 569 void AudioBufferSourceHandler::finish()
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 } 658 }
644 659
645 void AudioBufferSourceNode::start(double when, double grainOffset, double grainD uration, ExceptionState& exceptionState) 660 void AudioBufferSourceNode::start(double when, double grainOffset, double grainD uration, ExceptionState& exceptionState)
646 { 661 {
647 audioBufferSourceHandler().start(when, grainOffset, grainDuration, exception State); 662 audioBufferSourceHandler().start(when, grainOffset, grainDuration, exception State);
648 } 663 }
649 664
650 } // namespace blink 665 } // namespace blink
651 666
652 #endif // ENABLE(WEB_AUDIO) 667 #endif // ENABLE(WEB_AUDIO)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698