comparison audioio/AudioCallbackPlaySource.cpp @ 436:72c662fe7ea3 cxx11

Further dedicated-types fixes
author Chris Cannam
date Tue, 10 Mar 2015 17:02:52 +0000
parents 618d5816b04d
children aa6fb3516e28
comparison
equal deleted inserted replaced
435:618d5816b04d 436:72c662fe7ea3
304 m_crapConverter = 0; 304 m_crapConverter = 0;
305 } 305 }
306 m_sourceSampleRate = 0; 306 m_sourceSampleRate = 0;
307 } 307 }
308 308
309 int lastEnd = 0; 309 sv_frame_t lastEnd = 0;
310 for (std::set<Model *>::const_iterator i = m_models.begin(); 310 for (std::set<Model *>::const_iterator i = m_models.begin();
311 i != m_models.end(); ++i) { 311 i != m_models.end(); ++i) {
312 #ifdef DEBUG_AUDIO_PLAY_SOURCE 312 #ifdef DEBUG_AUDIO_PLAY_SOURCE
313 cout << "AudioCallbackPlaySource::removeModel(" << model << "): checking end frame on model " << *i << endl; 313 cout << "AudioCallbackPlaySource::removeModel(" << model << "): checking end frame on model " << *i << endl;
314 #endif 314 #endif
365 cerr << "clearRingBuffers" << endl; 365 cerr << "clearRingBuffers" << endl;
366 366
367 rebuildRangeLists(); 367 rebuildRangeLists();
368 368
369 if (count == 0) { 369 if (count == 0) {
370 if (m_writeBuffers) count = m_writeBuffers->size(); 370 if (m_writeBuffers) count = int(m_writeBuffers->size());
371 } 371 }
372 372
373 cerr << "current playing frame = " << getCurrentPlayingFrame() << endl; 373 cerr << "current playing frame = " << getCurrentPlayingFrame() << endl;
374 374
375 cerr << "write buffer fill (before) = " << m_writeBufferFill << endl; 375 cerr << "write buffer fill (before) = " << m_writeBufferFill << endl;
591 591
592 int 592 int
593 AudioCallbackPlaySource::getTargetBlockSize() const 593 AudioCallbackPlaySource::getTargetBlockSize() const
594 { 594 {
595 // cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << endl; 595 // cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << endl;
596 return m_blockSize; 596 return int(m_blockSize);
597 } 597 }
598 598
599 void 599 void
600 AudioCallbackPlaySource::setTargetPlayLatency(sv_frame_t latency) 600 AudioCallbackPlaySource::setTargetPlayLatency(sv_frame_t latency)
601 { 601 {
612 AudioCallbackPlaySource::getCurrentPlayingFrame() 612 AudioCallbackPlaySource::getCurrentPlayingFrame()
613 { 613 {
614 // This method attempts to estimate which audio sample frame is 614 // This method attempts to estimate which audio sample frame is
615 // "currently coming through the speakers". 615 // "currently coming through the speakers".
616 616
617 int targetRate = getTargetSampleRate(); 617 sv_samplerate_t targetRate = getTargetSampleRate();
618 int latency = m_playLatency; // at target rate 618 sv_frame_t latency = m_playLatency; // at target rate
619 RealTime latency_t = RealTime::zeroTime; 619 RealTime latency_t = RealTime::zeroTime;
620 620
621 if (targetRate != 0) { 621 if (targetRate != 0) {
622 latency_t = RealTime::frame2RealTime(latency, targetRate); 622 latency_t = RealTime::frame2RealTime(latency, targetRate);
623 } 623 }
653 int here = rb->getReadSpace(); 653 int here = rb->getReadSpace();
654 if (c == 0 || here < inbuffer) inbuffer = here; 654 if (c == 0 || here < inbuffer) inbuffer = here;
655 } 655 }
656 } 656 }
657 657
658 int readBufferFill = m_readBufferFill; 658 sv_frame_t readBufferFill = m_readBufferFill;
659 int lastRetrievedBlockSize = m_lastRetrievedBlockSize; 659 sv_frame_t lastRetrievedBlockSize = m_lastRetrievedBlockSize;
660 double lastRetrievalTimestamp = m_lastRetrievalTimestamp; 660 double lastRetrievalTimestamp = m_lastRetrievalTimestamp;
661 double currentTime = 0.0; 661 double currentTime = 0.0;
662 if (m_target) currentTime = m_target->getCurrentTime(); 662 if (m_target) currentTime = m_target->getCurrentTime();
663 663
664 bool looping = m_viewManager->getPlayLoopMode(); 664 bool looping = m_viewManager->getPlayLoopMode();
665 665
666 RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, targetRate); 666 RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, targetRate);
667 667
668 int stretchlat = 0; 668 sv_frame_t stretchlat = 0;
669 double timeRatio = 1.0; 669 double timeRatio = 1.0;
670 670
671 if (m_timeStretcher) { 671 if (m_timeStretcher) {
672 stretchlat = m_timeStretcher->getLatency(); 672 stretchlat = m_timeStretcher->getLatency();
673 timeRatio = m_timeStretcher->getTimeRatio(); 673 timeRatio = m_timeStretcher->getTimeRatio();
753 break; 753 break;
754 } 754 }
755 ++index; 755 ++index;
756 } 756 }
757 757
758 if (inRange >= (int)m_rangeStarts.size()) inRange = m_rangeStarts.size()-1; 758 if (inRange >= int(m_rangeStarts.size())) {
759 inRange = int(m_rangeStarts.size())-1;
760 }
759 761
760 RealTime playing_t = bufferedto_t; 762 RealTime playing_t = bufferedto_t;
761 763
762 playing_t = playing_t 764 playing_t = playing_t
763 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t 765 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t
804 806
805 while (playing_t < RealTime::zeroTime) { 807 while (playing_t < RealTime::zeroTime) {
806 808
807 if (inRange == 0) { 809 if (inRange == 0) {
808 if (looping) { 810 if (looping) {
809 inRange = m_rangeStarts.size() - 1; 811 inRange = int(m_rangeStarts.size()) - 1;
810 } else { 812 } else {
811 break; 813 break;
812 } 814 }
813 } else { 815 } else {
814 --inRange; 816 --inRange;
852 bool constrained = (m_viewManager->getPlaySelectionMode()); 854 bool constrained = (m_viewManager->getPlaySelectionMode());
853 855
854 m_rangeStarts.clear(); 856 m_rangeStarts.clear();
855 m_rangeDurations.clear(); 857 m_rangeDurations.clear();
856 858
857 int sourceRate = getSourceSampleRate(); 859 sv_samplerate_t sourceRate = getSourceSampleRate();
858 if (sourceRate == 0) return; 860 if (sourceRate == 0) return;
859 861
860 RealTime end = RealTime::frame2RealTime(m_lastModelEndFrame, sourceRate); 862 RealTime end = RealTime::frame2RealTime(m_lastModelEndFrame, sourceRate);
861 if (end == RealTime::zeroTime) return; 863 if (end == RealTime::zeroTime) return;
862 864
1058 { 1060 {
1059 return m_sourceSampleRate; 1061 return m_sourceSampleRate;
1060 } 1062 }
1061 1063
1062 void 1064 void
1063 AudioCallbackPlaySource::setTimeStretch(float factor) 1065 AudioCallbackPlaySource::setTimeStretch(double factor)
1064 { 1066 {
1065 m_stretchRatio = factor; 1067 m_stretchRatio = factor;
1066 1068
1067 if (!getTargetSampleRate()) return; // have to make our stretcher later 1069 if (!getTargetSampleRate()) return; // have to make our stretcher later
1068 1070
1069 if (m_timeStretcher || (factor == 1.f)) { 1071 if (m_timeStretcher || (factor == 1.0)) {
1070 // stretch ratio will be set in next process call if appropriate 1072 // stretch ratio will be set in next process call if appropriate
1071 } else { 1073 } else {
1072 m_stretcherInputCount = getTargetChannelCount(); 1074 m_stretcherInputCount = getTargetChannelCount();
1073 RubberBandStretcher *stretcher = new RubberBandStretcher 1075 RubberBandStretcher *stretcher = new RubberBandStretcher
1074 (getTargetSampleRate(), 1076 (int(getTargetSampleRate()),
1075 m_stretcherInputCount, 1077 m_stretcherInputCount,
1076 RubberBandStretcher::OptionProcessRealTime, 1078 RubberBandStretcher::OptionProcessRealTime,
1077 factor); 1079 factor);
1078 RubberBandStretcher *monoStretcher = new RubberBandStretcher 1080 RubberBandStretcher *monoStretcher = new RubberBandStretcher
1079 (getTargetSampleRate(), 1081 (int(getTargetSampleRate()),
1080 1, 1082 1,
1081 RubberBandStretcher::OptionProcessRealTime, 1083 RubberBandStretcher::OptionProcessRealTime,
1082 factor); 1084 factor);
1083 m_stretcherInputs = new float *[m_stretcherInputCount]; 1085 m_stretcherInputs = new float *[m_stretcherInputCount];
1084 m_stretcherInputSizes = new int[m_stretcherInputCount]; 1086 m_stretcherInputSizes = new sv_frame_t[m_stretcherInputCount];
1085 for (int c = 0; c < m_stretcherInputCount; ++c) { 1087 for (int c = 0; c < m_stretcherInputCount; ++c) {
1086 m_stretcherInputSizes[c] = 16384; 1088 m_stretcherInputSizes[c] = 16384;
1087 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]]; 1089 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]];
1088 } 1090 }
1089 m_monoStretcher = monoStretcher; 1091 m_monoStretcher = monoStretcher;
1144 if (count == 0) return 0; 1146 if (count == 0) return 0;
1145 1147
1146 RubberBandStretcher *ts = m_timeStretcher; 1148 RubberBandStretcher *ts = m_timeStretcher;
1147 RubberBandStretcher *ms = m_monoStretcher; 1149 RubberBandStretcher *ms = m_monoStretcher;
1148 1150
1149 float ratio = ts ? ts->getTimeRatio() : 1.f; 1151 double ratio = ts ? ts->getTimeRatio() : 1.0;
1150 1152
1151 if (ratio != m_stretchRatio) { 1153 if (ratio != m_stretchRatio) {
1152 if (!ts) { 1154 if (!ts) {
1153 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: Time ratio change to " << m_stretchRatio << " is pending, but no stretcher is set" << endl; 1155 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: Time ratio change to " << m_stretchRatio << " is pending, but no stretcher is set" << endl;
1154 m_stretchRatio = 1.f; 1156 m_stretchRatio = 1.0;
1155 } else { 1157 } else {
1156 ts->setTimeRatio(m_stretchRatio); 1158 ts->setTimeRatio(m_stretchRatio);
1157 if (ms) ms->setTimeRatio(m_stretchRatio); 1159 if (ms) ms->setTimeRatio(m_stretchRatio);
1158 if (m_stretchRatio >= 1.0) m_stretchMono = false; 1160 if (m_stretchRatio >= 1.0) m_stretchMono = false;
1159 } 1161 }
1184 1186
1185 if (rb) { 1187 if (rb) {
1186 1188
1187 // this is marginally more likely to leave our channels in 1189 // this is marginally more likely to leave our channels in
1188 // sync after a processing failure than just passing "count": 1190 // sync after a processing failure than just passing "count":
1189 int request = count; 1191 sv_frame_t request = count;
1190 if (ch > 0) request = got; 1192 if (ch > 0) request = got;
1191 1193
1192 got = rb->read(buffer[ch], request); 1194 got = rb->read(buffer[ch], int(request));
1193 1195
1194 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1196 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1195 cout << "AudioCallbackPlaySource::getSamples: got " << got << " (of " << count << ") samples on channel " << ch << ", signalling for more (possibly)" << endl; 1197 cout << "AudioCallbackPlaySource::getSamples: got " << got << " (of " << count << ") samples on channel " << ch << ", signalling for more (possibly)" << endl;
1196 #endif 1198 #endif
1197 } 1199 }
1213 1215
1214 return got; 1216 return got;
1215 } 1217 }
1216 1218
1217 int channels = getTargetChannelCount(); 1219 int channels = getTargetChannelCount();
1218 int available; 1220 sv_frame_t available;
1221 sv_frame_t fedToStretcher = 0;
1219 int warned = 0; 1222 int warned = 0;
1220 int fedToStretcher = 0;
1221 1223
1222 // The input block for a given output is approx output / ratio, 1224 // The input block for a given output is approx output / ratio,
1223 // but we can't predict it exactly, for an adaptive timestretcher. 1225 // but we can't predict it exactly, for an adaptive timestretcher.
1224 1226
1225 while ((available = ts->available()) < count) { 1227 while ((available = ts->available()) < count) {
1226 1228
1227 int reqd = lrintf((count - available) / ratio); 1229 sv_frame_t reqd = lrint(double(count - available) / ratio);
1228 reqd = std::max(reqd, (int)ts->getSamplesRequired()); 1230 reqd = std::max(reqd, sv_frame_t(ts->getSamplesRequired()));
1229 if (reqd == 0) reqd = 1; 1231 if (reqd == 0) reqd = 1;
1230 1232
1231 int got = reqd; 1233 sv_frame_t got = reqd;
1232 1234
1233 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1235 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1234 cerr << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << endl; 1236 cerr << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << endl;
1235 #endif 1237 #endif
1236 1238
1248 1250
1249 for (int c = 0; c < channels; ++c) { 1251 for (int c = 0; c < channels; ++c) {
1250 if (c >= m_stretcherInputCount) continue; 1252 if (c >= m_stretcherInputCount) continue;
1251 RingBuffer<float> *rb = getReadRingBuffer(c); 1253 RingBuffer<float> *rb = getReadRingBuffer(c);
1252 if (rb) { 1254 if (rb) {
1253 int gotHere; 1255 sv_frame_t gotHere;
1254 if (stretchChannels == 1 && c > 0) { 1256 if (stretchChannels == 1 && c > 0) {
1255 gotHere = rb->readAdding(m_stretcherInputs[0], got); 1257 gotHere = rb->readAdding(m_stretcherInputs[0], int(got));
1256 } else { 1258 } else {
1257 gotHere = rb->read(m_stretcherInputs[c], got); 1259 gotHere = rb->read(m_stretcherInputs[c], int(got));
1258 } 1260 }
1259 if (gotHere < got) got = gotHere; 1261 if (gotHere < got) got = gotHere;
1260 1262
1261 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1263 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1262 if (c == 0) { 1264 if (c == 0) {
1339 for (int i = 0; i < count; ++i) { 1341 for (int i = 0; i < count; ++i) {
1340 ib[c][i] = buffers[c][i]; 1342 ib[c][i] = buffers[c][i];
1341 } 1343 }
1342 } 1344 }
1343 1345
1344 plugin->run(Vamp::RealTime::zeroTime, count); 1346 plugin->run(Vamp::RealTime::zeroTime, int(count));
1345 1347
1346 for (int c = 0; c < getTargetChannelCount(); ++c) { 1348 for (int c = 0; c < getTargetChannelCount(); ++c) {
1347 for (int i = 0; i < count; ++i) { 1349 for (int i = 0; i < count; ++i) {
1348 buffers[c][i] = ob[c][i]; 1350 buffers[c][i] = ob[c][i];
1349 } 1351 }
1353 // Called from fill thread, m_playing true, mutex held 1355 // Called from fill thread, m_playing true, mutex held
1354 bool 1356 bool
1355 AudioCallbackPlaySource::fillBuffers() 1357 AudioCallbackPlaySource::fillBuffers()
1356 { 1358 {
1357 static float *tmp = 0; 1359 static float *tmp = 0;
1358 static int tmpSize = 0; 1360 static sv_frame_t tmpSize = 0;
1359 1361
1360 sv_frame_t space = 0; 1362 sv_frame_t space = 0;
1361 for (int c = 0; c < getTargetChannelCount(); ++c) { 1363 for (int c = 0; c < getTargetChannelCount(); ++c) {
1362 RingBuffer<float> *wb = getWriteRingBuffer(c); 1364 RingBuffer<float> *wb = getWriteRingBuffer(c);
1363 if (wb) { 1365 if (wb) {
1406 if (bufferPtrs) delete[] bufferPtrs; 1408 if (bufferPtrs) delete[] bufferPtrs;
1407 bufferPtrs = new float *[channels]; 1409 bufferPtrs = new float *[channels];
1408 bufferPtrCount = channels; 1410 bufferPtrCount = channels;
1409 } 1411 }
1410 1412
1411 int generatorBlockSize = m_audioGenerator->getBlockSize(); 1413 sv_frame_t generatorBlockSize = m_audioGenerator->getBlockSize();
1412 1414
1413 if (resample && !m_converter) { 1415 if (resample && !m_converter) {
1414 static bool warned = false; 1416 static bool warned = false;
1415 if (!warned) { 1417 if (!warned) {
1416 cerr << "WARNING: sample rates differ, but no converter available!" << endl; 1418 cerr << "WARNING: sample rates differ, but no converter available!" << endl;
1420 1422
1421 if (resample && m_converter) { 1423 if (resample && m_converter) {
1422 1424
1423 double ratio = 1425 double ratio =
1424 double(getTargetSampleRate()) / double(getSourceSampleRate()); 1426 double(getTargetSampleRate()) / double(getSourceSampleRate());
1425 orig = int(orig / ratio + 0.1); 1427 orig = sv_frame_t(double(orig) / ratio + 0.1);
1426 1428
1427 // orig must be a multiple of generatorBlockSize 1429 // orig must be a multiple of generatorBlockSize
1428 orig = (orig / generatorBlockSize) * generatorBlockSize; 1430 orig = (orig / generatorBlockSize) * generatorBlockSize;
1429 if (orig == 0) return false; 1431 if (orig == 0) return false;
1430 1432
1431 int work = std::max(orig, space); 1433 sv_frame_t work = std::max(orig, space);
1432 1434
1433 // We only allocate one buffer, but we use it in two halves. 1435 // We only allocate one buffer, but we use it in two halves.
1434 // We place the non-interleaved values in the second half of 1436 // We place the non-interleaved values in the second half of
1435 // the buffer (orig samples for channel 0, orig samples for 1437 // the buffer (orig samples for channel 0, orig samples for
1436 // channel 1 etc), and then interleave them into the first 1438 // channel 1 etc), and then interleave them into the first
1488 err = src_process(m_crapConverter, &data); 1490 err = src_process(m_crapConverter, &data);
1489 } else { 1491 } else {
1490 err = src_process(m_converter, &data); 1492 err = src_process(m_converter, &data);
1491 } 1493 }
1492 1494
1493 int toCopy = int(got * ratio + 0.1); 1495 sv_frame_t toCopy = sv_frame_t(double(got) * ratio + 0.1);
1494 1496
1495 if (err) { 1497 if (err) {
1496 cerr 1498 cerr
1497 << "AudioCallbackPlaySourceFillThread: ERROR in samplerate conversion: " 1499 << "AudioCallbackPlaySourceFillThread: ERROR in samplerate conversion: "
1498 << src_strerror(err) << endl; 1500 << src_strerror(err) << endl;
1508 for (int c = 0; c < channels; ++c) { 1510 for (int c = 0; c < channels; ++c) {
1509 for (int i = 0; i < toCopy; ++i) { 1511 for (int i = 0; i < toCopy; ++i) {
1510 tmp[i] = srcout[channels * i + c]; 1512 tmp[i] = srcout[channels * i + c];
1511 } 1513 }
1512 RingBuffer<float> *wb = getWriteRingBuffer(c); 1514 RingBuffer<float> *wb = getWriteRingBuffer(c);
1513 if (wb) wb->write(tmp, toCopy); 1515 if (wb) wb->write(tmp, int(toCopy));
1514 } 1516 }
1515 1517
1516 m_writeBufferFill = f; 1518 m_writeBufferFill = f;
1517 if (readWriteEqual) m_readBufferFill = f; 1519 if (readWriteEqual) m_readBufferFill = f;
1518 1520
1519 } else { 1521 } else {
1520 1522
1521 // space must be a multiple of generatorBlockSize 1523 // space must be a multiple of generatorBlockSize
1522 int reqSpace = space; 1524 sv_frame_t reqSpace = space;
1523 space = (reqSpace / generatorBlockSize) * generatorBlockSize; 1525 space = (reqSpace / generatorBlockSize) * generatorBlockSize;
1524 if (space == 0) { 1526 if (space == 0) {
1525 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1527 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1526 cout << "requested fill of " << reqSpace 1528 cout << "requested fill of " << reqSpace
1527 << " is less than generator block size of " 1529 << " is less than generator block size of "
1543 for (int i = 0; i < space; ++i) { 1545 for (int i = 0; i < space; ++i) {
1544 tmp[c * space + i] = 0.0f; 1546 tmp[c * space + i] = 0.0f;
1545 } 1547 }
1546 } 1548 }
1547 1549
1548 int got = mixModels(f, space, bufferPtrs); // also modifies f 1550 sv_frame_t got = mixModels(f, space, bufferPtrs); // also modifies f
1549 1551
1550 for (int c = 0; c < channels; ++c) { 1552 for (int c = 0; c < channels; ++c) {
1551 1553
1552 RingBuffer<float> *wb = getWriteRingBuffer(c); 1554 RingBuffer<float> *wb = getWriteRingBuffer(c);
1553 if (wb) { 1555 if (wb) {
1554 int actual = wb->write(bufferPtrs[c], got); 1556 int actual = wb->write(bufferPtrs[c], int(got));
1555 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1557 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1556 cout << "Wrote " << actual << " samples for ch " << c << ", now " 1558 cout << "Wrote " << actual << " samples for ch " << c << ", now "
1557 << wb->getReadSpace() << " to read" 1559 << wb->getReadSpace() << " to read"
1558 << endl; 1560 << endl;
1559 #endif 1561 #endif
1757 } 1759 }
1758 break; 1760 break;
1759 } 1761 }
1760 } 1762 }
1761 1763
1762 int rf = m_readBufferFill; 1764 sv_frame_t rf = m_readBufferFill;
1763 RingBuffer<float> *rb = getReadRingBuffer(0); 1765 RingBuffer<float> *rb = getReadRingBuffer(0);
1764 if (rb) { 1766 if (rb) {
1765 int rs = rb->getReadSpace(); 1767 int rs = rb->getReadSpace();
1766 //!!! incorrect when in non-contiguous selection, see comments elsewhere 1768 //!!! incorrect when in non-contiguous selection, see comments elsewhere
1767 // cout << "rs = " << rs << endl; 1769 // cout << "rs = " << rs << endl;
1771 1773
1772 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1774 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1773 SVDEBUG << "AudioCallbackPlaySource::unifyRingBuffers: m_readBufferFill = " << m_readBufferFill << ", rf = " << rf << ", m_writeBufferFill = " << m_writeBufferFill << endl; 1775 SVDEBUG << "AudioCallbackPlaySource::unifyRingBuffers: m_readBufferFill = " << m_readBufferFill << ", rf = " << rf << ", m_writeBufferFill = " << m_writeBufferFill << endl;
1774 #endif 1776 #endif
1775 1777
1776 int wf = m_writeBufferFill; 1778 sv_frame_t wf = m_writeBufferFill;
1777 int skip = 0; 1779 sv_frame_t skip = 0;
1778 for (int c = 0; c < getTargetChannelCount(); ++c) { 1780 for (int c = 0; c < getTargetChannelCount(); ++c) {
1779 RingBuffer<float> *wb = getWriteRingBuffer(c); 1781 RingBuffer<float> *wb = getWriteRingBuffer(c);
1780 if (wb) { 1782 if (wb) {
1781 if (c == 0) { 1783 if (c == 0) {
1782 1784
1790 if (wf < rf) skip = rf - wf; 1792 if (wf < rf) skip = rf - wf;
1791 if (skip == 0) break; 1793 if (skip == 0) break;
1792 } 1794 }
1793 1795
1794 // cout << "skipping " << skip << endl; 1796 // cout << "skipping " << skip << endl;
1795 wb->skip(skip); 1797 wb->skip(int(skip));
1796 } 1798 }
1797 } 1799 }
1798 1800
1799 m_bufferScavenger.claim(m_readBuffers); 1801 m_bufferScavenger.claim(m_readBuffers);
1800 m_readBuffers = m_writeBuffers; 1802 m_readBuffers = m_writeBuffers;
1833 s.m_mutex.unlock(); 1835 s.m_mutex.unlock();
1834 s.m_mutex.lock(); 1836 s.m_mutex.lock();
1835 1837
1836 } else { 1838 } else {
1837 1839
1838 float ms = 100; 1840 double ms = 100;
1839 if (s.getSourceSampleRate() > 0) { 1841 if (s.getSourceSampleRate() > 0) {
1840 ms = float(s.m_ringBufferSize) / 1842 ms = double(s.m_ringBufferSize) / s.getSourceSampleRate() * 1000.0;
1841 float(s.getSourceSampleRate()) * 1000.0;
1842 } 1843 }
1843 1844
1844 if (s.m_playing) ms /= 10; 1845 if (s.m_playing) ms /= 10;
1845 1846
1846 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1847 #ifdef DEBUG_AUDIO_PLAY_SOURCE