コード例 #1
0
void AudioBufferSourceHandler::handleStoppableSourceNode()
{
    // If the source node is not looping, and we have a buffer, we can determine when the source
    // would stop playing.  This is intended to handle the (uncommon) scenario where start() has
    // been called but is never connected to the destination (directly or indirectly).  By stopping
    // the node, the node can be collected.  Otherwise, the node will never get collected, leaking
    // memory.
    //
    // If looping was ever done (m_didSetLooping = true), give up.  We can't easily determine how
    // long we looped so we don't know the actual duration thus far, so don't try to do anything
    // fancy.
    if (!m_didSetLooping && buffer() && isPlayingOrScheduled() && m_minPlaybackRate > 0) {
        // Adjust the duration to include the playback rate. Only need to account for rate < 1
        // which makes the sound last longer.  For rate >= 1, the source stops sooner, but that's
        // ok.
        double actualDuration = buffer()->duration() / m_minPlaybackRate;

        double stopTime = m_startTime + actualDuration;

        // See crbug.com/478301. If a source node is started via start(), the source may not start
        // at that time but one quantum (128 frames) later.  But we compute the stop time based on
        // the start time and the duration, so we end up stopping one quantum early.  Thus, add a
        // little extra time; we just need to stop the source sometime after it should have stopped
        // if it hadn't already.  We don't need to be super precise on when to stop.
        double extraStopTime = kExtraStopFrames / static_cast<double>(context()->sampleRate());

        stopTime += extraStopTime;
        if (context()->currentTime() > stopTime) {
            // The context time has passed the time when the source nodes should have stopped
            // playing. Stop the node now and deref it. (But don't run the onEnded event because the
            // source never actually played.)
            finishWithoutOnEnded();
        }
    }
}
コード例 #2
0
void AudioScheduledSourceHandler::finish()
{
    finishWithoutOnEnded();

    if (m_hasEndedListener && context()->executionContext()) {
        context()->executionContext()->postTask(FROM_HERE, createCrossThreadTask(&AudioScheduledSourceHandler::notifyEnded, PassRefPtr<AudioScheduledSourceHandler>(this)));
    }
}
コード例 #3
0
void AudioScheduledSourceHandler::finish() {
  finishWithoutOnEnded();

  if (context()->getExecutionContext()) {
    context()->getExecutionContext()->postTask(
        BLINK_FROM_HERE,
        createCrossThreadTask(&AudioScheduledSourceHandler::notifyEnded,
                              PassRefPtr<AudioScheduledSourceHandler>(this)));
  }
}