comparison audioio/AudioCallbackPlaySource.cpp @ 94:9cc9862333bd sv1-v1.2pre4

* a hack to try to prevent playback pointer bouncing back when playback starts
author Chris Cannam
date Mon, 11 Feb 2008 17:08:59 +0000
parents 737b373246b5
children e177e6ee7c12
comparison
equal deleted inserted replaced
93:737b373246b5 94:9cc9862333bd
62 m_lastModelEndFrame(0), 62 m_lastModelEndFrame(0),
63 m_outputLeft(0.0), 63 m_outputLeft(0.0),
64 m_outputRight(0.0), 64 m_outputRight(0.0),
65 m_auditioningPlugin(0), 65 m_auditioningPlugin(0),
66 m_auditioningPluginBypassed(false), 66 m_auditioningPluginBypassed(false),
67 m_playStartFrame(0),
68 m_playStartFramePassed(false),
67 m_timeStretcher(0), 69 m_timeStretcher(0),
68 m_stretchRatio(1.0), 70 m_stretchRatio(1.0),
69 m_stretcherInputCount(0), 71 m_stretcherInputCount(0),
70 m_stretcherInputs(0), 72 m_stretcherInputs(0),
71 m_stretcherInputSizes(0), 73 m_stretcherInputSizes(0),
353 AudioCallbackPlaySource::play(size_t startFrame) 355 AudioCallbackPlaySource::play(size_t startFrame)
354 { 356 {
355 if (m_viewManager->getPlaySelectionMode() && 357 if (m_viewManager->getPlaySelectionMode() &&
356 !m_viewManager->getSelections().empty()) { 358 !m_viewManager->getSelections().empty()) {
357 359
360 std::cerr << "AudioCallbackPlaySource::play: constraining frame " << startFrame << " to selection = ";
361
358 startFrame = m_viewManager->constrainFrameToSelection(startFrame); 362 startFrame = m_viewManager->constrainFrameToSelection(startFrame);
363
364 std::cerr << startFrame << std::endl;
359 365
360 } else { 366 } else {
361 if (startFrame >= m_lastModelEndFrame) { 367 if (startFrame >= m_lastModelEndFrame) {
362 startFrame = 0; 368 startFrame = 0;
363 } 369 }
396 } 402 }
397 m_mutex.unlock(); 403 m_mutex.unlock();
398 404
399 m_audioGenerator->reset(); 405 m_audioGenerator->reset();
400 406
407 m_playStartFrame = startFrame;
408 m_playStartFramePassed = false;
409 m_playStartedAt = RealTime::zeroTime;
410 if (m_target) {
411 m_playStartedAt = RealTime::fromSeconds(m_target->getCurrentTime());
412 }
413
401 bool changed = !m_playing; 414 bool changed = !m_playing;
402 m_lastRetrievalTimestamp = 0; 415 m_lastRetrievalTimestamp = 0;
403 m_playing = true; 416 m_playing = true;
404 m_condition.wakeAll(); 417 m_condition.wakeAll();
405 if (changed) emit playStatusChanged(m_playing); 418 if (changed) emit playStatusChanged(m_playing);
629 ++index; 642 ++index;
630 } 643 }
631 644
632 if (inRange >= m_rangeStarts.size()) inRange = m_rangeStarts.size()-1; 645 if (inRange >= m_rangeStarts.size()) inRange = m_rangeStarts.size()-1;
633 646
634 RealTime playing_t = bufferedto_t - m_rangeStarts[inRange]; 647 RealTime playing_t = bufferedto_t;
635 648
636 playing_t = playing_t 649 playing_t = playing_t
637 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t 650 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t
638 + sincerequest_t; 651 + sincerequest_t;
652
653 // This rather gross little hack is used to ensure that latency
654 // compensation doesn't result in the playback pointer appearing
655 // to start earlier than the actual playback does. It doesn't
656 // work properly (hence the bail-out in the middle) because if we
657 // are playing a relatively short looped region, the playing time
658 // estimated from the buffer fill frame may have wrapped around
659 // the region boundary and end up being much smaller than the
660 // theoretical play start frame, perhaps even for the entire
661 // duration of playback!
662
663 if (!m_playStartFramePassed) {
664 RealTime playstart_t = RealTime::frame2RealTime(m_playStartFrame,
665 sourceRate);
666 if (playing_t < playstart_t) {
667 // std::cerr << "playing_t " << playing_t << " < playstart_t "
668 // << playstart_t << std::endl;
669 if (sincerequest_t > RealTime::zeroTime &&
670 m_playStartedAt + latency_t + stretchlat_t <
671 RealTime::fromSeconds(currentTime)) {
672 // std::cerr << "but we've been playing for long enough that I think we should disregard it (it probably results from loop wrapping)" << std::endl;
673 m_playStartFramePassed = true;
674 } else {
675 playing_t = playstart_t;
676 }
677 } else {
678 m_playStartFramePassed = true;
679 }
680 }
681
682 playing_t = playing_t - m_rangeStarts[inRange];
639 683
640 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 684 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
641 std::cerr << "playing_t as offset into range " << inRange << " (with start = " << m_rangeStarts[inRange] << ") = " << playing_t << std::endl; 685 std::cerr << "playing_t as offset into range " << inRange << " (with start = " << m_rangeStarts[inRange] << ") = " << playing_t << std::endl;
642 #endif 686 #endif
643 687