Mercurial > hg > svapp
comparison audioio/AudioCallbackPlaySource.cpp @ 293:068235cf5bf7
Drop std:: from cout, cerr, endl -- pull these in through Debug.h
author | Chris Cannam |
---|---|
date | Tue, 26 Nov 2013 14:12:50 +0000 |
parents | f853dfb200de |
children | 14b1768e5406 47964f188bd9 |
comparison
equal
deleted
inserted
replaced
291:3fc0df289533 | 293:068235cf5bf7 |
---|---|
105 #endif | 105 #endif |
106 m_exiting = true; | 106 m_exiting = true; |
107 | 107 |
108 if (m_fillThread) { | 108 if (m_fillThread) { |
109 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 109 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
110 std::cout << "AudioCallbackPlaySource dtor: awakening thread" << std::endl; | 110 cout << "AudioCallbackPlaySource dtor: awakening thread" << endl; |
111 #endif | 111 #endif |
112 m_condition.wakeAll(); | 112 m_condition.wakeAll(); |
113 m_fillThread->wait(); | 113 m_fillThread->wait(); |
114 delete m_fillThread; | 114 delete m_fillThread; |
115 } | 115 } |
162 if (modelChannels > m_sourceChannelCount) { | 162 if (modelChannels > m_sourceChannelCount) { |
163 m_sourceChannelCount = modelChannels; | 163 m_sourceChannelCount = modelChannels; |
164 } | 164 } |
165 | 165 |
166 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 166 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
167 std::cout << "Adding model with " << modelChannels << " channels at rate " << model->getSampleRate() << std::endl; | 167 cout << "Adding model with " << modelChannels << " channels at rate " << model->getSampleRate() << endl; |
168 #endif | 168 #endif |
169 | 169 |
170 if (m_sourceSampleRate == 0) { | 170 if (m_sourceSampleRate == 0) { |
171 | 171 |
172 m_sourceSampleRate = model->getSampleRate(); | 172 m_sourceSampleRate = model->getSampleRate(); |
243 m_fillThread = new FillThread(*this); | 243 m_fillThread = new FillThread(*this); |
244 m_fillThread->start(); | 244 m_fillThread->start(); |
245 } | 245 } |
246 | 246 |
247 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 247 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
248 std::cout << "AudioCallbackPlaySource::addModel: now have " << m_models.size() << " model(s) -- emitting modelReplaced" << std::endl; | 248 cout << "AudioCallbackPlaySource::addModel: now have " << m_models.size() << " model(s) -- emitting modelReplaced" << endl; |
249 #endif | 249 #endif |
250 | 250 |
251 if (buffersChanged || srChanged) { | 251 if (buffersChanged || srChanged) { |
252 emit modelReplaced(); | 252 emit modelReplaced(); |
253 } | 253 } |
254 | 254 |
255 connect(model, SIGNAL(modelChanged(size_t, size_t)), | 255 connect(model, SIGNAL(modelChanged(size_t, size_t)), |
256 this, SLOT(modelChanged(size_t, size_t))); | 256 this, SLOT(modelChanged(size_t, size_t))); |
257 | 257 |
258 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 258 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
259 std::cout << "AudioCallbackPlaySource::addModel: awakening thread" << std::endl; | 259 cout << "AudioCallbackPlaySource::addModel: awakening thread" << endl; |
260 #endif | 260 #endif |
261 | 261 |
262 m_condition.wakeAll(); | 262 m_condition.wakeAll(); |
263 } | 263 } |
264 | 264 |
278 AudioCallbackPlaySource::removeModel(Model *model) | 278 AudioCallbackPlaySource::removeModel(Model *model) |
279 { | 279 { |
280 m_mutex.lock(); | 280 m_mutex.lock(); |
281 | 281 |
282 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 282 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
283 std::cout << "AudioCallbackPlaySource::removeModel(" << model << ")" << std::endl; | 283 cout << "AudioCallbackPlaySource::removeModel(" << model << ")" << endl; |
284 #endif | 284 #endif |
285 | 285 |
286 disconnect(model, SIGNAL(modelChanged(size_t, size_t)), | 286 disconnect(model, SIGNAL(modelChanged(size_t, size_t)), |
287 this, SLOT(modelChanged(size_t, size_t))); | 287 this, SLOT(modelChanged(size_t, size_t))); |
288 | 288 |
300 | 300 |
301 size_t lastEnd = 0; | 301 size_t lastEnd = 0; |
302 for (std::set<Model *>::const_iterator i = m_models.begin(); | 302 for (std::set<Model *>::const_iterator i = m_models.begin(); |
303 i != m_models.end(); ++i) { | 303 i != m_models.end(); ++i) { |
304 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 304 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
305 std::cout << "AudioCallbackPlaySource::removeModel(" << model << "): checking end frame on model " << *i << std::endl; | 305 cout << "AudioCallbackPlaySource::removeModel(" << model << "): checking end frame on model " << *i << endl; |
306 #endif | 306 #endif |
307 if ((*i)->getEndFrame() > lastEnd) lastEnd = (*i)->getEndFrame(); | 307 if ((*i)->getEndFrame() > lastEnd) lastEnd = (*i)->getEndFrame(); |
308 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 308 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
309 std::cout << "(done, lastEnd now " << lastEnd << ")" << std::endl; | 309 cout << "(done, lastEnd now " << lastEnd << ")" << endl; |
310 #endif | 310 #endif |
311 } | 311 } |
312 m_lastModelEndFrame = lastEnd; | 312 m_lastModelEndFrame = lastEnd; |
313 | 313 |
314 m_audioGenerator->removeModel(model); | 314 m_audioGenerator->removeModel(model); |
322 AudioCallbackPlaySource::clearModels() | 322 AudioCallbackPlaySource::clearModels() |
323 { | 323 { |
324 m_mutex.lock(); | 324 m_mutex.lock(); |
325 | 325 |
326 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 326 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
327 std::cout << "AudioCallbackPlaySource::clearModels()" << std::endl; | 327 cout << "AudioCallbackPlaySource::clearModels()" << endl; |
328 #endif | 328 #endif |
329 | 329 |
330 m_models.clear(); | 330 m_models.clear(); |
331 | 331 |
332 if (m_converter) { | 332 if (m_converter) { |
368 | 368 |
369 for (size_t i = 0; i < count; ++i) { | 369 for (size_t i = 0; i < count; ++i) { |
370 m_writeBuffers->push_back(new RingBuffer<float>(m_ringBufferSize)); | 370 m_writeBuffers->push_back(new RingBuffer<float>(m_ringBufferSize)); |
371 } | 371 } |
372 | 372 |
373 // std::cout << "AudioCallbackPlaySource::clearRingBuffers: Created " | 373 // cout << "AudioCallbackPlaySource::clearRingBuffers: Created " |
374 // << count << " write buffers" << std::endl; | 374 // << count << " write buffers" << endl; |
375 | 375 |
376 if (!haveLock) { | 376 if (!haveLock) { |
377 m_mutex.unlock(); | 377 m_mutex.unlock(); |
378 } | 378 } |
379 } | 379 } |
395 startFrame = 0; | 395 startFrame = 0; |
396 } | 396 } |
397 } | 397 } |
398 | 398 |
399 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 399 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
400 std::cerr << "play(" << startFrame << ") -> playback model "; | 400 cerr << "play(" << startFrame << ") -> playback model "; |
401 #endif | 401 #endif |
402 | 402 |
403 startFrame = m_viewManager->alignReferenceToPlaybackFrame(startFrame); | 403 startFrame = m_viewManager->alignReferenceToPlaybackFrame(startFrame); |
404 | 404 |
405 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 405 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
406 std::cerr << startFrame << std::endl; | 406 cerr << startFrame << endl; |
407 #endif | 407 #endif |
408 | 408 |
409 // The fill thread will automatically empty its buffers before | 409 // The fill thread will automatically empty its buffers before |
410 // starting again if we have not so far been playing, but not if | 410 // starting again if we have not so far been playing, but not if |
411 // we're just re-seeking. | 411 // we're just re-seeking. |
423 m_readBufferFill = m_writeBufferFill = startFrame; | 423 m_readBufferFill = m_writeBufferFill = startFrame; |
424 if (m_readBuffers) { | 424 if (m_readBuffers) { |
425 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | 425 for (size_t c = 0; c < getTargetChannelCount(); ++c) { |
426 RingBuffer<float> *rb = getReadRingBuffer(c); | 426 RingBuffer<float> *rb = getReadRingBuffer(c); |
427 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 427 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
428 std::cerr << "reset ring buffer for channel " << c << std::endl; | 428 cerr << "reset ring buffer for channel " << c << endl; |
429 #endif | 429 #endif |
430 if (rb) rb->reset(); | 430 if (rb) rb->reset(); |
431 } | 431 } |
432 } | 432 } |
433 if (m_converter) src_reset(m_converter); | 433 if (m_converter) src_reset(m_converter); |
448 m_lastRetrievalTimestamp = 0; | 448 m_lastRetrievalTimestamp = 0; |
449 m_lastCurrentFrame = 0; | 449 m_lastCurrentFrame = 0; |
450 m_playing = true; | 450 m_playing = true; |
451 | 451 |
452 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 452 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
453 std::cout << "AudioCallbackPlaySource::play: awakening thread" << std::endl; | 453 cout << "AudioCallbackPlaySource::play: awakening thread" << endl; |
454 #endif | 454 #endif |
455 | 455 |
456 m_condition.wakeAll(); | 456 m_condition.wakeAll(); |
457 if (changed) { | 457 if (changed) { |
458 emit playStatusChanged(m_playing); | 458 emit playStatusChanged(m_playing); |
470 #endif | 470 #endif |
471 bool changed = m_playing; | 471 bool changed = m_playing; |
472 m_playing = false; | 472 m_playing = false; |
473 | 473 |
474 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 474 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
475 std::cout << "AudioCallbackPlaySource::stop: awakening thread" << std::endl; | 475 cout << "AudioCallbackPlaySource::stop: awakening thread" << endl; |
476 #endif | 476 #endif |
477 | 477 |
478 m_condition.wakeAll(); | 478 m_condition.wakeAll(); |
479 m_lastRetrievalTimestamp = 0; | 479 m_lastRetrievalTimestamp = 0; |
480 if (changed) { | 480 if (changed) { |
523 } | 523 } |
524 | 524 |
525 void | 525 void |
526 AudioCallbackPlaySource::audioProcessingOverload() | 526 AudioCallbackPlaySource::audioProcessingOverload() |
527 { | 527 { |
528 std::cerr << "Audio processing overload!" << std::endl; | 528 cerr << "Audio processing overload!" << endl; |
529 | 529 |
530 if (!m_playing) return; | 530 if (!m_playing) return; |
531 | 531 |
532 RealTimePluginInstance *ap = m_auditioningPlugin; | 532 RealTimePluginInstance *ap = m_auditioningPlugin; |
533 if (ap && !m_auditioningPluginBypassed) { | 533 if (ap && !m_auditioningPluginBypassed) { |
548 | 548 |
549 void | 549 void |
550 AudioCallbackPlaySource::setTarget(AudioCallbackPlayTarget *target, size_t size) | 550 AudioCallbackPlaySource::setTarget(AudioCallbackPlayTarget *target, size_t size) |
551 { | 551 { |
552 m_target = target; | 552 m_target = target; |
553 std::cout << "AudioCallbackPlaySource::setTarget: Block size -> " << size << std::endl; | 553 cout << "AudioCallbackPlaySource::setTarget: Block size -> " << size << endl; |
554 if (size != 0) { | 554 if (size != 0) { |
555 m_blockSize = size; | 555 m_blockSize = size; |
556 } | 556 } |
557 if (size * 4 > m_ringBufferSize) { | 557 if (size * 4 > m_ringBufferSize) { |
558 SVDEBUG << "AudioCallbackPlaySource::setTarget: Buffer size " | 558 SVDEBUG << "AudioCallbackPlaySource::setTarget: Buffer size " |
567 } | 567 } |
568 | 568 |
569 size_t | 569 size_t |
570 AudioCallbackPlaySource::getTargetBlockSize() const | 570 AudioCallbackPlaySource::getTargetBlockSize() const |
571 { | 571 { |
572 // std::cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << std::endl; | 572 // cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << endl; |
573 return m_blockSize; | 573 return m_blockSize; |
574 } | 574 } |
575 | 575 |
576 void | 576 void |
577 AudioCallbackPlaySource::setTargetPlayLatency(size_t latency) | 577 AudioCallbackPlaySource::setTargetPlayLatency(size_t latency) |
696 sincerequest_t = sincerequest_t / timeRatio; | 696 sincerequest_t = sincerequest_t / timeRatio; |
697 latency_t = latency_t / timeRatio; | 697 latency_t = latency_t / timeRatio; |
698 } | 698 } |
699 | 699 |
700 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 700 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
701 std::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 << std::endl; | 701 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; |
702 #endif | 702 #endif |
703 | 703 |
704 RealTime end = RealTime::frame2RealTime(m_lastModelEndFrame, sourceRate); | 704 RealTime end = RealTime::frame2RealTime(m_lastModelEndFrame, sourceRate); |
705 | 705 |
706 // Normally the range lists should contain at least one item each | 706 // Normally the range lists should contain at least one item each |
753 | 753 |
754 if (!m_playStartFramePassed) { | 754 if (!m_playStartFramePassed) { |
755 RealTime playstart_t = RealTime::frame2RealTime(m_playStartFrame, | 755 RealTime playstart_t = RealTime::frame2RealTime(m_playStartFrame, |
756 sourceRate); | 756 sourceRate); |
757 if (playing_t < playstart_t) { | 757 if (playing_t < playstart_t) { |
758 // std::cerr << "playing_t " << playing_t << " < playstart_t " | 758 // cerr << "playing_t " << playing_t << " < playstart_t " |
759 // << playstart_t << std::endl; | 759 // << playstart_t << endl; |
760 if (/*!!! sincerequest_t > RealTime::zeroTime && */ | 760 if (/*!!! sincerequest_t > RealTime::zeroTime && */ |
761 m_playStartedAt + latency_t + stretchlat_t < | 761 m_playStartedAt + latency_t + stretchlat_t < |
762 RealTime::fromSeconds(currentTime)) { | 762 RealTime::fromSeconds(currentTime)) { |
763 // std::cerr << "but we've been playing for long enough that I think we should disregard it (it probably results from loop wrapping)" << std::endl; | 763 // cerr << "but we've been playing for long enough that I think we should disregard it (it probably results from loop wrapping)" << endl; |
764 m_playStartFramePassed = true; | 764 m_playStartFramePassed = true; |
765 } else { | 765 } else { |
766 playing_t = playstart_t; | 766 playing_t = playstart_t; |
767 } | 767 } |
768 } else { | 768 } else { |
769 m_playStartFramePassed = true; | 769 m_playStartFramePassed = true; |
770 } | 770 } |
771 } | 771 } |
772 | 772 |
773 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 773 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
774 std::cerr << "playing_t " << playing_t; | 774 cerr << "playing_t " << playing_t; |
775 #endif | 775 #endif |
776 | 776 |
777 playing_t = playing_t - m_rangeStarts[inRange]; | 777 playing_t = playing_t - m_rangeStarts[inRange]; |
778 | 778 |
779 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 779 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
780 std::cerr << " as offset into range " << inRange << " (start =" << m_rangeStarts[inRange] << " duration =" << m_rangeDurations[inRange] << ") = " << playing_t << std::endl; | 780 cerr << " as offset into range " << inRange << " (start =" << m_rangeStarts[inRange] << " duration =" << m_rangeDurations[inRange] << ") = " << playing_t << endl; |
781 #endif | 781 #endif |
782 | 782 |
783 while (playing_t < RealTime::zeroTime) { | 783 while (playing_t < RealTime::zeroTime) { |
784 | 784 |
785 if (inRange == 0) { | 785 if (inRange == 0) { |
796 } | 796 } |
797 | 797 |
798 playing_t = playing_t + m_rangeStarts[inRange]; | 798 playing_t = playing_t + m_rangeStarts[inRange]; |
799 | 799 |
800 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 800 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
801 std::cerr << " playing time: " << playing_t << std::endl; | 801 cerr << " playing time: " << playing_t << endl; |
802 #endif | 802 #endif |
803 | 803 |
804 if (!looping) { | 804 if (!looping) { |
805 if (inRange == m_rangeStarts.size()-1 && | 805 if (inRange == m_rangeStarts.size()-1 && |
806 playing_t >= m_rangeStarts[inRange] + m_rangeDurations[inRange]) { | 806 playing_t >= m_rangeStarts[inRange] + m_rangeDurations[inRange]) { |
807 std::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" << std::endl; | 807 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; |
808 stop(); | 808 stop(); |
809 } | 809 } |
810 } | 810 } |
811 | 811 |
812 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; | 812 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; |
872 m_rangeStarts.push_back(RealTime::zeroTime); | 872 m_rangeStarts.push_back(RealTime::zeroTime); |
873 m_rangeDurations.push_back(end); | 873 m_rangeDurations.push_back(end); |
874 } | 874 } |
875 | 875 |
876 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 876 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
877 std::cerr << "Now have " << m_rangeStarts.size() << " play ranges" << std::endl; | 877 cerr << "Now have " << m_rangeStarts.size() << " play ranges" << endl; |
878 #endif | 878 #endif |
879 } | 879 } |
880 | 880 |
881 void | 881 void |
882 AudioCallbackPlaySource::setOutputLevels(float left, float right) | 882 AudioCallbackPlaySource::setOutputLevels(float left, float right) |
935 getTargetChannelCount(), | 935 getTargetChannelCount(), |
936 &err); | 936 &err); |
937 } | 937 } |
938 | 938 |
939 if (!m_converter || !m_crapConverter) { | 939 if (!m_converter || !m_crapConverter) { |
940 std::cerr | 940 cerr |
941 << "AudioCallbackPlaySource::setModel: ERROR in creating samplerate converter: " | 941 << "AudioCallbackPlaySource::setModel: ERROR in creating samplerate converter: " |
942 << src_strerror(err) << std::endl; | 942 << src_strerror(err) << endl; |
943 | 943 |
944 if (m_converter) { | 944 if (m_converter) { |
945 src_delete(m_converter); | 945 src_delete(m_converter); |
946 m_converter = 0; | 946 m_converter = 0; |
947 } | 947 } |
986 void | 986 void |
987 AudioCallbackPlaySource::setAuditioningEffect(Auditionable *a) | 987 AudioCallbackPlaySource::setAuditioningEffect(Auditionable *a) |
988 { | 988 { |
989 RealTimePluginInstance *plugin = dynamic_cast<RealTimePluginInstance *>(a); | 989 RealTimePluginInstance *plugin = dynamic_cast<RealTimePluginInstance *>(a); |
990 if (a && !plugin) { | 990 if (a && !plugin) { |
991 std::cerr << "WARNING: AudioCallbackPlaySource::setAuditioningEffect: auditionable object " << a << " is not a real-time plugin instance" << std::endl; | 991 cerr << "WARNING: AudioCallbackPlaySource::setAuditioningEffect: auditionable object " << a << " is not a real-time plugin instance" << endl; |
992 } | 992 } |
993 | 993 |
994 m_mutex.lock(); | 994 m_mutex.lock(); |
995 m_auditioningPlugin = plugin; | 995 m_auditioningPlugin = plugin; |
996 m_auditioningPluginBypassed = false; | 996 m_auditioningPluginBypassed = false; |
1098 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { | 1098 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { |
1099 | 1099 |
1100 RingBuffer<float> *rb = getReadRingBuffer(ch); | 1100 RingBuffer<float> *rb = getReadRingBuffer(ch); |
1101 | 1101 |
1102 if (!rb) { | 1102 if (!rb) { |
1103 std::cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: " | 1103 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: " |
1104 << "No ring buffer available for channel " << ch | 1104 << "No ring buffer available for channel " << ch |
1105 << ", returning no data here" << std::endl; | 1105 << ", returning no data here" << endl; |
1106 count = 0; | 1106 count = 0; |
1107 break; | 1107 break; |
1108 } | 1108 } |
1109 | 1109 |
1110 size_t rs = rb->getReadSpace(); | 1110 size_t rs = rb->getReadSpace(); |
1111 if (rs < count) { | 1111 if (rs < count) { |
1112 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1112 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1113 std::cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: " | 1113 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: " |
1114 << "Ring buffer for channel " << ch << " has only " | 1114 << "Ring buffer for channel " << ch << " has only " |
1115 << rs << " (of " << count << ") samples available (" | 1115 << rs << " (of " << count << ") samples available (" |
1116 << "ring buffer size is " << rb->getSize() << ", write " | 1116 << "ring buffer size is " << rb->getSize() << ", write " |
1117 << "space " << rb->getWriteSpace() << "), " | 1117 << "space " << rb->getWriteSpace() << "), " |
1118 << "reducing request size" << std::endl; | 1118 << "reducing request size" << endl; |
1119 #endif | 1119 #endif |
1120 count = rs; | 1120 count = rs; |
1121 } | 1121 } |
1122 } | 1122 } |
1123 | 1123 |
1128 | 1128 |
1129 float ratio = ts ? ts->getTimeRatio() : 1.f; | 1129 float ratio = ts ? ts->getTimeRatio() : 1.f; |
1130 | 1130 |
1131 if (ratio != m_stretchRatio) { | 1131 if (ratio != m_stretchRatio) { |
1132 if (!ts) { | 1132 if (!ts) { |
1133 std::cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: Time ratio change to " << m_stretchRatio << " is pending, but no stretcher is set" << std::endl; | 1133 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: Time ratio change to " << m_stretchRatio << " is pending, but no stretcher is set" << endl; |
1134 m_stretchRatio = 1.f; | 1134 m_stretchRatio = 1.f; |
1135 } else { | 1135 } else { |
1136 ts->setTimeRatio(m_stretchRatio); | 1136 ts->setTimeRatio(m_stretchRatio); |
1137 if (ms) ms->setTimeRatio(m_stretchRatio); | 1137 if (ms) ms->setTimeRatio(m_stretchRatio); |
1138 if (m_stretchRatio >= 1.0) m_stretchMono = false; | 1138 if (m_stretchRatio >= 1.0) m_stretchMono = false; |
1170 if (ch > 0) request = got; | 1170 if (ch > 0) request = got; |
1171 | 1171 |
1172 got = rb->read(buffer[ch], request); | 1172 got = rb->read(buffer[ch], request); |
1173 | 1173 |
1174 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 1174 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
1175 std::cout << "AudioCallbackPlaySource::getSamples: got " << got << " (of " << count << ") samples on channel " << ch << ", signalling for more (possibly)" << std::endl; | 1175 cout << "AudioCallbackPlaySource::getSamples: got " << got << " (of " << count << ") samples on channel " << ch << ", signalling for more (possibly)" << endl; |
1176 #endif | 1176 #endif |
1177 } | 1177 } |
1178 | 1178 |
1179 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { | 1179 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { |
1180 for (int i = got; i < count; ++i) { | 1180 for (int i = got; i < count; ++i) { |
1184 } | 1184 } |
1185 | 1185 |
1186 applyAuditioningEffect(count, buffer); | 1186 applyAuditioningEffect(count, buffer); |
1187 | 1187 |
1188 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1188 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1189 std::cout << "AudioCallbackPlaySource::getSamples: awakening thread" << std::endl; | 1189 cout << "AudioCallbackPlaySource::getSamples: awakening thread" << endl; |
1190 #endif | 1190 #endif |
1191 | 1191 |
1192 m_condition.wakeAll(); | 1192 m_condition.wakeAll(); |
1193 | 1193 |
1194 return got; | 1194 return got; |
1209 if (reqd == 0) reqd = 1; | 1209 if (reqd == 0) reqd = 1; |
1210 | 1210 |
1211 size_t got = reqd; | 1211 size_t got = reqd; |
1212 | 1212 |
1213 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 1213 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
1214 std::cerr << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << std::endl; | 1214 cerr << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << endl; |
1215 #endif | 1215 #endif |
1216 | 1216 |
1217 for (size_t c = 0; c < channels; ++c) { | 1217 for (size_t c = 0; c < channels; ++c) { |
1218 if (c >= m_stretcherInputCount) continue; | 1218 if (c >= m_stretcherInputCount) continue; |
1219 if (reqd > m_stretcherInputSizes[c]) { | 1219 if (reqd > m_stretcherInputSizes[c]) { |
1220 if (c == 0) { | 1220 if (c == 0) { |
1221 std::cerr << "WARNING: resizing stretcher input buffer from " << m_stretcherInputSizes[c] << " to " << (reqd * 2) << std::endl; | 1221 cerr << "WARNING: resizing stretcher input buffer from " << m_stretcherInputSizes[c] << " to " << (reqd * 2) << endl; |
1222 } | 1222 } |
1223 delete[] m_stretcherInputs[c]; | 1223 delete[] m_stretcherInputs[c]; |
1224 m_stretcherInputSizes[c] = reqd * 2; | 1224 m_stretcherInputSizes[c] = reqd * 2; |
1225 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]]; | 1225 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]]; |
1226 } | 1226 } |
1244 << ", " << rb->getReadSpace() << " remain" << endl; | 1244 << ", " << rb->getReadSpace() << " remain" << endl; |
1245 } | 1245 } |
1246 #endif | 1246 #endif |
1247 | 1247 |
1248 } else { | 1248 } else { |
1249 std::cerr << "WARNING: No ring buffer available for channel " << c << " in stretcher input block" << std::endl; | 1249 cerr << "WARNING: No ring buffer available for channel " << c << " in stretcher input block" << endl; |
1250 } | 1250 } |
1251 } | 1251 } |
1252 | 1252 |
1253 if (got < reqd) { | 1253 if (got < reqd) { |
1254 std::cerr << "WARNING: Read underrun in playback (" | 1254 cerr << "WARNING: Read underrun in playback (" |
1255 << got << " < " << reqd << ")" << std::endl; | 1255 << got << " < " << reqd << ")" << endl; |
1256 } | 1256 } |
1257 | 1257 |
1258 ts->process(m_stretcherInputs, got, false); | 1258 ts->process(m_stretcherInputs, got, false); |
1259 | 1259 |
1260 fedToStretcher += got; | 1260 fedToStretcher += got; |
1261 | 1261 |
1262 if (got == 0) break; | 1262 if (got == 0) break; |
1263 | 1263 |
1264 if (ts->available() == available) { | 1264 if (ts->available() == available) { |
1265 std::cerr << "WARNING: AudioCallbackPlaySource::getSamples: Added " << got << " samples to time stretcher, created no new available output samples (warned = " << warned << ")" << std::endl; | 1265 cerr << "WARNING: AudioCallbackPlaySource::getSamples: Added " << got << " samples to time stretcher, created no new available output samples (warned = " << warned << ")" << endl; |
1266 if (++warned == 5) break; | 1266 if (++warned == 5) break; |
1267 } | 1267 } |
1268 } | 1268 } |
1269 | 1269 |
1270 ts->retrieve(buffer, count); | 1270 ts->retrieve(buffer, count); |
1276 } | 1276 } |
1277 | 1277 |
1278 applyAuditioningEffect(count, buffer); | 1278 applyAuditioningEffect(count, buffer); |
1279 | 1279 |
1280 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1280 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1281 std::cout << "AudioCallbackPlaySource::getSamples [stretched]: awakening thread" << std::endl; | 1281 cout << "AudioCallbackPlaySource::getSamples [stretched]: awakening thread" << endl; |
1282 #endif | 1282 #endif |
1283 | 1283 |
1284 m_condition.wakeAll(); | 1284 m_condition.wakeAll(); |
1285 | 1285 |
1286 return count; | 1286 return count; |
1292 if (m_auditioningPluginBypassed) return; | 1292 if (m_auditioningPluginBypassed) return; |
1293 RealTimePluginInstance *plugin = m_auditioningPlugin; | 1293 RealTimePluginInstance *plugin = m_auditioningPlugin; |
1294 if (!plugin) return; | 1294 if (!plugin) return; |
1295 | 1295 |
1296 if (plugin->getAudioInputCount() != getTargetChannelCount()) { | 1296 if (plugin->getAudioInputCount() != getTargetChannelCount()) { |
1297 // std::cerr << "plugin input count " << plugin->getAudioInputCount() | 1297 // cerr << "plugin input count " << plugin->getAudioInputCount() |
1298 // << " != our channel count " << getTargetChannelCount() | 1298 // << " != our channel count " << getTargetChannelCount() |
1299 // << std::endl; | 1299 // << endl; |
1300 return; | 1300 return; |
1301 } | 1301 } |
1302 if (plugin->getAudioOutputCount() != getTargetChannelCount()) { | 1302 if (plugin->getAudioOutputCount() != getTargetChannelCount()) { |
1303 // std::cerr << "plugin output count " << plugin->getAudioOutputCount() | 1303 // cerr << "plugin output count " << plugin->getAudioOutputCount() |
1304 // << " != our channel count " << getTargetChannelCount() | 1304 // << " != our channel count " << getTargetChannelCount() |
1305 // << std::endl; | 1305 // << endl; |
1306 return; | 1306 return; |
1307 } | 1307 } |
1308 if (plugin->getBufferSize() < count) { | 1308 if (plugin->getBufferSize() < count) { |
1309 // std::cerr << "plugin buffer size " << plugin->getBufferSize() | 1309 // cerr << "plugin buffer size " << plugin->getBufferSize() |
1310 // << " < our block size " << count | 1310 // << " < our block size " << count |
1311 // << std::endl; | 1311 // << endl; |
1312 return; | 1312 return; |
1313 } | 1313 } |
1314 | 1314 |
1315 float **ib = plugin->getAudioInputBuffers(); | 1315 float **ib = plugin->getAudioInputBuffers(); |
1316 float **ob = plugin->getAudioOutputBuffers(); | 1316 float **ob = plugin->getAudioOutputBuffers(); |
1346 } | 1346 } |
1347 } | 1347 } |
1348 | 1348 |
1349 if (space == 0) { | 1349 if (space == 0) { |
1350 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1350 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1351 std::cout << "AudioCallbackPlaySourceFillThread: no space to fill" << std::endl; | 1351 cout << "AudioCallbackPlaySourceFillThread: no space to fill" << endl; |
1352 #endif | 1352 #endif |
1353 return false; | 1353 return false; |
1354 } | 1354 } |
1355 | 1355 |
1356 size_t f = m_writeBufferFill; | 1356 size_t f = m_writeBufferFill; |
1357 | 1357 |
1358 bool readWriteEqual = (m_readBuffers == m_writeBuffers); | 1358 bool readWriteEqual = (m_readBuffers == m_writeBuffers); |
1359 | 1359 |
1360 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1360 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1361 if (!readWriteEqual) { | 1361 if (!readWriteEqual) { |
1362 std::cout << "AudioCallbackPlaySourceFillThread: note read buffers != write buffers" << std::endl; | 1362 cout << "AudioCallbackPlaySourceFillThread: note read buffers != write buffers" << endl; |
1363 } | 1363 } |
1364 std::cout << "AudioCallbackPlaySourceFillThread: filling " << space << " frames" << std::endl; | 1364 cout << "AudioCallbackPlaySourceFillThread: filling " << space << " frames" << endl; |
1365 #endif | 1365 #endif |
1366 | 1366 |
1367 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1367 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1368 std::cout << "buffered to " << f << " already" << std::endl; | 1368 cout << "buffered to " << f << " already" << endl; |
1369 #endif | 1369 #endif |
1370 | 1370 |
1371 bool resample = (getSourceSampleRate() != getTargetSampleRate()); | 1371 bool resample = (getSourceSampleRate() != getTargetSampleRate()); |
1372 | 1372 |
1373 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1373 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1374 std::cout << (resample ? "" : "not ") << "resampling (source " << getSourceSampleRate() << ", target " << getTargetSampleRate() << ")" << std::endl; | 1374 cout << (resample ? "" : "not ") << "resampling (source " << getSourceSampleRate() << ", target " << getTargetSampleRate() << ")" << endl; |
1375 #endif | 1375 #endif |
1376 | 1376 |
1377 size_t channels = getTargetChannelCount(); | 1377 size_t channels = getTargetChannelCount(); |
1378 | 1378 |
1379 size_t orig = space; | 1379 size_t orig = space; |
1391 size_t generatorBlockSize = m_audioGenerator->getBlockSize(); | 1391 size_t generatorBlockSize = m_audioGenerator->getBlockSize(); |
1392 | 1392 |
1393 if (resample && !m_converter) { | 1393 if (resample && !m_converter) { |
1394 static bool warned = false; | 1394 static bool warned = false; |
1395 if (!warned) { | 1395 if (!warned) { |
1396 std::cerr << "WARNING: sample rates differ, but no converter available!" << std::endl; | 1396 cerr << "WARNING: sample rates differ, but no converter available!" << endl; |
1397 warned = true; | 1397 warned = true; |
1398 } | 1398 } |
1399 } | 1399 } |
1400 | 1400 |
1401 if (resample && m_converter) { | 1401 if (resample && m_converter) { |
1461 | 1461 |
1462 int err = 0; | 1462 int err = 0; |
1463 | 1463 |
1464 if (m_timeStretcher && m_timeStretcher->getTimeRatio() < 0.4) { | 1464 if (m_timeStretcher && m_timeStretcher->getTimeRatio() < 0.4) { |
1465 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1465 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1466 std::cout << "Using crappy converter" << std::endl; | 1466 cout << "Using crappy converter" << endl; |
1467 #endif | 1467 #endif |
1468 err = src_process(m_crapConverter, &data); | 1468 err = src_process(m_crapConverter, &data); |
1469 } else { | 1469 } else { |
1470 err = src_process(m_converter, &data); | 1470 err = src_process(m_converter, &data); |
1471 } | 1471 } |
1472 | 1472 |
1473 size_t toCopy = size_t(got * ratio + 0.1); | 1473 size_t toCopy = size_t(got * ratio + 0.1); |
1474 | 1474 |
1475 if (err) { | 1475 if (err) { |
1476 std::cerr | 1476 cerr |
1477 << "AudioCallbackPlaySourceFillThread: ERROR in samplerate conversion: " | 1477 << "AudioCallbackPlaySourceFillThread: ERROR in samplerate conversion: " |
1478 << src_strerror(err) << std::endl; | 1478 << src_strerror(err) << endl; |
1479 //!!! Then what? | 1479 //!!! Then what? |
1480 } else { | 1480 } else { |
1481 got = data.input_frames_used; | 1481 got = data.input_frames_used; |
1482 toCopy = data.output_frames_gen; | 1482 toCopy = data.output_frames_gen; |
1483 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1483 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1484 std::cout << "Resampled " << got << " frames to " << toCopy << " frames" << std::endl; | 1484 cout << "Resampled " << got << " frames to " << toCopy << " frames" << endl; |
1485 #endif | 1485 #endif |
1486 } | 1486 } |
1487 | 1487 |
1488 for (size_t c = 0; c < channels; ++c) { | 1488 for (size_t c = 0; c < channels; ++c) { |
1489 for (size_t i = 0; i < toCopy; ++i) { | 1489 for (size_t i = 0; i < toCopy; ++i) { |
1501 // space must be a multiple of generatorBlockSize | 1501 // space must be a multiple of generatorBlockSize |
1502 size_t reqSpace = space; | 1502 size_t reqSpace = space; |
1503 space = (reqSpace / generatorBlockSize) * generatorBlockSize; | 1503 space = (reqSpace / generatorBlockSize) * generatorBlockSize; |
1504 if (space == 0) { | 1504 if (space == 0) { |
1505 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1505 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1506 std::cout << "requested fill of " << reqSpace | 1506 cout << "requested fill of " << reqSpace |
1507 << " is less than generator block size of " | 1507 << " is less than generator block size of " |
1508 << generatorBlockSize << ", leaving it" << std::endl; | 1508 << generatorBlockSize << ", leaving it" << endl; |
1509 #endif | 1509 #endif |
1510 return false; | 1510 return false; |
1511 } | 1511 } |
1512 | 1512 |
1513 if (tmpSize < channels * space) { | 1513 if (tmpSize < channels * space) { |
1531 | 1531 |
1532 RingBuffer<float> *wb = getWriteRingBuffer(c); | 1532 RingBuffer<float> *wb = getWriteRingBuffer(c); |
1533 if (wb) { | 1533 if (wb) { |
1534 size_t actual = wb->write(bufferPtrs[c], got); | 1534 size_t actual = wb->write(bufferPtrs[c], got); |
1535 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1535 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1536 std::cout << "Wrote " << actual << " samples for ch " << c << ", now " | 1536 cout << "Wrote " << actual << " samples for ch " << c << ", now " |
1537 << wb->getReadSpace() << " to read" | 1537 << wb->getReadSpace() << " to read" |
1538 << std::endl; | 1538 << endl; |
1539 #endif | 1539 #endif |
1540 if (actual < got) { | 1540 if (actual < got) { |
1541 std::cerr << "WARNING: Buffer overrun in channel " << c | 1541 cerr << "WARNING: Buffer overrun in channel " << c |
1542 << ": wrote " << actual << " of " << got | 1542 << ": wrote " << actual << " of " << got |
1543 << " samples" << std::endl; | 1543 << " samples" << endl; |
1544 } | 1544 } |
1545 } | 1545 } |
1546 } | 1546 } |
1547 | 1547 |
1548 m_writeBufferFill = f; | 1548 m_writeBufferFill = f; |
1549 if (readWriteEqual) m_readBufferFill = f; | 1549 if (readWriteEqual) m_readBufferFill = f; |
1550 | 1550 |
1551 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1551 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1552 std::cout << "Read buffer fill is now " << m_readBufferFill << std::endl; | 1552 cout << "Read buffer fill is now " << m_readBufferFill << endl; |
1553 #endif | 1553 #endif |
1554 | 1554 |
1555 //!!! 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 | 1555 //!!! 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 |
1556 } | 1556 } |
1557 | 1557 |
1574 static float **chunkBufferPtrs = 0; | 1574 static float **chunkBufferPtrs = 0; |
1575 static size_t chunkBufferPtrCount = 0; | 1575 static size_t chunkBufferPtrCount = 0; |
1576 size_t channels = getTargetChannelCount(); | 1576 size_t channels = getTargetChannelCount(); |
1577 | 1577 |
1578 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1578 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1579 std::cout << "Selection playback: start " << frame << ", size " << count <<", channels " << channels << std::endl; | 1579 cout << "Selection playback: start " << frame << ", size " << count <<", channels " << channels << endl; |
1580 #endif | 1580 #endif |
1581 | 1581 |
1582 if (chunkBufferPtrCount < channels) { | 1582 if (chunkBufferPtrCount < channels) { |
1583 if (chunkBufferPtrs) delete[] chunkBufferPtrs; | 1583 if (chunkBufferPtrs) delete[] chunkBufferPtrs; |
1584 chunkBufferPtrs = new float *[channels]; | 1584 chunkBufferPtrs = new float *[channels]; |
1652 chunkSize = m_lastModelEndFrame - chunkStart; | 1652 chunkSize = m_lastModelEndFrame - chunkStart; |
1653 } | 1653 } |
1654 nextChunkStart = chunkStart + chunkSize; | 1654 nextChunkStart = chunkStart + chunkSize; |
1655 } | 1655 } |
1656 | 1656 |
1657 // std::cout << "chunkStart " << chunkStart << ", chunkSize " << chunkSize << ", nextChunkStart " << nextChunkStart << ", frame " << frame << ", count " << count << ", processed " << processed << std::endl; | 1657 // cout << "chunkStart " << chunkStart << ", chunkSize " << chunkSize << ", nextChunkStart " << nextChunkStart << ", frame " << frame << ", count " << count << ", processed " << processed << endl; |
1658 | 1658 |
1659 if (!chunkSize) { | 1659 if (!chunkSize) { |
1660 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1660 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1661 std::cout << "Ending selection playback at " << nextChunkStart << std::endl; | 1661 cout << "Ending selection playback at " << nextChunkStart << endl; |
1662 #endif | 1662 #endif |
1663 // We need to maintain full buffers so that the other | 1663 // We need to maintain full buffers so that the other |
1664 // thread can tell where it's got to in the playback -- so | 1664 // thread can tell where it's got to in the playback -- so |
1665 // return the full amount here | 1665 // return the full amount here |
1666 frame = frame + count; | 1666 frame = frame + count; |
1667 return count; | 1667 return count; |
1668 } | 1668 } |
1669 | 1669 |
1670 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1670 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1671 std::cout << "Selection playback: chunk at " << chunkStart << " -> " << nextChunkStart << " (size " << chunkSize << ")" << std::endl; | 1671 cout << "Selection playback: chunk at " << chunkStart << " -> " << nextChunkStart << " (size " << chunkSize << ")" << endl; |
1672 #endif | 1672 #endif |
1673 | 1673 |
1674 size_t got = 0; | 1674 size_t got = 0; |
1675 | 1675 |
1676 if (selectionSize < 100) { | 1676 if (selectionSize < 100) { |
1708 processed += chunkSize; | 1708 processed += chunkSize; |
1709 chunkStart = nextChunkStart; | 1709 chunkStart = nextChunkStart; |
1710 } | 1710 } |
1711 | 1711 |
1712 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1712 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1713 std::cout << "Returning selection playback " << processed << " frames to " << nextChunkStart << std::endl; | 1713 cout << "Returning selection playback " << processed << " frames to " << nextChunkStart << endl; |
1714 #endif | 1714 #endif |
1715 | 1715 |
1716 frame = nextChunkStart; | 1716 frame = nextChunkStart; |
1717 return processed; | 1717 return processed; |
1718 } | 1718 } |
1744 size_t rf = m_readBufferFill; | 1744 size_t rf = m_readBufferFill; |
1745 RingBuffer<float> *rb = getReadRingBuffer(0); | 1745 RingBuffer<float> *rb = getReadRingBuffer(0); |
1746 if (rb) { | 1746 if (rb) { |
1747 size_t rs = rb->getReadSpace(); | 1747 size_t rs = rb->getReadSpace(); |
1748 //!!! incorrect when in non-contiguous selection, see comments elsewhere | 1748 //!!! incorrect when in non-contiguous selection, see comments elsewhere |
1749 // std::cout << "rs = " << rs << std::endl; | 1749 // cout << "rs = " << rs << endl; |
1750 if (rs < rf) rf -= rs; | 1750 if (rs < rf) rf -= rs; |
1751 else rf = 0; | 1751 else rf = 0; |
1752 } | 1752 } |
1753 | 1753 |
1754 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 1754 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
1761 RingBuffer<float> *wb = getWriteRingBuffer(c); | 1761 RingBuffer<float> *wb = getWriteRingBuffer(c); |
1762 if (wb) { | 1762 if (wb) { |
1763 if (c == 0) { | 1763 if (c == 0) { |
1764 | 1764 |
1765 size_t wrs = wb->getReadSpace(); | 1765 size_t wrs = wb->getReadSpace(); |
1766 // std::cout << "wrs = " << wrs << std::endl; | 1766 // cout << "wrs = " << wrs << endl; |
1767 | 1767 |
1768 if (wrs < wf) wf -= wrs; | 1768 if (wrs < wf) wf -= wrs; |
1769 else wf = 0; | 1769 else wf = 0; |
1770 // std::cout << "wf = " << wf << std::endl; | 1770 // cout << "wf = " << wf << endl; |
1771 | 1771 |
1772 if (wf < rf) skip = rf - wf; | 1772 if (wf < rf) skip = rf - wf; |
1773 if (skip == 0) break; | 1773 if (skip == 0) break; |
1774 } | 1774 } |
1775 | 1775 |
1776 // std::cout << "skipping " << skip << std::endl; | 1776 // cout << "skipping " << skip << endl; |
1777 wb->skip(skip); | 1777 wb->skip(skip); |
1778 } | 1778 } |
1779 } | 1779 } |
1780 | 1780 |
1781 m_bufferScavenger.claim(m_readBuffers); | 1781 m_bufferScavenger.claim(m_readBuffers); |
1782 m_readBuffers = m_writeBuffers; | 1782 m_readBuffers = m_writeBuffers; |
1783 m_readBufferFill = m_writeBufferFill; | 1783 m_readBufferFill = m_writeBufferFill; |
1784 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 1784 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
1785 std::cerr << "unified" << std::endl; | 1785 cerr << "unified" << endl; |
1786 #endif | 1786 #endif |
1787 } | 1787 } |
1788 | 1788 |
1789 void | 1789 void |
1790 AudioCallbackPlaySource::FillThread::run() | 1790 AudioCallbackPlaySource::FillThread::run() |
1791 { | 1791 { |
1792 AudioCallbackPlaySource &s(m_source); | 1792 AudioCallbackPlaySource &s(m_source); |
1793 | 1793 |
1794 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1794 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1795 std::cout << "AudioCallbackPlaySourceFillThread starting" << std::endl; | 1795 cout << "AudioCallbackPlaySourceFillThread starting" << endl; |
1796 #endif | 1796 #endif |
1797 | 1797 |
1798 s.m_mutex.lock(); | 1798 s.m_mutex.lock(); |
1799 | 1799 |
1800 bool previouslyPlaying = s.m_playing; | 1800 bool previouslyPlaying = s.m_playing; |
1807 s.m_pluginScavenger.scavenge(); | 1807 s.m_pluginScavenger.scavenge(); |
1808 | 1808 |
1809 if (work && s.m_playing && s.getSourceSampleRate()) { | 1809 if (work && s.m_playing && s.getSourceSampleRate()) { |
1810 | 1810 |
1811 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1811 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1812 std::cout << "AudioCallbackPlaySourceFillThread: not waiting" << std::endl; | 1812 cout << "AudioCallbackPlaySourceFillThread: not waiting" << endl; |
1813 #endif | 1813 #endif |
1814 | 1814 |
1815 s.m_mutex.unlock(); | 1815 s.m_mutex.unlock(); |
1816 s.m_mutex.lock(); | 1816 s.m_mutex.lock(); |
1817 | 1817 |
1824 } | 1824 } |
1825 | 1825 |
1826 if (s.m_playing) ms /= 10; | 1826 if (s.m_playing) ms /= 10; |
1827 | 1827 |
1828 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1828 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1829 if (!s.m_playing) std::cout << std::endl; | 1829 if (!s.m_playing) cout << endl; |
1830 std::cout << "AudioCallbackPlaySourceFillThread: waiting for " << ms << "ms..." << std::endl; | 1830 cout << "AudioCallbackPlaySourceFillThread: waiting for " << ms << "ms..." << endl; |
1831 #endif | 1831 #endif |
1832 | 1832 |
1833 s.m_condition.wait(&s.m_mutex, size_t(ms)); | 1833 s.m_condition.wait(&s.m_mutex, size_t(ms)); |
1834 } | 1834 } |
1835 | 1835 |
1836 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1836 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1837 std::cout << "AudioCallbackPlaySourceFillThread: awoken" << std::endl; | 1837 cout << "AudioCallbackPlaySourceFillThread: awoken" << endl; |
1838 #endif | 1838 #endif |
1839 | 1839 |
1840 work = false; | 1840 work = false; |
1841 | 1841 |
1842 if (!s.getSourceSampleRate()) { | 1842 if (!s.getSourceSampleRate()) { |
1843 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1843 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1844 std::cout << "AudioCallbackPlaySourceFillThread: source sample rate is zero" << std::endl; | 1844 cout << "AudioCallbackPlaySourceFillThread: source sample rate is zero" << endl; |
1845 #endif | 1845 #endif |
1846 continue; | 1846 continue; |
1847 } | 1847 } |
1848 | 1848 |
1849 bool playing = s.m_playing; | 1849 bool playing = s.m_playing; |
1850 | 1850 |
1851 if (playing && !previouslyPlaying) { | 1851 if (playing && !previouslyPlaying) { |
1852 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1852 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1853 std::cout << "AudioCallbackPlaySourceFillThread: playback state changed, resetting" << std::endl; | 1853 cout << "AudioCallbackPlaySourceFillThread: playback state changed, resetting" << endl; |
1854 #endif | 1854 #endif |
1855 for (size_t c = 0; c < s.getTargetChannelCount(); ++c) { | 1855 for (size_t c = 0; c < s.getTargetChannelCount(); ++c) { |
1856 RingBuffer<float> *rb = s.getReadRingBuffer(c); | 1856 RingBuffer<float> *rb = s.getReadRingBuffer(c); |
1857 if (rb) rb->reset(); | 1857 if (rb) rb->reset(); |
1858 } | 1858 } |