Mercurial > hg > svapp
comparison audioio/AudioCallbackPlaySource.cpp @ 102:8591a0a3d57e
* Tolerable fixes to #1903062 and #1903046
author | Chris Cannam |
---|---|
date | Wed, 27 Feb 2008 18:04:10 +0000 |
parents | cd5cbdecc82d |
children | 2485f822dc54 |
comparison
equal
deleted
inserted
replaced
99:cd5cbdecc82d | 102:8591a0a3d57e |
---|---|
55 m_targetSampleRate(0), | 55 m_targetSampleRate(0), |
56 m_playLatency(0), | 56 m_playLatency(0), |
57 m_target(0), | 57 m_target(0), |
58 m_lastRetrievalTimestamp(0.0), | 58 m_lastRetrievalTimestamp(0.0), |
59 m_lastRetrievedBlockSize(0), | 59 m_lastRetrievedBlockSize(0), |
60 m_trustworthyTimestamps(true), | |
61 m_lastCurrentFrame(0), | |
60 m_playing(false), | 62 m_playing(false), |
61 m_exiting(false), | 63 m_exiting(false), |
62 m_lastModelEndFrame(0), | 64 m_lastModelEndFrame(0), |
63 m_outputLeft(0.0), | 65 m_outputLeft(0.0), |
64 m_outputRight(0.0), | 66 m_outputRight(0.0), |
377 std::cerr << startFrame << std::endl; | 379 std::cerr << startFrame << std::endl; |
378 | 380 |
379 // The fill thread will automatically empty its buffers before | 381 // The fill thread will automatically empty its buffers before |
380 // starting again if we have not so far been playing, but not if | 382 // starting again if we have not so far been playing, but not if |
381 // we're just re-seeking. | 383 // we're just re-seeking. |
384 // NO -- we can end up playing some first -- always reset here | |
382 | 385 |
383 m_mutex.lock(); | 386 m_mutex.lock(); |
387 | |
384 if (m_timeStretcher) { | 388 if (m_timeStretcher) { |
385 m_timeStretcher->reset(); | 389 m_timeStretcher->reset(); |
386 } | 390 } |
387 if (m_playing) { | 391 |
388 std::cerr << "playing already, resetting" << std::endl; | 392 m_readBufferFill = m_writeBufferFill = startFrame; |
389 m_readBufferFill = m_writeBufferFill = startFrame; | 393 if (m_readBuffers) { |
390 if (m_readBuffers) { | 394 for (size_t c = 0; c < getTargetChannelCount(); ++c) { |
391 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | 395 RingBuffer<float> *rb = getReadRingBuffer(c); |
392 RingBuffer<float> *rb = getReadRingBuffer(c); | 396 std::cerr << "reset ring buffer for channel " << c << std::endl; |
393 std::cerr << "reset ring buffer for channel " << c << std::endl; | 397 if (rb) rb->reset(); |
394 if (rb) rb->reset(); | 398 } |
395 } | 399 } |
396 } | 400 if (m_converter) src_reset(m_converter); |
397 if (m_converter) src_reset(m_converter); | 401 if (m_crapConverter) src_reset(m_crapConverter); |
398 if (m_crapConverter) src_reset(m_crapConverter); | 402 |
399 } else { | |
400 if (m_converter) src_reset(m_converter); | |
401 if (m_crapConverter) src_reset(m_crapConverter); | |
402 m_readBufferFill = m_writeBufferFill = startFrame; | |
403 } | |
404 m_mutex.unlock(); | 403 m_mutex.unlock(); |
405 | 404 |
406 m_audioGenerator->reset(); | 405 m_audioGenerator->reset(); |
407 | 406 |
408 m_playStartFrame = startFrame; | 407 m_playStartFrame = startFrame; |
412 m_playStartedAt = RealTime::fromSeconds(m_target->getCurrentTime()); | 411 m_playStartedAt = RealTime::fromSeconds(m_target->getCurrentTime()); |
413 } | 412 } |
414 | 413 |
415 bool changed = !m_playing; | 414 bool changed = !m_playing; |
416 m_lastRetrievalTimestamp = 0; | 415 m_lastRetrievalTimestamp = 0; |
416 m_lastCurrentFrame = 0; | |
417 m_playing = true; | 417 m_playing = true; |
418 m_condition.wakeAll(); | 418 m_condition.wakeAll(); |
419 if (changed) emit playStatusChanged(m_playing); | 419 if (changed) emit playStatusChanged(m_playing); |
420 } | 420 } |
421 | 421 |
424 { | 424 { |
425 bool changed = m_playing; | 425 bool changed = m_playing; |
426 m_playing = false; | 426 m_playing = false; |
427 m_condition.wakeAll(); | 427 m_condition.wakeAll(); |
428 m_lastRetrievalTimestamp = 0; | 428 m_lastRetrievalTimestamp = 0; |
429 m_lastCurrentFrame = 0; | |
429 if (changed) emit playStatusChanged(m_playing); | 430 if (changed) emit playStatusChanged(m_playing); |
430 } | 431 } |
431 | 432 |
432 void | 433 void |
433 AudioCallbackPlaySource::selectionChanged() | 434 AudioCallbackPlaySource::selectionChanged() |
552 size_t readBufferFill = m_readBufferFill; | 553 size_t readBufferFill = m_readBufferFill; |
553 size_t lastRetrievedBlockSize = m_lastRetrievedBlockSize; | 554 size_t lastRetrievedBlockSize = m_lastRetrievedBlockSize; |
554 double lastRetrievalTimestamp = m_lastRetrievalTimestamp; | 555 double lastRetrievalTimestamp = m_lastRetrievalTimestamp; |
555 double currentTime = 0.0; | 556 double currentTime = 0.0; |
556 if (m_target) currentTime = m_target->getCurrentTime(); | 557 if (m_target) currentTime = m_target->getCurrentTime(); |
558 | |
559 bool looping = m_viewManager->getPlayLoopMode(); | |
557 | 560 |
558 RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, targetRate); | 561 RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, targetRate); |
559 | 562 |
560 size_t stretchlat = 0; | 563 size_t stretchlat = 0; |
561 double timeRatio = 1.0; | 564 double timeRatio = 1.0; |
577 // from being played. | 580 // from being played. |
578 | 581 |
579 RealTime sincerequest_t = RealTime::zeroTime; | 582 RealTime sincerequest_t = RealTime::zeroTime; |
580 RealTime lastretrieved_t = RealTime::zeroTime; | 583 RealTime lastretrieved_t = RealTime::zeroTime; |
581 | 584 |
582 if (m_target && lastRetrievalTimestamp != 0.0) { | 585 if (m_target && |
586 m_trustworthyTimestamps && | |
587 lastRetrievalTimestamp != 0.0) { | |
583 | 588 |
584 lastretrieved_t = RealTime::frame2RealTime | 589 lastretrieved_t = RealTime::frame2RealTime |
585 (lastRetrievedBlockSize, targetRate); | 590 (lastRetrievedBlockSize, targetRate); |
586 | 591 |
587 // calculate number of frames at target rate that have elapsed | 592 // calculate number of frames at target rate that have elapsed |
588 // since the end of the last call to getSourceSamples | 593 // since the end of the last call to getSourceSamples |
589 | 594 |
590 double elapsed = currentTime - lastRetrievalTimestamp; | 595 if (m_trustworthyTimestamps && !looping) { |
591 | 596 |
592 if (elapsed > 0.0) { | 597 // this adjustment seems to cause more problems when looping |
593 sincerequest_t = RealTime::fromSeconds(elapsed); | 598 double elapsed = currentTime - lastRetrievalTimestamp; |
599 | |
600 if (elapsed > 0.0) { | |
601 sincerequest_t = RealTime::fromSeconds(elapsed); | |
602 } | |
594 } | 603 } |
595 | 604 |
596 } else { | 605 } else { |
597 | 606 |
598 lastretrieved_t = RealTime::frame2RealTime | 607 lastretrieved_t = RealTime::frame2RealTime |
603 | 612 |
604 if (timeRatio != 1.0) { | 613 if (timeRatio != 1.0) { |
605 lastretrieved_t = lastretrieved_t / timeRatio; | 614 lastretrieved_t = lastretrieved_t / timeRatio; |
606 sincerequest_t = sincerequest_t / timeRatio; | 615 sincerequest_t = sincerequest_t / timeRatio; |
607 } | 616 } |
608 | |
609 bool looping = m_viewManager->getPlayLoopMode(); | |
610 | 617 |
611 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 618 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
612 std::cerr << "\nbuffered to: " << bufferedto_t << ", in buffer: " << inbuffer_t << ", time ratio " << timeRatio << "\n stretcher latency: " << stretchlat_t << ", device latency: " << latency_t << "\n since request: " << sincerequest_t << ", last retrieved: " << lastretrieved_t << std::endl; | 619 std::cerr << "\nbuffered to: " << bufferedto_t << ", in buffer: " << inbuffer_t << ", time ratio " << timeRatio << "\n stretcher latency: " << stretchlat_t << ", device latency: " << latency_t << "\n since request: " << sincerequest_t << ", last retrieved: " << lastretrieved_t << std::endl; |
613 #endif | 620 #endif |
614 | 621 |
716 } | 723 } |
717 | 724 |
718 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; | 725 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; |
719 | 726 |
720 size_t frame = RealTime::realTime2Frame(playing_t, sourceRate); | 727 size_t frame = RealTime::realTime2Frame(playing_t, sourceRate); |
728 | |
729 if (m_lastCurrentFrame > 0 && !looping) { | |
730 if (frame < m_lastCurrentFrame) { | |
731 frame = m_lastCurrentFrame; | |
732 } | |
733 } | |
734 | |
735 m_lastCurrentFrame = frame; | |
736 | |
721 return m_viewManager->alignPlaybackFrameToReference(frame); | 737 return m_viewManager->alignPlaybackFrameToReference(frame); |
722 } | 738 } |
723 | 739 |
724 void | 740 void |
725 AudioCallbackPlaySource::rebuildRangeLists() | 741 AudioCallbackPlaySource::rebuildRangeLists() |
1135 // std::cerr << "plugin output count " << plugin->getAudioOutputCount() | 1151 // std::cerr << "plugin output count " << plugin->getAudioOutputCount() |
1136 // << " != our channel count " << getTargetChannelCount() | 1152 // << " != our channel count " << getTargetChannelCount() |
1137 // << std::endl; | 1153 // << std::endl; |
1138 return; | 1154 return; |
1139 } | 1155 } |
1140 if (plugin->getBufferSize() != count) { | 1156 if (plugin->getBufferSize() < count) { |
1141 // std::cerr << "plugin buffer size " << plugin->getBufferSize() | 1157 // std::cerr << "plugin buffer size " << plugin->getBufferSize() |
1142 // << " != our block size " << count | 1158 // << " < our block size " << count |
1143 // << std::endl; | 1159 // << std::endl; |
1144 return; | 1160 return; |
1145 } | 1161 } |
1146 | 1162 |
1147 float **ib = plugin->getAudioInputBuffers(); | 1163 float **ib = plugin->getAudioInputBuffers(); |
1151 for (size_t i = 0; i < count; ++i) { | 1167 for (size_t i = 0; i < count; ++i) { |
1152 ib[c][i] = buffers[c][i]; | 1168 ib[c][i] = buffers[c][i]; |
1153 } | 1169 } |
1154 } | 1170 } |
1155 | 1171 |
1156 plugin->run(Vamp::RealTime::zeroTime); | 1172 plugin->run(Vamp::RealTime::zeroTime, count); |
1157 | 1173 |
1158 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | 1174 for (size_t c = 0; c < getTargetChannelCount(); ++c) { |
1159 for (size_t i = 0; i < count; ++i) { | 1175 for (size_t i = 0; i < count; ++i) { |
1160 buffers[c][i] = ob[c][i]; | 1176 buffers[c][i] = ob[c][i]; |
1161 } | 1177 } |