Mercurial > hg > svapp
comparison audioio/AudioCallbackPlaySource.cpp @ 13:89bb89894ad6
* As previous commit
author | Chris Cannam |
---|---|
date | Fri, 17 Feb 2006 18:11:08 +0000 |
parents | 29b38a641d43 |
children | 6b5eaf206f0f |
comparison
equal
deleted
inserted
replaced
12:29b38a641d43 | 13:89bb89894ad6 |
---|---|
20 | 20 |
21 #include <iostream> | 21 #include <iostream> |
22 #include <cassert> | 22 #include <cassert> |
23 | 23 |
24 //#define DEBUG_AUDIO_PLAY_SOURCE 1 | 24 //#define DEBUG_AUDIO_PLAY_SOURCE 1 |
25 //#define DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1 | |
25 | 26 |
26 //const size_t AudioCallbackPlaySource::m_ringBufferSize = 102400; | 27 //const size_t AudioCallbackPlaySource::m_ringBufferSize = 102400; |
27 const size_t AudioCallbackPlaySource::m_ringBufferSize = 131071; | 28 const size_t AudioCallbackPlaySource::m_ringBufferSize = 131071; |
28 | 29 |
29 AudioCallbackPlaySource::AudioCallbackPlaySource(ViewManager *manager) : | 30 AudioCallbackPlaySource::AudioCallbackPlaySource(ViewManager *manager) : |
30 m_viewManager(manager), | 31 m_viewManager(manager), |
31 m_audioGenerator(new AudioGenerator(manager)), | 32 m_audioGenerator(new AudioGenerator(manager)), |
32 m_readBuffers(0), | 33 m_readBuffers(0), |
33 m_writeBuffers(0), | 34 m_writeBuffers(0), |
35 m_readBufferFill(0), | |
36 m_writeBufferFill(0), | |
37 m_bufferScavenger(1), | |
34 m_sourceChannelCount(0), | 38 m_sourceChannelCount(0), |
35 m_blockSize(1024), | 39 m_blockSize(1024), |
36 m_sourceSampleRate(0), | 40 m_sourceSampleRate(0), |
37 m_targetSampleRate(0), | 41 m_targetSampleRate(0), |
38 m_playLatency(0), | 42 m_playLatency(0), |
39 m_playing(false), | 43 m_playing(false), |
40 m_exiting(false), | 44 m_exiting(false), |
41 m_bufferedToFrame(0), | |
42 m_lastModelEndFrame(0), | 45 m_lastModelEndFrame(0), |
43 m_outputLeft(0.0), | 46 m_outputLeft(0.0), |
44 m_outputRight(0.0), | 47 m_outputRight(0.0), |
45 m_slowdownCounter(0), | 48 m_slowdownCounter(0), |
46 m_timeStretcher(0), | 49 m_timeStretcher(0), |
117 m_sourceChannelCount = modelChannels; | 120 m_sourceChannelCount = modelChannels; |
118 } | 121 } |
119 | 122 |
120 std::cerr << "Adding model with " << modelChannels << " channels " << std::endl; | 123 std::cerr << "Adding model with " << modelChannels << " channels " << std::endl; |
121 | 124 |
122 if (!m_writeBuffers || m_writeBuffers->size() < modelChannels) { | 125 if (!m_writeBuffers || (m_writeBuffers->size() < getTargetChannelCount())) { |
123 m_audioGenerator->setTargetChannelCount(modelChannels); | 126 clearRingBuffers(true, getTargetChannelCount()); |
124 } | |
125 | |
126 if (!m_writeBuffers || (m_writeBuffers->size() < modelChannels)) { | |
127 clearRingBuffers(true, modelChannels); | |
128 buffersChanged = true; | 127 buffersChanged = true; |
129 } else { | 128 } else { |
130 if (canPlay) clearRingBuffers(true); | 129 if (canPlay) clearRingBuffers(true); |
131 } | 130 } |
132 | 131 |
137 } | 136 } |
138 } | 137 } |
139 | 138 |
140 m_mutex.unlock(); | 139 m_mutex.unlock(); |
141 | 140 |
141 m_audioGenerator->setTargetChannelCount(getTargetChannelCount()); | |
142 | |
142 if (!m_fillThread) { | 143 if (!m_fillThread) { |
143 m_fillThread = new AudioCallbackPlaySourceFillThread(*this); | 144 m_fillThread = new AudioCallbackPlaySourceFillThread(*this); |
144 m_fillThread->start(); | 145 m_fillThread->start(); |
145 } | 146 } |
146 | 147 |
211 if (!haveLock) m_mutex.lock(); | 212 if (!haveLock) m_mutex.lock(); |
212 | 213 |
213 if (count == 0) { | 214 if (count == 0) { |
214 if (m_writeBuffers) count = m_writeBuffers->size(); | 215 if (m_writeBuffers) count = m_writeBuffers->size(); |
215 } | 216 } |
217 | |
218 size_t sf = m_readBufferFill; | |
219 RingBuffer<float> *rb = getReadRingBuffer(0); | |
220 if (rb) { | |
221 //!!! This is incorrect if we're in a non-contiguous selection | |
222 //Same goes for all related code (subtracting the read space | |
223 //from the fill frame to try to establish where the effective | |
224 //pre-resample/timestretch read pointer is) | |
225 size_t rs = rb->getReadSpace(); | |
226 if (rs < sf) sf -= rs; | |
227 else sf = 0; | |
228 } | |
229 m_writeBufferFill = sf; | |
216 | 230 |
217 if (m_readBuffers != m_writeBuffers) { | 231 if (m_readBuffers != m_writeBuffers) { |
218 delete m_writeBuffers; | 232 delete m_writeBuffers; |
219 } | 233 } |
220 | 234 |
261 // starting again if we have not so far been playing, but not if | 275 // starting again if we have not so far been playing, but not if |
262 // we're just re-seeking. | 276 // we're just re-seeking. |
263 | 277 |
264 m_mutex.lock(); | 278 m_mutex.lock(); |
265 if (m_playing) { | 279 if (m_playing) { |
266 m_bufferedToFrame = startFrame; | 280 m_readBufferFill = m_writeBufferFill = startFrame; |
267 if (m_readBuffers) { | 281 if (m_readBuffers) { |
268 for (size_t c = 0; c < getSourceChannelCount(); ++c) { | 282 for (size_t c = 0; c < getTargetChannelCount(); ++c) { |
269 RingBuffer<float> *rb = getReadRingBuffer(c); | 283 RingBuffer<float> *rb = getReadRingBuffer(c); |
270 if (rb) rb->reset(); | 284 if (rb) rb->reset(); |
271 } | 285 } |
272 } | 286 } |
273 if (m_converter) src_reset(m_converter); | 287 if (m_converter) src_reset(m_converter); |
274 } else { | 288 } else { |
275 if (m_converter) src_reset(m_converter); | 289 if (m_converter) src_reset(m_converter); |
276 m_bufferedToFrame = startFrame; | 290 m_readBufferFill = m_writeBufferFill = startFrame; |
277 } | 291 } |
278 m_mutex.unlock(); | 292 m_mutex.unlock(); |
279 | 293 |
280 m_audioGenerator->reset(); | 294 m_audioGenerator->reset(); |
281 | 295 |
357 resample = true; | 371 resample = true; |
358 ratio = double(getSourceSampleRate()) / double(getTargetSampleRate()); | 372 ratio = double(getSourceSampleRate()) / double(getTargetSampleRate()); |
359 } | 373 } |
360 | 374 |
361 size_t readSpace = 0; | 375 size_t readSpace = 0; |
362 for (size_t c = 0; c < getSourceChannelCount(); ++c) { | 376 for (size_t c = 0; c < getTargetChannelCount(); ++c) { |
363 RingBuffer<float> *rb = getReadRingBuffer(c); | 377 RingBuffer<float> *rb = getReadRingBuffer(c); |
364 if (rb) { | 378 if (rb) { |
365 size_t spaceHere = rb->getReadSpace(); | 379 size_t spaceHere = rb->getReadSpace(); |
366 if (c == 0 || spaceHere < readSpace) readSpace = spaceHere; | 380 if (c == 0 || spaceHere < readSpace) readSpace = spaceHere; |
367 } | 381 } |
378 if (timeStretcher) { | 392 if (timeStretcher) { |
379 latency += timeStretcher->getStretcher(0)->getProcessingLatency(); | 393 latency += timeStretcher->getStretcher(0)->getProcessingLatency(); |
380 } | 394 } |
381 | 395 |
382 latency += readSpace; | 396 latency += readSpace; |
383 size_t bufferedFrame = m_bufferedToFrame; | 397 size_t bufferedFrame = m_readBufferFill; |
384 | 398 |
385 bool looping = m_viewManager->getPlayLoopMode(); | 399 bool looping = m_viewManager->getPlayLoopMode(); |
386 bool constrained = (m_viewManager->getPlaySelectionMode() && | 400 bool constrained = (m_viewManager->getPlaySelectionMode() && |
387 !m_viewManager->getSelections().empty()); | 401 !m_viewManager->getSelections().empty()); |
388 | 402 |
487 m_targetSampleRate = sr; | 501 m_targetSampleRate = sr; |
488 | 502 |
489 if (getSourceSampleRate() != getTargetSampleRate()) { | 503 if (getSourceSampleRate() != getTargetSampleRate()) { |
490 | 504 |
491 int err = 0; | 505 int err = 0; |
492 m_converter = src_new(SRC_SINC_BEST_QUALITY, m_sourceChannelCount, &err); | 506 m_converter = src_new(SRC_SINC_BEST_QUALITY, |
507 getTargetChannelCount(), &err); | |
493 if (!m_converter) { | 508 if (!m_converter) { |
494 std::cerr | 509 std::cerr |
495 << "AudioCallbackPlaySource::setModel: ERROR in creating samplerate converter: " | 510 << "AudioCallbackPlaySource::setModel: ERROR in creating samplerate converter: " |
496 << src_strerror(err) << std::endl; | 511 << src_strerror(err) << std::endl; |
497 } | 512 } |
508 } | 523 } |
509 | 524 |
510 size_t | 525 size_t |
511 AudioCallbackPlaySource::getSourceChannelCount() const | 526 AudioCallbackPlaySource::getSourceChannelCount() const |
512 { | 527 { |
528 return m_sourceChannelCount; | |
529 } | |
530 | |
531 size_t | |
532 AudioCallbackPlaySource::getTargetChannelCount() const | |
533 { | |
534 if (m_sourceChannelCount < 2) return 2; | |
513 return m_sourceChannelCount; | 535 return m_sourceChannelCount; |
514 } | 536 } |
515 | 537 |
516 size_t | 538 size_t |
517 AudioCallbackPlaySource::getSourceSampleRate() const | 539 AudioCallbackPlaySource::getSourceSampleRate() const |
588 return; | 610 return; |
589 } | 611 } |
590 | 612 |
591 if (factor > 1) { | 613 if (factor > 1) { |
592 TimeStretcherData *newStretcher = new TimeStretcherData | 614 TimeStretcherData *newStretcher = new TimeStretcherData |
593 (getSourceChannelCount(), factor, getTargetBlockSize()); | 615 (getTargetChannelCount(), factor, getTargetBlockSize()); |
594 m_slowdownCounter = 0; | 616 m_slowdownCounter = 0; |
595 m_timeStretcher = newStretcher; | 617 m_timeStretcher = newStretcher; |
596 } else { | 618 } else { |
597 m_timeStretcher = 0; | 619 m_timeStretcher = 0; |
598 } | 620 } |
604 | 626 |
605 size_t | 627 size_t |
606 AudioCallbackPlaySource::getSourceSamples(size_t count, float **buffer) | 628 AudioCallbackPlaySource::getSourceSamples(size_t count, float **buffer) |
607 { | 629 { |
608 if (!m_playing) { | 630 if (!m_playing) { |
609 for (size_t ch = 0; ch < getSourceChannelCount(); ++ch) { | 631 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { |
610 for (size_t i = 0; i < count; ++i) { | 632 for (size_t i = 0; i < count; ++i) { |
611 buffer[ch][i] = 0.0; | 633 buffer[ch][i] = 0.0; |
612 } | 634 } |
613 } | 635 } |
614 return 0; | 636 return 0; |
618 | 640 |
619 if (!timeStretcher || timeStretcher->getFactor() == 1) { | 641 if (!timeStretcher || timeStretcher->getFactor() == 1) { |
620 | 642 |
621 size_t got = 0; | 643 size_t got = 0; |
622 | 644 |
623 for (size_t ch = 0; ch < getSourceChannelCount(); ++ch) { | 645 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { |
624 | 646 |
625 RingBuffer<float> *rb = getReadRingBuffer(ch); | 647 RingBuffer<float> *rb = getReadRingBuffer(ch); |
626 | 648 |
627 if (rb) { | 649 if (rb) { |
628 | 650 |
636 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 658 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
637 std::cout << "AudioCallbackPlaySource::getSamples: got " << got << " samples on channel " << ch << ", signalling for more (possibly)" << std::endl; | 659 std::cout << "AudioCallbackPlaySource::getSamples: got " << got << " samples on channel " << ch << ", signalling for more (possibly)" << std::endl; |
638 #endif | 660 #endif |
639 } | 661 } |
640 | 662 |
641 for (size_t ch = 0; ch < getSourceChannelCount(); ++ch) { | 663 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { |
642 for (size_t i = got; i < count; ++i) { | 664 for (size_t i = got; i < count; ++i) { |
643 buffer[ch][i] = 0.0; | 665 buffer[ch][i] = 0.0; |
644 } | 666 } |
645 } | 667 } |
646 } | 668 } |
652 if (m_slowdownCounter == 0) { | 674 if (m_slowdownCounter == 0) { |
653 | 675 |
654 size_t got = 0; | 676 size_t got = 0; |
655 double *ib = timeStretcher->getInputBuffer(); | 677 double *ib = timeStretcher->getInputBuffer(); |
656 | 678 |
657 for (size_t ch = 0; ch < getSourceChannelCount(); ++ch) { | 679 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { |
658 | 680 |
659 RingBuffer<float> *rb = getReadRingBuffer(ch); | 681 RingBuffer<float> *rb = getReadRingBuffer(ch); |
660 | 682 |
661 if (rb) { | 683 if (rb) { |
662 | 684 |
680 // reset this in case the factor has changed leaving the | 702 // reset this in case the factor has changed leaving the |
681 // counter out of range | 703 // counter out of range |
682 m_slowdownCounter = 0; | 704 m_slowdownCounter = 0; |
683 } | 705 } |
684 | 706 |
685 for (size_t ch = 0; ch < getSourceChannelCount(); ++ch) { | 707 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { |
686 | 708 |
687 double *ob = timeStretcher->getOutputBuffer(ch); | 709 double *ob = timeStretcher->getOutputBuffer(ch); |
688 | 710 |
689 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 711 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
690 std::cerr << "AudioCallbackPlaySource::getSamples: Copying from (" << (m_slowdownCounter * count) << "," << count << ") to buffer" << std::endl; | 712 std::cerr << "AudioCallbackPlaySource::getSamples: Copying from (" << (m_slowdownCounter * count) << "," << count << ") to buffer" << std::endl; |
706 { | 728 { |
707 static float *tmp = 0; | 729 static float *tmp = 0; |
708 static size_t tmpSize = 0; | 730 static size_t tmpSize = 0; |
709 | 731 |
710 size_t space = 0; | 732 size_t space = 0; |
711 for (size_t c = 0; c < getSourceChannelCount(); ++c) { | 733 for (size_t c = 0; c < getTargetChannelCount(); ++c) { |
712 RingBuffer<float> *wb = getWriteRingBuffer(c); | 734 RingBuffer<float> *wb = getWriteRingBuffer(c); |
713 if (wb) { | 735 if (wb) { |
714 size_t spaceHere = wb->getWriteSpace(); | 736 size_t spaceHere = wb->getWriteSpace(); |
715 if (c == 0 || spaceHere < space) space = spaceHere; | 737 if (c == 0 || spaceHere < space) space = spaceHere; |
716 } | 738 } |
717 } | 739 } |
718 | 740 |
719 if (space == 0) return false; | 741 if (space == 0) return false; |
720 | 742 |
743 size_t f = m_writeBufferFill; | |
744 | |
745 bool readWriteEqual = (m_readBuffers == m_writeBuffers); | |
746 | |
721 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 747 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
722 std::cout << "AudioCallbackPlaySourceFillThread: filling " << space << " frames" << std::endl; | 748 std::cout << "AudioCallbackPlaySourceFillThread: filling " << space << " frames" << std::endl; |
723 #endif | 749 #endif |
724 | 750 |
725 size_t f = m_bufferedToFrame; | |
726 | |
727 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 751 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
728 std::cout << "buffered to " << f << " already" << std::endl; | 752 std::cout << "buffered to " << f << " already" << std::endl; |
729 #endif | 753 #endif |
730 | 754 |
731 bool resample = (getSourceSampleRate() != getTargetSampleRate()); | 755 bool resample = (getSourceSampleRate() != getTargetSampleRate()); |
732 | 756 |
733 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 757 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
734 std::cout << (resample ? "" : "not ") << "resampling (source " << getSourceSampleRate() << ", target " << getTargetSampleRate() << ")" << std::endl; | 758 std::cout << (resample ? "" : "not ") << "resampling (source " << getSourceSampleRate() << ", target " << getTargetSampleRate() << ")" << std::endl; |
735 #endif | 759 #endif |
736 | 760 |
737 size_t channels = getSourceChannelCount(); | 761 size_t channels = getTargetChannelCount(); |
762 | |
738 size_t orig = space; | 763 size_t orig = space; |
739 size_t got = 0; | 764 size_t got = 0; |
740 | 765 |
741 static float **bufferPtrs = 0; | 766 static float **bufferPtrs = 0; |
742 static size_t bufferPtrCount = 0; | 767 static size_t bufferPtrCount = 0; |
841 } | 866 } |
842 RingBuffer<float> *wb = getWriteRingBuffer(c); | 867 RingBuffer<float> *wb = getWriteRingBuffer(c); |
843 if (wb) wb->write(tmp, toCopy); | 868 if (wb) wb->write(tmp, toCopy); |
844 } | 869 } |
845 | 870 |
846 m_bufferedToFrame = f; | 871 m_writeBufferFill = f; |
847 | 872 if (readWriteEqual) m_readBufferFill = f; |
873 | |
848 } else { | 874 } else { |
849 | 875 |
850 // space must be a multiple of generatorBlockSize | 876 // space must be a multiple of generatorBlockSize |
851 space = (space / generatorBlockSize) * generatorBlockSize; | 877 space = (space / generatorBlockSize) * generatorBlockSize; |
852 if (space == 0) return false; | 878 if (space == 0) return false; |
879 << wb->getReadSpace() << " to read" | 905 << wb->getReadSpace() << " to read" |
880 << std::endl; | 906 << std::endl; |
881 #endif | 907 #endif |
882 } | 908 } |
883 | 909 |
884 m_bufferedToFrame = f; | 910 m_writeBufferFill = f; |
911 if (readWriteEqual) m_readBufferFill = f; | |
912 | |
885 //!!! how do we know when ended? need to mark up a fully-buffered flag and check this if we find the buffers empty in getSourceSamples | 913 //!!! how do we know when ended? need to mark up a fully-buffered flag and check this if we find the buffers empty in getSourceSamples |
886 } | 914 } |
887 | 915 |
888 return true; | 916 return true; |
889 } | 917 } |
901 bool constrained = (m_viewManager->getPlaySelectionMode() && | 929 bool constrained = (m_viewManager->getPlaySelectionMode() && |
902 !m_viewManager->getSelections().empty()); | 930 !m_viewManager->getSelections().empty()); |
903 | 931 |
904 static float **chunkBufferPtrs = 0; | 932 static float **chunkBufferPtrs = 0; |
905 static size_t chunkBufferPtrCount = 0; | 933 static size_t chunkBufferPtrCount = 0; |
906 size_t channels = getSourceChannelCount(); | 934 size_t channels = getTargetChannelCount(); |
907 | 935 |
908 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 936 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
909 std::cerr << "Selection playback: start " << frame << ", size " << count <<", channels " << channels << std::endl; | 937 std::cerr << "Selection playback: start " << frame << ", size " << count <<", channels " << channels << std::endl; |
910 #endif | 938 #endif |
911 | 939 |
1039 frame = nextChunkStart; | 1067 frame = nextChunkStart; |
1040 return processed; | 1068 return processed; |
1041 } | 1069 } |
1042 | 1070 |
1043 void | 1071 void |
1072 AudioCallbackPlaySource::unifyRingBuffers() | |
1073 { | |
1074 if (m_readBuffers == m_writeBuffers) return; | |
1075 | |
1076 // only unify if there will be something to read | |
1077 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | |
1078 RingBuffer<float> *wb = getWriteRingBuffer(c); | |
1079 if (wb) { | |
1080 if (wb->getReadSpace() < m_blockSize * 2) { | |
1081 if ((m_writeBufferFill + m_blockSize * 2) < | |
1082 m_lastModelEndFrame) { | |
1083 // OK, we don't have enough and there's more to | |
1084 // read -- don't unify until we can do better | |
1085 return; | |
1086 } | |
1087 } | |
1088 break; | |
1089 } | |
1090 } | |
1091 | |
1092 size_t rf = m_readBufferFill; | |
1093 RingBuffer<float> *rb = getReadRingBuffer(0); | |
1094 if (rb) { | |
1095 size_t rs = rb->getReadSpace(); | |
1096 //!!! incorrect when in non-contiguous selection, see comments elsewhere | |
1097 // std::cerr << "rs = " << rs << std::endl; | |
1098 if (rs < rf) rf -= rs; | |
1099 else rf = 0; | |
1100 } | |
1101 | |
1102 //std::cerr << "m_readBufferFill = " << m_readBufferFill << ", rf = " << rf << ", m_writeBufferFill = " << m_writeBufferFill << std::endl; | |
1103 | |
1104 size_t wf = m_writeBufferFill; | |
1105 size_t skip = 0; | |
1106 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | |
1107 RingBuffer<float> *wb = getWriteRingBuffer(c); | |
1108 if (wb) { | |
1109 if (c == 0) { | |
1110 | |
1111 size_t wrs = wb->getReadSpace(); | |
1112 // std::cerr << "wrs = " << wrs << std::endl; | |
1113 | |
1114 if (wrs < wf) wf -= wrs; | |
1115 else wf = 0; | |
1116 // std::cerr << "wf = " << wf << std::endl; | |
1117 | |
1118 if (wf < rf) skip = rf - wf; | |
1119 if (skip == 0) break; | |
1120 } | |
1121 | |
1122 // std::cerr << "skipping " << skip << std::endl; | |
1123 wb->skip(skip); | |
1124 } | |
1125 } | |
1126 | |
1127 m_bufferScavenger.claim(m_readBuffers); | |
1128 m_readBuffers = m_writeBuffers; | |
1129 m_readBufferFill = m_writeBufferFill; | |
1130 std::cerr << "unified" << std::endl; | |
1131 } | |
1132 | |
1133 void | |
1044 AudioCallbackPlaySource::AudioCallbackPlaySourceFillThread::run() | 1134 AudioCallbackPlaySource::AudioCallbackPlaySourceFillThread::run() |
1045 { | 1135 { |
1046 AudioCallbackPlaySource &s(m_source); | 1136 AudioCallbackPlaySource &s(m_source); |
1047 | 1137 |
1048 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1138 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1054 bool previouslyPlaying = s.m_playing; | 1144 bool previouslyPlaying = s.m_playing; |
1055 bool work = false; | 1145 bool work = false; |
1056 | 1146 |
1057 while (!s.m_exiting) { | 1147 while (!s.m_exiting) { |
1058 | 1148 |
1059 if (s.m_readBuffers != s.m_writeBuffers) { | 1149 s.unifyRingBuffers(); |
1060 s.m_bufferScavenger.claim(s.m_readBuffers); | |
1061 s.m_readBuffers = s.m_writeBuffers; | |
1062 std::cerr << "unified" << std::endl; | |
1063 } | |
1064 | |
1065 s.m_bufferScavenger.scavenge(); | 1150 s.m_bufferScavenger.scavenge(); |
1066 s.m_timeStretcherScavenger.scavenge(); | 1151 s.m_timeStretcherScavenger.scavenge(); |
1067 | 1152 |
1068 if (work && s.m_playing && s.getSourceSampleRate()) { | 1153 if (work && s.m_playing && s.getSourceSampleRate()) { |
1069 | 1154 |
1098 | 1183 |
1099 if (playing && !previouslyPlaying) { | 1184 if (playing && !previouslyPlaying) { |
1100 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1185 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1101 std::cout << "AudioCallbackPlaySourceFillThread: playback state changed, resetting" << std::endl; | 1186 std::cout << "AudioCallbackPlaySourceFillThread: playback state changed, resetting" << std::endl; |
1102 #endif | 1187 #endif |
1103 for (size_t c = 0; c < s.getSourceChannelCount(); ++c) { | 1188 for (size_t c = 0; c < s.getTargetChannelCount(); ++c) { |
1104 RingBuffer<float> *rb = s.getReadRingBuffer(c); | 1189 RingBuffer<float> *rb = s.getReadRingBuffer(c); |
1105 if (rb) rb->reset(); | 1190 if (rb) rb->reset(); |
1106 } | 1191 } |
1107 } | 1192 } |
1108 previouslyPlaying = playing; | 1193 previouslyPlaying = playing; |