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 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 // get any bad rate values. | 583 // get any bad rate values. |
584 final_playback_rate = clampTo(final_playback_rate, 0.0, kMaxRate); | 584 final_playback_rate = clampTo(final_playback_rate, 0.0, kMaxRate); |
585 | 585 |
586 bool is_playback_rate_valid = | 586 bool is_playback_rate_valid = |
587 !std::isnan(final_playback_rate) && !std::isinf(final_playback_rate); | 587 !std::isnan(final_playback_rate) && !std::isinf(final_playback_rate); |
588 DCHECK(is_playback_rate_valid); | 588 DCHECK(is_playback_rate_valid); |
589 | 589 |
590 if (!is_playback_rate_valid) | 590 if (!is_playback_rate_valid) |
591 final_playback_rate = 1.0; | 591 final_playback_rate = 1.0; |
592 | 592 |
593 // Record the minimum playback rate for use by handleStoppableSourceNode. | 593 // Record the minimum playback rate for use by HandleStoppableSourceNode. |
594 min_playback_rate_ = std::min(final_playback_rate, min_playback_rate_); | 594 if (final_playback_rate < min_playback_rate_) { |
| 595 MutexLocker locker(min_playback_rate_mutex_); |
| 596 min_playback_rate_ = final_playback_rate; |
| 597 } |
595 | 598 |
596 return final_playback_rate; | 599 return final_playback_rate; |
597 } | 600 } |
598 | 601 |
| 602 double AudioBufferSourceHandler::GetMinPlaybackRate() { |
| 603 DCHECK(IsMainThread()); |
| 604 MutexLocker locker(min_playback_rate_mutex_); |
| 605 return min_playback_rate_; |
| 606 } |
| 607 |
599 bool AudioBufferSourceHandler::PropagatesSilence() const { | 608 bool AudioBufferSourceHandler::PropagatesSilence() const { |
600 return !IsPlayingOrScheduled() || HasFinished() || !buffer_; | 609 return !IsPlayingOrScheduled() || HasFinished() || !buffer_; |
601 } | 610 } |
602 | 611 |
603 void AudioBufferSourceHandler::HandleStoppableSourceNode() { | 612 void AudioBufferSourceHandler::HandleStoppableSourceNode() { |
604 // If the source node is not looping, and we have a buffer, we can determine | 613 // If the source node is not looping, and we have a buffer, we can determine |
605 // when the source would stop playing. This is intended to handle the | 614 // when the source would stop playing. This is intended to handle the |
606 // (uncommon) scenario where start() has been called but is never connected to | 615 // (uncommon) scenario where start() has been called but is never connected to |
607 // the destination (directly or indirectly). By stopping the node, the node | 616 // the destination (directly or indirectly). By stopping the node, the node |
608 // can be collected. Otherwise, the node will never get collected, leaking | 617 // can be collected. Otherwise, the node will never get collected, leaking |
609 // memory. | 618 // memory. |
610 // | 619 // |
611 // If looping was ever done (m_didSetLooping = true), give up. We can't | 620 // If looping was ever done (m_didSetLooping = true), give up. We can't |
612 // easily determine how long we looped so we don't know the actual duration | 621 // easily determine how long we looped so we don't know the actual duration |
613 // thus far, so don't try to do anything fancy. | 622 // thus far, so don't try to do anything fancy. |
| 623 double min_playback_rate = GetMinPlaybackRate(); |
614 if (!DidSetLooping() && Buffer() && IsPlayingOrScheduled() && | 624 if (!DidSetLooping() && Buffer() && IsPlayingOrScheduled() && |
615 min_playback_rate_ > 0) { | 625 min_playback_rate > 0) { |
616 // Adjust the duration to include the playback rate. Only need to account | 626 // Adjust the duration to include the playback rate. Only need to account |
617 // for rate < 1 which makes the sound last longer. For rate >= 1, the | 627 // for rate < 1 which makes the sound last longer. For rate >= 1, the |
618 // source stops sooner, but that's ok. | 628 // source stops sooner, but that's ok. |
619 double actual_duration = Buffer()->duration() / min_playback_rate_; | 629 double actual_duration = Buffer()->duration() / min_playback_rate; |
620 | 630 |
621 double stop_time = start_time_ + actual_duration; | 631 double stop_time = start_time_ + actual_duration; |
622 | 632 |
623 // See crbug.com/478301. If a source node is started via start(), the source | 633 // See crbug.com/478301. If a source node is started via start(), the source |
624 // may not start at that time but one quantum (128 frames) later. But we | 634 // may not start at that time but one quantum (128 frames) later. But we |
625 // compute the stop time based on the start time and the duration, so we end | 635 // compute the stop time based on the start time and the duration, so we end |
626 // up stopping one quantum early. Thus, add a little extra time; we just | 636 // up stopping one quantum early. Thus, add a little extra time; we just |
627 // need to stop the source sometime after it should have stopped if it | 637 // need to stop the source sometime after it should have stopped if it |
628 // hadn't already. We don't need to be super precise on when to stop. | 638 // hadn't already. We don't need to be super precise on when to stop. |
629 double extra_stop_time = | 639 double extra_stop_time = |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 | 766 |
757 void AudioBufferSourceNode::start(double when, | 767 void AudioBufferSourceNode::start(double when, |
758 double grain_offset, | 768 double grain_offset, |
759 double grain_duration, | 769 double grain_duration, |
760 ExceptionState& exception_state) { | 770 ExceptionState& exception_state) { |
761 GetAudioBufferSourceHandler().Start(when, grain_offset, grain_duration, | 771 GetAudioBufferSourceHandler().Start(when, grain_offset, grain_duration, |
762 exception_state); | 772 exception_state); |
763 } | 773 } |
764 | 774 |
765 } // namespace blink | 775 } // namespace blink |
OLD | NEW |