comparison audio/AudioCallbackPlaySource.cpp @ 554:4be200469a9c 3.0-integration

Merge from branch bqresample
author Chris Cannam
date Fri, 09 Dec 2016 18:01:55 +0000
parents 2a1e9e017484
children 2683a8ca36ea
comparison
equal deleted inserted replaced
546:4de547a5905c 554:4be200469a9c
26 #include "data/model/ReadOnlyWaveFileModel.h" 26 #include "data/model/ReadOnlyWaveFileModel.h"
27 #include "data/model/SparseOneDimensionalModel.h" 27 #include "data/model/SparseOneDimensionalModel.h"
28 #include "plugin/RealTimePluginInstance.h" 28 #include "plugin/RealTimePluginInstance.h"
29 29
30 #include "bqaudioio/SystemPlaybackTarget.h" 30 #include "bqaudioio/SystemPlaybackTarget.h"
31 #include "bqaudioio/ResamplerWrapper.h"
31 32
32 #include <rubberband/RubberBandStretcher.h> 33 #include <rubberband/RubberBandStretcher.h>
33 using namespace RubberBand; 34 using namespace RubberBand;
34 35
35 #include <iostream> 36 #include <iostream>
51 m_writeBufferFill(0), 52 m_writeBufferFill(0),
52 m_bufferScavenger(1), 53 m_bufferScavenger(1),
53 m_sourceChannelCount(0), 54 m_sourceChannelCount(0),
54 m_blockSize(1024), 55 m_blockSize(1024),
55 m_sourceSampleRate(0), 56 m_sourceSampleRate(0),
56 m_targetSampleRate(0), 57 m_deviceSampleRate(0),
57 m_playLatency(0), 58 m_playLatency(0),
58 m_target(0), 59 m_target(0),
59 m_lastRetrievalTimestamp(0.0), 60 m_lastRetrievalTimestamp(0.0),
60 m_lastRetrievedBlockSize(0), 61 m_lastRetrievedBlockSize(0),
61 m_trustworthyTimestamps(true), 62 m_trustworthyTimestamps(true),
75 m_stretchRatio(1.0), 76 m_stretchRatio(1.0),
76 m_stretchMono(false), 77 m_stretchMono(false),
77 m_stretcherInputCount(0), 78 m_stretcherInputCount(0),
78 m_stretcherInputs(0), 79 m_stretcherInputs(0),
79 m_stretcherInputSizes(0), 80 m_stretcherInputSizes(0),
80 m_fillThread(0) 81 m_fillThread(0),
82 m_resamplerWrapper(0)
81 { 83 {
82 m_viewManager->setAudioPlaySource(this); 84 m_viewManager->setAudioPlaySource(this);
83 85
84 connect(m_viewManager, SIGNAL(selectionChanged()), 86 connect(m_viewManager, SIGNAL(selectionChanged()),
85 this, SLOT(selectionChanged())); 87 this, SLOT(selectionChanged()));
226 buffersChanged = true; 228 buffersChanged = true;
227 } else { 229 } else {
228 if (willPlay) clearRingBuffers(true); 230 if (willPlay) clearRingBuffers(true);
229 } 231 }
230 232
231 if (buffersChanged || srChanged) { 233 if (srChanged) {
232 234
233 // There are more channels than there were before, or the 235 SVCERR << "AudioCallbackPlaySource: Source rate changed" << endl;
234 // source sample rate has changed 236
235 237 if (m_resamplerWrapper) {
236 //!!! 238 SVCERR << "AudioCallbackPlaySource: Source sample rate changed to "
237 239 << m_sourceSampleRate << ", updating resampler wrapper" << endl;
240 m_resamplerWrapper->changeApplicationSampleRate
241 (int(round(m_sourceSampleRate)));
242 m_resamplerWrapper->reset();
243 }
244
245 delete m_timeStretcher;
246 delete m_monoStretcher;
247 m_timeStretcher = 0;
248 m_monoStretcher = 0;
249
250 if (m_stretchRatio != 1.f) {
251 setTimeStretch(m_stretchRatio);
252 }
238 } 253 }
239 254
240 rebuildRangeLists(); 255 rebuildRangeLists();
241 256
242 m_mutex.unlock(); 257 m_mutex.unlock();
536 { 551 {
537 clearRingBuffers(); 552 clearRingBuffers();
538 } 553 }
539 554
540 void 555 void
541 AudioCallbackPlaySource::preferenceChanged(PropertyContainer::PropertyName n) 556 AudioCallbackPlaySource::preferenceChanged(PropertyContainer::PropertyName )
542 { 557 {
543 } 558 }
544 559
545 void 560 void
546 AudioCallbackPlaySource::audioProcessingOverload() 561 AudioCallbackPlaySource::audioProcessingOverload()
571 { 586 {
572 m_target = target; 587 m_target = target;
573 } 588 }
574 589
575 void 590 void
591 AudioCallbackPlaySource::setResamplerWrapper(breakfastquay::ResamplerWrapper *w)
592 {
593 m_resamplerWrapper = w;
594 if (m_resamplerWrapper && m_sourceSampleRate != 0) {
595 m_resamplerWrapper->changeApplicationSampleRate
596 (int(round(m_sourceSampleRate)));
597 }
598 }
599
600 void
576 AudioCallbackPlaySource::setSystemPlaybackBlockSize(int size) 601 AudioCallbackPlaySource::setSystemPlaybackBlockSize(int size)
577 { 602 {
578 cout << "AudioCallbackPlaySource::setTarget: Block size -> " << size << endl; 603 cout << "AudioCallbackPlaySource::setTarget: Block size -> " << size << endl;
579 if (size != 0) { 604 if (size != 0) {
580 m_blockSize = size; 605 m_blockSize = size;
616 AudioCallbackPlaySource::getCurrentPlayingFrame() 641 AudioCallbackPlaySource::getCurrentPlayingFrame()
617 { 642 {
618 // This method attempts to estimate which audio sample frame is 643 // This method attempts to estimate which audio sample frame is
619 // "currently coming through the speakers". 644 // "currently coming through the speakers".
620 645
621 sv_samplerate_t targetRate = getTargetSampleRate(); 646 sv_samplerate_t deviceRate = getDeviceSampleRate();
622 sv_frame_t latency = m_playLatency; // at target rate 647 sv_frame_t latency = m_playLatency; // at target rate
623 RealTime latency_t = RealTime::zeroTime; 648 RealTime latency_t = RealTime::zeroTime;
624 649
625 if (targetRate != 0) { 650 if (deviceRate != 0) {
626 latency_t = RealTime::frame2RealTime(latency, targetRate); 651 latency_t = RealTime::frame2RealTime(latency, deviceRate);
627 } 652 }
628 653
629 return getCurrentFrame(latency_t); 654 return getCurrentFrame(latency_t);
630 } 655 }
631 656
636 } 661 }
637 662
638 sv_frame_t 663 sv_frame_t
639 AudioCallbackPlaySource::getCurrentFrame(RealTime latency_t) 664 AudioCallbackPlaySource::getCurrentFrame(RealTime latency_t)
640 { 665 {
641 // We resample when filling the ring buffer, and time-stretch when 666 // The ring buffers contain data at the source sample rate and all
642 // draining it. The buffer contains data at the "target rate" and 667 // processing (including time stretching) happens at this
643 // the latency provided by the target is also at the target rate. 668 // rate. Resampling only happens after the audio data leaves this
644 // Because of the multiple rates involved, we do the actual 669 // class.
645 // calculation using RealTime instead. 670
646 671 // (But because historically more than one sample rate could have
647 sv_samplerate_t sourceRate = getSourceSampleRate(); 672 // been involved here, we do latency calculations using RealTime
648 sv_samplerate_t targetRate = getTargetSampleRate(); 673 // values instead of samples.)
649 674
650 if (sourceRate == 0 || targetRate == 0) return 0; 675 sv_samplerate_t rate = getSourceSampleRate();
676
677 if (rate == 0) return 0;
651 678
652 int inbuffer = 0; // at target rate 679 int inbuffer = 0; // at target rate
653 680
654 for (int c = 0; c < getTargetChannelCount(); ++c) { 681 for (int c = 0; c < getTargetChannelCount(); ++c) {
655 RingBuffer<float> *rb = getReadRingBuffer(c); 682 RingBuffer<float> *rb = getReadRingBuffer(c);
665 double currentTime = 0.0; 692 double currentTime = 0.0;
666 if (m_target) currentTime = m_target->getCurrentTime(); 693 if (m_target) currentTime = m_target->getCurrentTime();
667 694
668 bool looping = m_viewManager->getPlayLoopMode(); 695 bool looping = m_viewManager->getPlayLoopMode();
669 696
670 RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, targetRate); 697 RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, rate);
671 698
672 sv_frame_t stretchlat = 0; 699 sv_frame_t stretchlat = 0;
673 double timeRatio = 1.0; 700 double timeRatio = 1.0;
674 701
675 if (m_timeStretcher) { 702 if (m_timeStretcher) {
676 stretchlat = m_timeStretcher->getLatency(); 703 stretchlat = m_timeStretcher->getLatency();
677 timeRatio = m_timeStretcher->getTimeRatio(); 704 timeRatio = m_timeStretcher->getTimeRatio();
678 } 705 }
679 706
680 RealTime stretchlat_t = RealTime::frame2RealTime(stretchlat, targetRate); 707 RealTime stretchlat_t = RealTime::frame2RealTime(stretchlat, rate);
681 708
682 // When the target has just requested a block from us, the last 709 // When the target has just requested a block from us, the last
683 // sample it obtained was our buffer fill frame count minus the 710 // sample it obtained was our buffer fill frame count minus the
684 // amount of read space (converted back to source sample rate) 711 // amount of read space (converted back to source sample rate)
685 // remaining now. That sample is not expected to be played until 712 // remaining now. That sample is not expected to be played until
693 720
694 if (m_target && 721 if (m_target &&
695 m_trustworthyTimestamps && 722 m_trustworthyTimestamps &&
696 lastRetrievalTimestamp != 0.0) { 723 lastRetrievalTimestamp != 0.0) {
697 724
698 lastretrieved_t = RealTime::frame2RealTime 725 lastretrieved_t = RealTime::frame2RealTime(lastRetrievedBlockSize, rate);
699 (lastRetrievedBlockSize, targetRate);
700 726
701 // calculate number of frames at target rate that have elapsed 727 // calculate number of frames at target rate that have elapsed
702 // since the end of the last call to getSourceSamples 728 // since the end of the last call to getSourceSamples
703 729
704 if (m_trustworthyTimestamps && !looping) { 730 if (m_trustworthyTimestamps && !looping) {
711 } 737 }
712 } 738 }
713 739
714 } else { 740 } else {
715 741
716 lastretrieved_t = RealTime::frame2RealTime 742 lastretrieved_t = RealTime::frame2RealTime(getTargetBlockSize(), rate);
717 (getTargetBlockSize(), targetRate); 743 }
718 } 744
719 745 RealTime bufferedto_t = RealTime::frame2RealTime(readBufferFill, rate);
720 RealTime bufferedto_t = RealTime::frame2RealTime(readBufferFill, sourceRate);
721 746
722 if (timeRatio != 1.0) { 747 if (timeRatio != 1.0) {
723 lastretrieved_t = lastretrieved_t / timeRatio; 748 lastretrieved_t = lastretrieved_t / timeRatio;
724 sincerequest_t = sincerequest_t / timeRatio; 749 sincerequest_t = sincerequest_t / timeRatio;
725 latency_t = latency_t / timeRatio; 750 latency_t = latency_t / timeRatio;
741 // this code is only used in case of error in rebuildRangeLists 766 // this code is only used in case of error in rebuildRangeLists
742 RealTime playing_t = bufferedto_t 767 RealTime playing_t = bufferedto_t
743 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t 768 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t
744 + sincerequest_t; 769 + sincerequest_t;
745 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; 770 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime;
746 sv_frame_t frame = RealTime::realTime2Frame(playing_t, sourceRate); 771 sv_frame_t frame = RealTime::realTime2Frame(playing_t, rate);
747 return m_viewManager->alignPlaybackFrameToReference(frame); 772 return m_viewManager->alignPlaybackFrameToReference(frame);
748 } 773 }
749 774
750 int inRange = 0; 775 int inRange = 0;
751 int index = 0; 776 int index = 0;
778 // the region boundary and end up being much smaller than the 803 // the region boundary and end up being much smaller than the
779 // theoretical play start frame, perhaps even for the entire 804 // theoretical play start frame, perhaps even for the entire
780 // duration of playback! 805 // duration of playback!
781 806
782 if (!m_playStartFramePassed) { 807 if (!m_playStartFramePassed) {
783 RealTime playstart_t = RealTime::frame2RealTime(m_playStartFrame, 808 RealTime playstart_t = RealTime::frame2RealTime(m_playStartFrame, rate);
784 sourceRate);
785 if (playing_t < playstart_t) { 809 if (playing_t < playstart_t) {
786 // cerr << "playing_t " << playing_t << " < playstart_t " 810 // cerr << "playing_t " << playing_t << " < playstart_t "
787 // << playstart_t << endl; 811 // << playstart_t << endl;
788 if (/*!!! sincerequest_t > RealTime::zeroTime && */ 812 if (/*!!! sincerequest_t > RealTime::zeroTime && */
789 m_playStartedAt + latency_t + stretchlat_t < 813 m_playStartedAt + latency_t + stretchlat_t <
837 } 861 }
838 } 862 }
839 863
840 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; 864 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime;
841 865
842 sv_frame_t frame = RealTime::realTime2Frame(playing_t, sourceRate); 866 sv_frame_t frame = RealTime::realTime2Frame(playing_t, rate);
843 867
844 if (m_lastCurrentFrame > 0 && !looping) { 868 if (m_lastCurrentFrame > 0 && !looping) {
845 if (frame < m_lastCurrentFrame) { 869 if (frame < m_lastCurrentFrame) {
846 frame = m_lastCurrentFrame; 870 frame = m_lastCurrentFrame;
847 } 871 }
922 } 946 }
923 947
924 void 948 void
925 AudioCallbackPlaySource::setSystemPlaybackSampleRate(int sr) 949 AudioCallbackPlaySource::setSystemPlaybackSampleRate(int sr)
926 { 950 {
927 bool first = (m_targetSampleRate == 0); 951 m_deviceSampleRate = sr;
928 952 }
929 m_targetSampleRate = sr; 953
930 954 void
931 if (first && (m_stretchRatio != 1.f)) { 955 AudioCallbackPlaySource::setSystemPlaybackChannelCount(int)
932 // couldn't create a stretcher before because we had no sample
933 // rate: make one now
934 setTimeStretch(m_stretchRatio);
935 }
936 }
937
938 void
939 AudioCallbackPlaySource::setSystemPlaybackChannelCount(int c)
940 { 956 {
941 } 957 }
942 958
943 void 959 void
944 AudioCallbackPlaySource::setAuditioningEffect(Auditionable *a) 960 AudioCallbackPlaySource::setAuditioningEffect(Auditionable *a)
967 m_audioGenerator->clearSoloModelSet(); 983 m_audioGenerator->clearSoloModelSet();
968 clearRingBuffers(); 984 clearRingBuffers();
969 } 985 }
970 986
971 sv_samplerate_t 987 sv_samplerate_t
972 AudioCallbackPlaySource::getTargetSampleRate() const 988 AudioCallbackPlaySource::getDeviceSampleRate() const
973 { 989 {
974 if (m_targetSampleRate) return m_targetSampleRate; 990 return m_deviceSampleRate;
975 else return getSourceSampleRate();
976 } 991 }
977 992
978 int 993 int
979 AudioCallbackPlaySource::getSourceChannelCount() const 994 AudioCallbackPlaySource::getSourceChannelCount() const
980 { 995 {
997 void 1012 void
998 AudioCallbackPlaySource::setTimeStretch(double factor) 1013 AudioCallbackPlaySource::setTimeStretch(double factor)
999 { 1014 {
1000 m_stretchRatio = factor; 1015 m_stretchRatio = factor;
1001 1016
1002 if (!getTargetSampleRate()) return; // have to make our stretcher later 1017 int rate = int(getSourceSampleRate());
1018 if (!rate) return; // have to make our stretcher later
1003 1019
1004 if (m_timeStretcher || (factor == 1.0)) { 1020 if (m_timeStretcher || (factor == 1.0)) {
1005 // stretch ratio will be set in next process call if appropriate 1021 // stretch ratio will be set in next process call if appropriate
1006 } else { 1022 } else {
1007 m_stretcherInputCount = getTargetChannelCount(); 1023 m_stretcherInputCount = getTargetChannelCount();
1008 RubberBandStretcher *stretcher = new RubberBandStretcher 1024 RubberBandStretcher *stretcher = new RubberBandStretcher
1009 (int(getTargetSampleRate()), 1025 (rate,
1010 m_stretcherInputCount, 1026 m_stretcherInputCount,
1011 RubberBandStretcher::OptionProcessRealTime, 1027 RubberBandStretcher::OptionProcessRealTime,
1012 factor); 1028 factor);
1013 RubberBandStretcher *monoStretcher = new RubberBandStretcher 1029 RubberBandStretcher *monoStretcher = new RubberBandStretcher
1014 (int(getTargetSampleRate()), 1030 (rate,
1015 1, 1031 1,
1016 RubberBandStretcher::OptionProcessRealTime, 1032 RubberBandStretcher::OptionProcessRealTime,
1017 factor); 1033 factor);
1018 m_stretcherInputs = new float *[m_stretcherInputCount]; 1034 m_stretcherInputs = new float *[m_stretcherInputCount];
1019 m_stretcherInputSizes = new sv_frame_t[m_stretcherInputCount]; 1035 m_stretcherInputSizes = new sv_frame_t[m_stretcherInputCount];
1306 cout << "AudioCallbackPlaySourceFillThread: no space to fill" << endl; 1322 cout << "AudioCallbackPlaySourceFillThread: no space to fill" << endl;
1307 #endif 1323 #endif
1308 return false; 1324 return false;
1309 } 1325 }
1310 1326
1327 // space is now the number of samples that can be written on each
1328 // channel's write ringbuffer
1329
1311 sv_frame_t f = m_writeBufferFill; 1330 sv_frame_t f = m_writeBufferFill;
1312 1331
1313 bool readWriteEqual = (m_readBuffers == m_writeBuffers); 1332 bool readWriteEqual = (m_readBuffers == m_writeBuffers);
1314 1333
1315 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1334 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1322 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1341 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1323 cout << "buffered to " << f << " already" << endl; 1342 cout << "buffered to " << f << " already" << endl;
1324 #endif 1343 #endif
1325 1344
1326 int channels = getTargetChannelCount(); 1345 int channels = getTargetChannelCount();
1327
1328 sv_frame_t orig = space;
1329 1346
1330 static float **bufferPtrs = 0; 1347 static float **bufferPtrs = 0;
1331 static int bufferPtrCount = 0; 1348 static int bufferPtrCount = 0;
1332 1349
1333 if (bufferPtrCount < channels) { 1350 if (bufferPtrCount < channels) {