Mercurial > hg > svapp
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 |