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 }