comparison audio/AudioCallbackPlaySource.cpp @ 563:ce3818cd16c5 3.0-integration

Debug changes
author Chris Cannam
date Wed, 14 Dec 2016 11:56:34 +0000
parents 3c846b06c518
children 36076ef960fb
comparison
equal deleted inserted replaced
562:3c846b06c518 563:ce3818cd16c5
369 AudioCallbackPlaySource::clearRingBuffers(bool haveLock, int count) 369 AudioCallbackPlaySource::clearRingBuffers(bool haveLock, int count)
370 { 370 {
371 if (!haveLock) m_mutex.lock(); 371 if (!haveLock) m_mutex.lock();
372 372
373 #ifdef DEBUG_AUDIO_PLAY_SOURCE 373 #ifdef DEBUG_AUDIO_PLAY_SOURCE
374 cerr << "clearRingBuffers" << endl; 374 cout << "clearRingBuffers" << endl;
375 #endif 375 #endif
376 376
377 rebuildRangeLists(); 377 rebuildRangeLists();
378 378
379 if (count == 0) { 379 if (count == 0) {
380 if (m_writeBuffers) count = int(m_writeBuffers->size()); 380 if (m_writeBuffers) count = int(m_writeBuffers->size());
381 } 381 }
382 382
383 #ifdef DEBUG_AUDIO_PLAY_SOURCE 383 #ifdef DEBUG_AUDIO_PLAY_SOURCE
384 cerr << "current playing frame = " << getCurrentPlayingFrame() << endl; 384 cout << "current playing frame = " << getCurrentPlayingFrame() << endl;
385 385
386 cerr << "write buffer fill (before) = " << m_writeBufferFill << endl; 386 cout << "write buffer fill (before) = " << m_writeBufferFill << endl;
387 #endif 387 #endif
388 388
389 m_writeBufferFill = getCurrentBufferedFrame(); 389 m_writeBufferFill = getCurrentBufferedFrame();
390 390
391 #ifdef DEBUG_AUDIO_PLAY_SOURCE 391 #ifdef DEBUG_AUDIO_PLAY_SOURCE
392 cerr << "current buffered frame = " << m_writeBufferFill << endl; 392 cout << "current buffered frame = " << m_writeBufferFill << endl;
393 #endif 393 #endif
394 394
395 if (m_readBuffers != m_writeBuffers) { 395 if (m_readBuffers != m_writeBuffers) {
396 delete m_writeBuffers; 396 delete m_writeBuffers;
397 } 397 }
416 AudioCallbackPlaySource::play(sv_frame_t startFrame) 416 AudioCallbackPlaySource::play(sv_frame_t startFrame)
417 { 417 {
418 if (!m_target) return; 418 if (!m_target) return;
419 419
420 if (!m_sourceSampleRate) { 420 if (!m_sourceSampleRate) {
421 cerr << "AudioCallbackPlaySource::play: No source sample rate available, not playing" << endl; 421 SVCERR << "AudioCallbackPlaySource::play: No source sample rate available, not playing" << endl;
422 return; 422 return;
423 } 423 }
424 424
425 if (m_viewManager->getPlaySelectionMode() && 425 if (m_viewManager->getPlaySelectionMode() &&
426 !m_viewManager->getSelections().empty()) { 426 !m_viewManager->getSelections().empty()) {
427 427
428 SVDEBUG << "AudioCallbackPlaySource::play: constraining frame " << startFrame << " to selection = "; 428 #ifdef DEBUG_AUDIO_PLAY_SOURCE
429 cout << "AudioCallbackPlaySource::play: constraining frame " << startFrame << " to selection = ";
430 #endif
429 431
430 startFrame = m_viewManager->constrainFrameToSelection(startFrame); 432 startFrame = m_viewManager->constrainFrameToSelection(startFrame);
431 433
432 SVDEBUG << startFrame << endl; 434 #ifdef DEBUG_AUDIO_PLAY_SOURCE
435 cout << startFrame << endl;
436 #endif
433 437
434 } else { 438 } else {
435 if (startFrame < 0) { 439 if (startFrame < 0) {
436 startFrame = 0; 440 startFrame = 0;
437 } 441 }
439 startFrame = 0; 443 startFrame = 0;
440 } 444 }
441 } 445 }
442 446
443 #ifdef DEBUG_AUDIO_PLAY_SOURCE 447 #ifdef DEBUG_AUDIO_PLAY_SOURCE
444 cerr << "play(" << startFrame << ") -> playback model "; 448 cout << "play(" << startFrame << ") -> aligned playback model ";
445 #endif 449 #endif
446 450
447 startFrame = m_viewManager->alignReferenceToPlaybackFrame(startFrame); 451 startFrame = m_viewManager->alignReferenceToPlaybackFrame(startFrame);
448 452
449 #ifdef DEBUG_AUDIO_PLAY_SOURCE 453 #ifdef DEBUG_AUDIO_PLAY_SOURCE
450 cerr << startFrame << endl; 454 cout << startFrame << endl;
451 #endif 455 #endif
452 456
453 // The fill thread will automatically empty its buffers before 457 // The fill thread will automatically empty its buffers before
454 // starting again if we have not so far been playing, but not if 458 // starting again if we have not so far been playing, but not if
455 // we're just re-seeking. 459 // we're just re-seeking.
467 m_readBufferFill = m_writeBufferFill = startFrame; 471 m_readBufferFill = m_writeBufferFill = startFrame;
468 if (m_readBuffers) { 472 if (m_readBuffers) {
469 for (int c = 0; c < getTargetChannelCount(); ++c) { 473 for (int c = 0; c < getTargetChannelCount(); ++c) {
470 RingBuffer<float> *rb = getReadRingBuffer(c); 474 RingBuffer<float> *rb = getReadRingBuffer(c);
471 #ifdef DEBUG_AUDIO_PLAY_SOURCE 475 #ifdef DEBUG_AUDIO_PLAY_SOURCE
472 cerr << "reset ring buffer for channel " << c << endl; 476 cout << "reset ring buffer for channel " << c << endl;
473 #endif 477 #endif
474 if (rb) rb->reset(); 478 if (rb) rb->reset();
475 } 479 }
476 } 480 }
477 481
562 } 566 }
563 567
564 void 568 void
565 AudioCallbackPlaySource::audioProcessingOverload() 569 AudioCallbackPlaySource::audioProcessingOverload()
566 { 570 {
567 cerr << "Audio processing overload!" << endl; 571 SVCERR << "Audio processing overload!" << endl;
568 572
569 if (!m_playing) return; 573 if (!m_playing) return;
570 574
571 RealTimePluginInstance *ap = m_auditioningPlugin; 575 RealTimePluginInstance *ap = m_auditioningPlugin;
572 if (ap && !m_auditioningPluginBypassed) { 576 if (ap && !m_auditioningPluginBypassed) {
613 if (size != 0) { 617 if (size != 0) {
614 m_blockSize = size; 618 m_blockSize = size;
615 } 619 }
616 if (size * 4 > m_ringBufferSize) { 620 if (size * 4 > m_ringBufferSize) {
617 #ifdef DEBUG_AUDIO_PLAY_SOURCE 621 #ifdef DEBUG_AUDIO_PLAY_SOURCE
618 cerr << "AudioCallbackPlaySource::setTarget: Buffer size " 622 cout << "AudioCallbackPlaySource::setTarget: Buffer size "
619 << size << " > a quarter of ring buffer size " 623 << size << " > a quarter of ring buffer size "
620 << m_ringBufferSize << ", calling for more ring buffer" 624 << m_ringBufferSize << ", calling for more ring buffer"
621 << endl; 625 << endl;
622 #endif 626 #endif
623 m_ringBufferSize = size * 4; 627 m_ringBufferSize = size * 4;
758 sincerequest_t = sincerequest_t / timeRatio; 762 sincerequest_t = sincerequest_t / timeRatio;
759 latency_t = latency_t / timeRatio; 763 latency_t = latency_t / timeRatio;
760 } 764 }
761 765
762 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 766 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
763 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 quantity: " << lastretrieved_t << endl; 767 cout << "\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 quantity: " << lastretrieved_t << endl;
764 #endif 768 #endif
765 769
766 // Normally the range lists should contain at least one item each 770 // Normally the range lists should contain at least one item each
767 // -- if playback is unconstrained, that item should report the 771 // -- if playback is unconstrained, that item should report the
768 // entire source audio duration. 772 // entire source audio duration.
814 // duration of playback! 818 // duration of playback!
815 819
816 if (!m_playStartFramePassed) { 820 if (!m_playStartFramePassed) {
817 RealTime playstart_t = RealTime::frame2RealTime(m_playStartFrame, rate); 821 RealTime playstart_t = RealTime::frame2RealTime(m_playStartFrame, rate);
818 if (playing_t < playstart_t) { 822 if (playing_t < playstart_t) {
819 // cerr << "playing_t " << playing_t << " < playstart_t " 823 // cout << "playing_t " << playing_t << " < playstart_t "
820 // << playstart_t << endl; 824 // << playstart_t << endl;
821 if (/*!!! sincerequest_t > RealTime::zeroTime && */ 825 if (/*!!! sincerequest_t > RealTime::zeroTime && */
822 m_playStartedAt + latency_t + stretchlat_t < 826 m_playStartedAt + latency_t + stretchlat_t <
823 RealTime::fromSeconds(currentTime)) { 827 RealTime::fromSeconds(currentTime)) {
824 // cerr << "but we've been playing for long enough that I think we should disregard it (it probably results from loop wrapping)" << endl; 828 // cout << "but we've been playing for long enough that I think we should disregard it (it probably results from loop wrapping)" << endl;
825 m_playStartFramePassed = true; 829 m_playStartFramePassed = true;
826 } else { 830 } else {
827 playing_t = playstart_t; 831 playing_t = playstart_t;
828 } 832 }
829 } else { 833 } else {
830 m_playStartFramePassed = true; 834 m_playStartFramePassed = true;
831 } 835 }
832 } 836 }
833 837
834 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 838 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
835 cerr << "playing_t " << playing_t; 839 cout << "playing_t " << playing_t;
836 #endif 840 #endif
837 841
838 playing_t = playing_t - m_rangeStarts[inRange]; 842 playing_t = playing_t - m_rangeStarts[inRange];
839 843
840 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 844 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
841 cerr << " as offset into range " << inRange << " (start =" << m_rangeStarts[inRange] << " duration =" << m_rangeDurations[inRange] << ") = " << playing_t << endl; 845 cout << " as offset into range " << inRange << " (start =" << m_rangeStarts[inRange] << " duration =" << m_rangeDurations[inRange] << ") = " << playing_t << endl;
842 #endif 846 #endif
843 847
844 while (playing_t < RealTime::zeroTime) { 848 while (playing_t < RealTime::zeroTime) {
845 849
846 if (inRange == 0) { 850 if (inRange == 0) {
857 } 861 }
858 862
859 playing_t = playing_t + m_rangeStarts[inRange]; 863 playing_t = playing_t + m_rangeStarts[inRange];
860 864
861 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 865 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
862 cerr << " playing time: " << playing_t << endl; 866 cout << " playing time: " << playing_t << endl;
863 #endif 867 #endif
864 868
865 if (!looping) { 869 if (!looping) {
866 if (inRange == (int)m_rangeStarts.size()-1 && 870 if (inRange == (int)m_rangeStarts.size()-1 &&
867 playing_t >= m_rangeStarts[inRange] + m_rangeDurations[inRange]) { 871 playing_t >= m_rangeStarts[inRange] + m_rangeDurations[inRange]) {
868 cerr << "Not looping, inRange " << inRange << " == rangeStarts.size()-1, playing_t " << playing_t << " >= m_rangeStarts[inRange] " << m_rangeStarts[inRange] << " + m_rangeDurations[inRange] " << m_rangeDurations[inRange] << " -- stopping" << endl; 872 cout << "Not looping, inRange " << inRange << " == rangeStarts.size()-1, playing_t " << playing_t << " >= m_rangeStarts[inRange] " << m_rangeStarts[inRange] << " + m_rangeDurations[inRange] " << m_rangeDurations[inRange] << " -- stopping" << endl;
869 stop(); 873 stop();
870 } 874 }
871 } 875 }
872 876
873 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; 877 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime;
933 m_rangeStarts.push_back(RealTime::zeroTime); 937 m_rangeStarts.push_back(RealTime::zeroTime);
934 m_rangeDurations.push_back(end); 938 m_rangeDurations.push_back(end);
935 } 939 }
936 940
937 #ifdef DEBUG_AUDIO_PLAY_SOURCE 941 #ifdef DEBUG_AUDIO_PLAY_SOURCE
938 cerr << "Now have " << m_rangeStarts.size() << " play ranges" << endl; 942 cout << "Now have " << m_rangeStarts.size() << " play ranges" << endl;
939 #endif 943 #endif
940 } 944 }
941 945
942 void 946 void
943 AudioCallbackPlaySource::setOutputLevels(float left, float right) 947 AudioCallbackPlaySource::setOutputLevels(float left, float right)
969 void 973 void
970 AudioCallbackPlaySource::setAuditioningEffect(Auditionable *a) 974 AudioCallbackPlaySource::setAuditioningEffect(Auditionable *a)
971 { 975 {
972 RealTimePluginInstance *plugin = dynamic_cast<RealTimePluginInstance *>(a); 976 RealTimePluginInstance *plugin = dynamic_cast<RealTimePluginInstance *>(a);
973 if (a && !plugin) { 977 if (a && !plugin) {
974 cerr << "WARNING: AudioCallbackPlaySource::setAuditioningEffect: auditionable object " << a << " is not a real-time plugin instance" << endl; 978 SVCERR << "WARNING: AudioCallbackPlaySource::setAuditioningEffect: auditionable object " << a << " is not a real-time plugin instance" << endl;
975 } 979 }
976 980
977 m_mutex.lock(); 981 m_mutex.lock();
978 m_auditioningPlugin = plugin; 982 m_auditioningPlugin = plugin;
979 m_auditioningPluginBypassed = false; 983 m_auditioningPluginBypassed = false;
1110 1114
1111 int channels = getTargetChannelCount(); 1115 int channels = getTargetChannelCount();
1112 1116
1113 if (!m_playing) { 1117 if (!m_playing) {
1114 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1118 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1115 SVDEBUG << "AudioCallbackPlaySource::getSourceSamples: Not playing" << endl; 1119 cout << "AudioCallbackPlaySource::getSourceSamples: Not playing" << endl;
1116 #endif 1120 #endif
1117 v_zero_channels(buffer, requestedChannels, count); 1121 v_zero_channels(buffer, requestedChannels, count);
1118 return 0; 1122 return 0;
1119 } 1123 }
1120 if (requestedChannels < channels) { 1124 if (requestedChannels < channels) {
1125 if (requestedChannels > channels) { 1129 if (requestedChannels > channels) {
1126 v_zero_channels(buffer + channels, requestedChannels - channels, count); 1130 v_zero_channels(buffer + channels, requestedChannels - channels, count);
1127 } 1131 }
1128 1132
1129 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1133 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1130 SVDEBUG << "AudioCallbackPlaySource::getSourceSamples: Playing" << endl; 1134 cout << "AudioCallbackPlaySource::getSourceSamples: Playing" << endl;
1131 #endif 1135 #endif
1132 1136
1133 // Ensure that all buffers have at least the amount of data we 1137 // Ensure that all buffers have at least the amount of data we
1134 // need -- else reduce the size of our requests correspondingly 1138 // need -- else reduce the size of our requests correspondingly
1135 1139
1136 for (int ch = 0; ch < channels; ++ch) { 1140 for (int ch = 0; ch < channels; ++ch) {
1137 1141
1138 RingBuffer<float> *rb = getReadRingBuffer(ch); 1142 RingBuffer<float> *rb = getReadRingBuffer(ch);
1139 1143
1140 if (!rb) { 1144 if (!rb) {
1141 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: " 1145 SVCERR << "WARNING: AudioCallbackPlaySource::getSourceSamples: "
1142 << "No ring buffer available for channel " << ch 1146 << "No ring buffer available for channel " << ch
1143 << ", returning no data here" << endl; 1147 << ", returning no data here" << endl;
1144 count = 0; 1148 count = 0;
1145 break; 1149 break;
1146 } 1150 }
1166 1170
1167 double ratio = ts ? ts->getTimeRatio() : 1.0; 1171 double ratio = ts ? ts->getTimeRatio() : 1.0;
1168 1172
1169 if (ratio != m_stretchRatio) { 1173 if (ratio != m_stretchRatio) {
1170 if (!ts) { 1174 if (!ts) {
1171 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: Time ratio change to " << m_stretchRatio << " is pending, but no stretcher is set" << endl; 1175 SVCERR << "WARNING: AudioCallbackPlaySource::getSourceSamples: Time ratio change to " << m_stretchRatio << " is pending, but no stretcher is set" << endl;
1172 m_stretchRatio = 1.0; 1176 m_stretchRatio = 1.0;
1173 } else { 1177 } else {
1174 ts->setTimeRatio(m_stretchRatio); 1178 ts->setTimeRatio(m_stretchRatio);
1175 if (ms) ms->setTimeRatio(m_stretchRatio); 1179 if (ms) ms->setTimeRatio(m_stretchRatio);
1176 if (m_stretchRatio >= 1.0) m_stretchMono = false; 1180 if (m_stretchRatio >= 1.0) m_stretchMono = false;
1194 1198
1195 if (!ts || ratio == 1.f) { 1199 if (!ts || ratio == 1.f) {
1196 1200
1197 int got = 0; 1201 int got = 0;
1198 1202
1199 cerr << "channels == " << channels << endl; 1203 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1204 cout << "channels == " << channels << endl;
1205 #endif
1200 1206
1201 for (int ch = 0; ch < channels; ++ch) { 1207 for (int ch = 0; ch < channels; ++ch) {
1202 1208
1203 RingBuffer<float> *rb = getReadRingBuffer(ch); 1209 RingBuffer<float> *rb = getReadRingBuffer(ch);
1204 1210
1248 if (reqd == 0) reqd = 1; 1254 if (reqd == 0) reqd = 1;
1249 1255
1250 sv_frame_t got = reqd; 1256 sv_frame_t got = reqd;
1251 1257
1252 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1258 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1253 cerr << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << endl; 1259 cout << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << endl;
1254 #endif 1260 #endif
1255 1261
1256 for (int c = 0; c < channels; ++c) { 1262 for (int c = 0; c < channels; ++c) {
1257 if (c >= m_stretcherInputCount) continue; 1263 if (c >= m_stretcherInputCount) continue;
1258 if (reqd > m_stretcherInputSizes[c]) { 1264 if (reqd > m_stretcherInputSizes[c]) {
1259 if (c == 0) { 1265 if (c == 0) {
1260 cerr << "WARNING: resizing stretcher input buffer from " << m_stretcherInputSizes[c] << " to " << (reqd * 2) << endl; 1266 SVDEBUG << "NOTE: resizing stretcher input buffer from " << m_stretcherInputSizes[c] << " to " << (reqd * 2) << endl;
1261 } 1267 }
1262 delete[] m_stretcherInputs[c]; 1268 delete[] m_stretcherInputs[c];
1263 m_stretcherInputSizes[c] = reqd * 2; 1269 m_stretcherInputSizes[c] = reqd * 2;
1264 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]]; 1270 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]];
1265 } 1271 }
1277 } 1283 }
1278 if (gotHere < got) got = gotHere; 1284 if (gotHere < got) got = gotHere;
1279 1285
1280 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1286 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1281 if (c == 0) { 1287 if (c == 0) {
1282 SVDEBUG << "feeding stretcher: got " << gotHere 1288 cout << "feeding stretcher: got " << gotHere
1283 << ", " << rb->getReadSpace() << " remain" << endl; 1289 << ", " << rb->getReadSpace() << " remain" << endl;
1284 } 1290 }
1285 #endif 1291 #endif
1286 1292
1287 } else { 1293 } else {
1288 cerr << "WARNING: No ring buffer available for channel " << c << " in stretcher input block" << endl; 1294 SVCERR << "WARNING: No ring buffer available for channel " << c << " in stretcher input block" << endl;
1289 } 1295 }
1290 } 1296 }
1291 1297
1292 if (got < reqd) { 1298 if (got < reqd) {
1293 cerr << "WARNING: Read underrun in playback (" 1299 SVCERR << "WARNING: Read underrun in playback ("
1294 << got << " < " << reqd << ")" << endl; 1300 << got << " < " << reqd << ")" << endl;
1295 } 1301 }
1296 1302
1297 ts->process(m_stretcherInputs, size_t(got), false); 1303 ts->process(m_stretcherInputs, size_t(got), false);
1298 1304
1299 fedToStretcher += got; 1305 fedToStretcher += got;
1300 1306
1301 if (got == 0) break; 1307 if (got == 0) break;
1302 1308
1303 if (ts->available() == available) { 1309 if (ts->available() == available) {
1304 cerr << "WARNING: AudioCallbackPlaySource::getSamples: Added " << got << " samples to time stretcher, created no new available output samples (warned = " << warned << ")" << endl; 1310 SVCERR << "WARNING: AudioCallbackPlaySource::getSamples: Added " << got << " samples to time stretcher, created no new available output samples (warned = " << warned << ")" << endl;
1305 if (++warned == 5) break; 1311 if (++warned == 5) break;
1306 } 1312 }
1307 } 1313 }
1308 1314
1309 ts->retrieve(buffer, size_t(count)); 1315 ts->retrieve(buffer, size_t(count));
1327 if (m_auditioningPluginBypassed) return; 1333 if (m_auditioningPluginBypassed) return;
1328 RealTimePluginInstance *plugin = m_auditioningPlugin; 1334 RealTimePluginInstance *plugin = m_auditioningPlugin;
1329 if (!plugin) return; 1335 if (!plugin) return;
1330 1336
1331 if ((int)plugin->getAudioInputCount() != getTargetChannelCount()) { 1337 if ((int)plugin->getAudioInputCount() != getTargetChannelCount()) {
1332 // cerr << "plugin input count " << plugin->getAudioInputCount() 1338 // cout << "plugin input count " << plugin->getAudioInputCount()
1333 // << " != our channel count " << getTargetChannelCount() 1339 // << " != our channel count " << getTargetChannelCount()
1334 // << endl; 1340 // << endl;
1335 return; 1341 return;
1336 } 1342 }
1337 if ((int)plugin->getAudioOutputCount() != getTargetChannelCount()) { 1343 if ((int)plugin->getAudioOutputCount() != getTargetChannelCount()) {
1338 // cerr << "plugin output count " << plugin->getAudioOutputCount() 1344 // cout << "plugin output count " << plugin->getAudioOutputCount()
1339 // << " != our channel count " << getTargetChannelCount() 1345 // << " != our channel count " << getTargetChannelCount()
1340 // << endl; 1346 // << endl;
1341 return; 1347 return;
1342 } 1348 }
1343 if ((int)plugin->getBufferSize() < count) { 1349 if ((int)plugin->getBufferSize() < count) {
1344 // cerr << "plugin buffer size " << plugin->getBufferSize() 1350 // cout << "plugin buffer size " << plugin->getBufferSize()
1345 // << " < our block size " << count 1351 // << " < our block size " << count
1346 // << endl; 1352 // << endl;
1347 return; 1353 return;
1348 } 1354 }
1349 1355
1457 cout << "Wrote " << actual << " samples for ch " << c << ", now " 1463 cout << "Wrote " << actual << " samples for ch " << c << ", now "
1458 << wb->getReadSpace() << " to read" 1464 << wb->getReadSpace() << " to read"
1459 << endl; 1465 << endl;
1460 #endif 1466 #endif
1461 if (actual < got) { 1467 if (actual < got) {
1462 cerr << "WARNING: Buffer overrun in channel " << c 1468 SVCERR << "WARNING: Buffer overrun in channel " << c
1463 << ": wrote " << actual << " of " << got 1469 << ": wrote " << actual << " of " << got
1464 << " samples" << endl; 1470 << " samples" << endl;
1465 } 1471 }
1466 } 1472 }
1467 } 1473 }
1468 1474
1469 m_writeBufferFill = f; 1475 m_writeBufferFill = f;
1470 if (readWriteEqual) m_readBufferFill = f; 1476 if (readWriteEqual) m_readBufferFill = f;
1471 1477
1472 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1478 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1473 cout << "Read buffer fill is now " << m_readBufferFill << endl; 1479 cout << "Read buffer fill is now " << m_readBufferFill << ", write buffer fill "
1480 << m_writeBufferFill << endl;
1474 #endif 1481 #endif
1475 1482
1476 //!!! 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 1483 //!!! 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
1477 1484
1478 return true; 1485 return true;
1489 1496
1490 bool looping = m_viewManager->getPlayLoopMode(); 1497 bool looping = m_viewManager->getPlayLoopMode();
1491 bool constrained = (m_viewManager->getPlaySelectionMode() && 1498 bool constrained = (m_viewManager->getPlaySelectionMode() &&
1492 !m_viewManager->getSelections().empty()); 1499 !m_viewManager->getSelections().empty());
1493 1500
1501 int channels = getTargetChannelCount();
1502
1503 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1504 cout << "mixModels: start " << frame << ", size " << count << ", channels " << channels << endl;
1505 #endif
1506 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1507 if (constrained) {
1508 cout << "Manager has " << m_viewManager->getSelections().size() << " selection(s):" << endl;
1509 for (auto sel: m_viewManager->getSelections()) {
1510 cout << sel.getStartFrame() << " -> " << sel.getEndFrame()
1511 << " (" << (sel.getEndFrame() - sel.getStartFrame()) << " frames)"
1512 << endl;
1513 }
1514 }
1515 #endif
1516
1494 static float **chunkBufferPtrs = 0; 1517 static float **chunkBufferPtrs = 0;
1495 static int chunkBufferPtrCount = 0; 1518 static int chunkBufferPtrCount = 0;
1496 int channels = getTargetChannelCount();
1497
1498 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1499 cout << "Selection playback: start " << frame << ", size " << count <<", channels " << channels << endl;
1500 #endif
1501 1519
1502 if (chunkBufferPtrCount < channels) { 1520 if (chunkBufferPtrCount < channels) {
1503 if (chunkBufferPtrs) delete[] chunkBufferPtrs; 1521 if (chunkBufferPtrs) delete[] chunkBufferPtrs;
1504 chunkBufferPtrs = new float *[channels]; 1522 chunkBufferPtrs = new float *[channels];
1505 chunkBufferPtrCount = channels; 1523 chunkBufferPtrCount = channels;
1571 if (chunkSize > m_lastModelEndFrame - chunkStart) { 1589 if (chunkSize > m_lastModelEndFrame - chunkStart) {
1572 chunkSize = m_lastModelEndFrame - chunkStart; 1590 chunkSize = m_lastModelEndFrame - chunkStart;
1573 } 1591 }
1574 nextChunkStart = chunkStart + chunkSize; 1592 nextChunkStart = chunkStart + chunkSize;
1575 } 1593 }
1576 1594
1577 // cout << "chunkStart " << chunkStart << ", chunkSize " << chunkSize << ", nextChunkStart " << nextChunkStart << ", frame " << frame << ", count " << count << ", processed " << processed << endl; 1595 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1578 1596 cout << "chunkStart " << chunkStart << ", chunkSize " << chunkSize << ", nextChunkStart " << nextChunkStart << ", frame " << frame << ", count " << count << ", processed " << processed << endl;
1597 #endif
1598
1579 if (!chunkSize) { 1599 if (!chunkSize) {
1580 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1581 cout << "Ending selection playback at " << nextChunkStart << endl;
1582 #endif
1583 // We need to maintain full buffers so that the other 1600 // We need to maintain full buffers so that the other
1584 // thread can tell where it's got to in the playback -- so 1601 // thread can tell where it's got to in the playback -- so
1585 // return the full amount here 1602 // return the full amount here
1586 frame = frame + count; 1603 frame = frame + count;
1587 if (frame < nextChunkStart) { 1604 if (frame < nextChunkStart) {
1593 #endif 1610 #endif
1594 return count; 1611 return count;
1595 } 1612 }
1596 1613
1597 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1614 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1598 cout << "Selection playback: chunk at " << chunkStart << " -> " << nextChunkStart << " (size " << chunkSize << ")" << endl; 1615 cout << "mixModels: chunk at " << chunkStart << " -> " << nextChunkStart << " (size " << chunkSize << ")" << endl;
1599 #endif 1616 #endif
1600 1617
1601 if (selectionSize < 100) { 1618 if (selectionSize < 100) {
1602 fadeIn = 0; 1619 fadeIn = 0;
1603 fadeOut = 0; 1620 fadeOut = 0;
1633 processed += chunkSize; 1650 processed += chunkSize;
1634 chunkStart = nextChunkStart; 1651 chunkStart = nextChunkStart;
1635 } 1652 }
1636 1653
1637 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1654 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1638 cout << "Returning selection playback " << processed << " frames to " << nextChunkStart << endl; 1655 cout << "mixModels returning " << processed << " frames to " << nextChunkStart << endl;
1639 #endif 1656 #endif
1640 1657
1641 frame = nextChunkStart; 1658 frame = nextChunkStart;
1642 return processed; 1659 return processed;
1643 } 1660 }
1655 if ((m_writeBufferFill + m_blockSize * 2) < 1672 if ((m_writeBufferFill + m_blockSize * 2) <
1656 m_lastModelEndFrame) { 1673 m_lastModelEndFrame) {
1657 // OK, we don't have enough and there's more to 1674 // OK, we don't have enough and there's more to
1658 // read -- don't unify until we can do better 1675 // read -- don't unify until we can do better
1659 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1676 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1660 SVDEBUG << "AudioCallbackPlaySource::unifyRingBuffers: Not unifying: write buffer has less (" << wb->getReadSpace() << ") than " << m_blockSize*2 << " to read and write buffer fill (" << m_writeBufferFill << ") is not close to end frame (" << m_lastModelEndFrame << ")" << endl; 1677 cout << "AudioCallbackPlaySource::unifyRingBuffers: Not unifying: write buffer has less (" << wb->getReadSpace() << ") than " << m_blockSize*2 << " to read and write buffer fill (" << m_writeBufferFill << ") is not close to end frame (" << m_lastModelEndFrame << ")" << endl;
1661 #endif 1678 #endif
1662 return; 1679 return;
1663 } 1680 }
1664 } 1681 }
1665 break; 1682 break;
1675 if (rs < rf) rf -= rs; 1692 if (rs < rf) rf -= rs;
1676 else rf = 0; 1693 else rf = 0;
1677 } 1694 }
1678 1695
1679 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1696 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1680 SVDEBUG << "AudioCallbackPlaySource::unifyRingBuffers: m_readBufferFill = " << m_readBufferFill << ", rf = " << rf << ", m_writeBufferFill = " << m_writeBufferFill << endl; 1697 cout << "AudioCallbackPlaySource::unifyRingBuffers: m_readBufferFill = " << m_readBufferFill << ", rf = " << rf << ", m_writeBufferFill = " << m_writeBufferFill << endl;
1681 #endif 1698 #endif
1682 1699
1683 sv_frame_t wf = m_writeBufferFill; 1700 sv_frame_t wf = m_writeBufferFill;
1684 sv_frame_t skip = 0; 1701 sv_frame_t skip = 0;
1685 for (int c = 0; c < getTargetChannelCount(); ++c) { 1702 for (int c = 0; c < getTargetChannelCount(); ++c) {
1705 1722
1706 m_bufferScavenger.claim(m_readBuffers); 1723 m_bufferScavenger.claim(m_readBuffers);
1707 m_readBuffers = m_writeBuffers; 1724 m_readBuffers = m_writeBuffers;
1708 m_readBufferFill = m_writeBufferFill; 1725 m_readBufferFill = m_writeBufferFill;
1709 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1726 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1710 cerr << "unified" << endl; 1727 cout << "unified" << endl;
1711 #endif 1728 #endif
1712 } 1729 }
1713 1730
1714 void 1731 void
1715 AudioCallbackPlaySource::FillThread::run() 1732 AudioCallbackPlaySource::FillThread::run()