Mercurial > hg > svapp
comparison audioio/AudioCallbackPlaySource.cpp @ 366:0876ea394902 warnfix_no_size_t
Remove size_t's, fix compiler warnings
author | Chris Cannam |
---|---|
date | Tue, 17 Jun 2014 16:23:06 +0100 |
parents | 055ff09f7a08 |
children | 1e4fa2007e61 |
comparison
equal
deleted
inserted
replaced
355:e7a3fa8f4eec | 366:0876ea394902 |
---|---|
35 #include <cassert> | 35 #include <cassert> |
36 | 36 |
37 //#define DEBUG_AUDIO_PLAY_SOURCE 1 | 37 //#define DEBUG_AUDIO_PLAY_SOURCE 1 |
38 //#define DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1 | 38 //#define DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1 |
39 | 39 |
40 static const size_t DEFAULT_RING_BUFFER_SIZE = 131071; | 40 static const int DEFAULT_RING_BUFFER_SIZE = 131071; |
41 | 41 |
42 AudioCallbackPlaySource::AudioCallbackPlaySource(ViewManagerBase *manager, | 42 AudioCallbackPlaySource::AudioCallbackPlaySource(ViewManagerBase *manager, |
43 QString clientName) : | 43 QString clientName) : |
44 m_viewManager(manager), | 44 m_viewManager(manager), |
45 m_audioGenerator(new AudioGenerator()), | 45 m_audioGenerator(new AudioGenerator()), |
125 | 125 |
126 delete m_writeBuffers; | 126 delete m_writeBuffers; |
127 | 127 |
128 delete m_audioGenerator; | 128 delete m_audioGenerator; |
129 | 129 |
130 for (size_t i = 0; i < m_stretcherInputCount; ++i) { | 130 for (int i = 0; i < m_stretcherInputCount; ++i) { |
131 delete[] m_stretcherInputs[i]; | 131 delete[] m_stretcherInputs[i]; |
132 } | 132 } |
133 delete[] m_stretcherInputSizes; | 133 delete[] m_stretcherInputSizes; |
134 delete[] m_stretcherInputs; | 134 delete[] m_stretcherInputs; |
135 | 135 |
157 m_lastModelEndFrame = model->getEndFrame(); | 157 m_lastModelEndFrame = model->getEndFrame(); |
158 } | 158 } |
159 | 159 |
160 bool buffersChanged = false, srChanged = false; | 160 bool buffersChanged = false, srChanged = false; |
161 | 161 |
162 size_t modelChannels = 1; | 162 int modelChannels = 1; |
163 DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(model); | 163 DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(model); |
164 if (dtvm) modelChannels = dtvm->getChannelCount(); | 164 if (dtvm) modelChannels = dtvm->getChannelCount(); |
165 if (modelChannels > m_sourceChannelCount) { | 165 if (modelChannels > m_sourceChannelCount) { |
166 m_sourceChannelCount = modelChannels; | 166 m_sourceChannelCount = modelChannels; |
167 } | 167 } |
218 srChanged = true; | 218 srChanged = true; |
219 } | 219 } |
220 } | 220 } |
221 } | 221 } |
222 | 222 |
223 if (!m_writeBuffers || (m_writeBuffers->size() < getTargetChannelCount())) { | 223 if (!m_writeBuffers || (int)m_writeBuffers->size() < getTargetChannelCount()) { |
224 clearRingBuffers(true, getTargetChannelCount()); | 224 clearRingBuffers(true, getTargetChannelCount()); |
225 buffersChanged = true; | 225 buffersChanged = true; |
226 } else { | 226 } else { |
227 if (canPlay) clearRingBuffers(true); | 227 if (canPlay) clearRingBuffers(true); |
228 } | 228 } |
253 | 253 |
254 if (buffersChanged || srChanged) { | 254 if (buffersChanged || srChanged) { |
255 emit modelReplaced(); | 255 emit modelReplaced(); |
256 } | 256 } |
257 | 257 |
258 connect(model, SIGNAL(modelChanged(size_t, size_t)), | 258 connect(model, SIGNAL(modelChanged(int, int)), |
259 this, SLOT(modelChanged(size_t, size_t))); | 259 this, SLOT(modelChanged(int, int))); |
260 | 260 |
261 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 261 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
262 cout << "AudioCallbackPlaySource::addModel: awakening thread" << endl; | 262 cout << "AudioCallbackPlaySource::addModel: awakening thread" << endl; |
263 #endif | 263 #endif |
264 | 264 |
265 m_condition.wakeAll(); | 265 m_condition.wakeAll(); |
266 } | 266 } |
267 | 267 |
268 void | 268 void |
269 AudioCallbackPlaySource::modelChanged(size_t startFrame, size_t endFrame) | 269 AudioCallbackPlaySource::modelChanged(int , int endFrame) |
270 { | 270 { |
271 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 271 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
272 SVDEBUG << "AudioCallbackPlaySource::modelChanged(" << startFrame << "," << endFrame << ")" << endl; | 272 SVDEBUG << "AudioCallbackPlaySource::modelChanged(" << startFrame << "," << endFrame << ")" << endl; |
273 #endif | 273 #endif |
274 if (endFrame > m_lastModelEndFrame) { | 274 if (endFrame > m_lastModelEndFrame) { |
284 | 284 |
285 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 285 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
286 cout << "AudioCallbackPlaySource::removeModel(" << model << ")" << endl; | 286 cout << "AudioCallbackPlaySource::removeModel(" << model << ")" << endl; |
287 #endif | 287 #endif |
288 | 288 |
289 disconnect(model, SIGNAL(modelChanged(size_t, size_t)), | 289 disconnect(model, SIGNAL(modelChanged(int, int)), |
290 this, SLOT(modelChanged(size_t, size_t))); | 290 this, SLOT(modelChanged(int, int))); |
291 | 291 |
292 m_models.erase(model); | 292 m_models.erase(model); |
293 | 293 |
294 if (m_models.empty()) { | 294 if (m_models.empty()) { |
295 if (m_converter) { | 295 if (m_converter) { |
299 m_crapConverter = 0; | 299 m_crapConverter = 0; |
300 } | 300 } |
301 m_sourceSampleRate = 0; | 301 m_sourceSampleRate = 0; |
302 } | 302 } |
303 | 303 |
304 size_t lastEnd = 0; | 304 int lastEnd = 0; |
305 for (std::set<Model *>::const_iterator i = m_models.begin(); | 305 for (std::set<Model *>::const_iterator i = m_models.begin(); |
306 i != m_models.end(); ++i) { | 306 i != m_models.end(); ++i) { |
307 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 307 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
308 cout << "AudioCallbackPlaySource::removeModel(" << model << "): checking end frame on model " << *i << endl; | 308 cout << "AudioCallbackPlaySource::removeModel(" << model << "): checking end frame on model " << *i << endl; |
309 #endif | 309 #endif |
349 | 349 |
350 clearRingBuffers(); | 350 clearRingBuffers(); |
351 } | 351 } |
352 | 352 |
353 void | 353 void |
354 AudioCallbackPlaySource::clearRingBuffers(bool haveLock, size_t count) | 354 AudioCallbackPlaySource::clearRingBuffers(bool haveLock, int count) |
355 { | 355 { |
356 if (!haveLock) m_mutex.lock(); | 356 if (!haveLock) m_mutex.lock(); |
357 | 357 |
358 rebuildRangeLists(); | 358 rebuildRangeLists(); |
359 | 359 |
367 delete m_writeBuffers; | 367 delete m_writeBuffers; |
368 } | 368 } |
369 | 369 |
370 m_writeBuffers = new RingBufferVector; | 370 m_writeBuffers = new RingBufferVector; |
371 | 371 |
372 for (size_t i = 0; i < count; ++i) { | 372 for (int i = 0; i < count; ++i) { |
373 m_writeBuffers->push_back(new RingBuffer<float>(m_ringBufferSize)); | 373 m_writeBuffers->push_back(new RingBuffer<float>(m_ringBufferSize)); |
374 } | 374 } |
375 | 375 |
376 // cout << "AudioCallbackPlaySource::clearRingBuffers: Created " | 376 // cout << "AudioCallbackPlaySource::clearRingBuffers: Created " |
377 // << count << " write buffers" << endl; | 377 // << count << " write buffers" << endl; |
380 m_mutex.unlock(); | 380 m_mutex.unlock(); |
381 } | 381 } |
382 } | 382 } |
383 | 383 |
384 void | 384 void |
385 AudioCallbackPlaySource::play(size_t startFrame) | 385 AudioCallbackPlaySource::play(int startFrame) |
386 { | 386 { |
387 if (m_viewManager->getPlaySelectionMode() && | 387 if (m_viewManager->getPlaySelectionMode() && |
388 !m_viewManager->getSelections().empty()) { | 388 !m_viewManager->getSelections().empty()) { |
389 | 389 |
390 SVDEBUG << "AudioCallbackPlaySource::play: constraining frame " << startFrame << " to selection = "; | 390 SVDEBUG << "AudioCallbackPlaySource::play: constraining frame " << startFrame << " to selection = "; |
423 m_monoStretcher->reset(); | 423 m_monoStretcher->reset(); |
424 } | 424 } |
425 | 425 |
426 m_readBufferFill = m_writeBufferFill = startFrame; | 426 m_readBufferFill = m_writeBufferFill = startFrame; |
427 if (m_readBuffers) { | 427 if (m_readBuffers) { |
428 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | 428 for (int c = 0; c < getTargetChannelCount(); ++c) { |
429 RingBuffer<float> *rb = getReadRingBuffer(c); | 429 RingBuffer<float> *rb = getReadRingBuffer(c); |
430 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 430 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
431 cerr << "reset ring buffer for channel " << c << endl; | 431 cerr << "reset ring buffer for channel " << c << endl; |
432 #endif | 432 #endif |
433 if (rb) rb->reset(); | 433 if (rb) rb->reset(); |
548 return; | 548 return; |
549 } | 549 } |
550 } | 550 } |
551 | 551 |
552 void | 552 void |
553 AudioCallbackPlaySource::setTarget(AudioCallbackPlayTarget *target, size_t size) | 553 AudioCallbackPlaySource::setTarget(AudioCallbackPlayTarget *target, int size) |
554 { | 554 { |
555 m_target = target; | 555 m_target = target; |
556 cout << "AudioCallbackPlaySource::setTarget: Block size -> " << size << endl; | 556 cout << "AudioCallbackPlaySource::setTarget: Block size -> " << size << endl; |
557 if (size != 0) { | 557 if (size != 0) { |
558 m_blockSize = size; | 558 m_blockSize = size; |
567 clearRingBuffers(); | 567 clearRingBuffers(); |
568 } | 568 } |
569 } | 569 } |
570 } | 570 } |
571 | 571 |
572 size_t | 572 int |
573 AudioCallbackPlaySource::getTargetBlockSize() const | 573 AudioCallbackPlaySource::getTargetBlockSize() const |
574 { | 574 { |
575 // cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << endl; | 575 // cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << endl; |
576 return m_blockSize; | 576 return m_blockSize; |
577 } | 577 } |
578 | 578 |
579 void | 579 void |
580 AudioCallbackPlaySource::setTargetPlayLatency(size_t latency) | 580 AudioCallbackPlaySource::setTargetPlayLatency(int latency) |
581 { | 581 { |
582 m_playLatency = latency; | 582 m_playLatency = latency; |
583 } | 583 } |
584 | 584 |
585 size_t | 585 int |
586 AudioCallbackPlaySource::getTargetPlayLatency() const | 586 AudioCallbackPlaySource::getTargetPlayLatency() const |
587 { | 587 { |
588 return m_playLatency; | 588 return m_playLatency; |
589 } | 589 } |
590 | 590 |
591 size_t | 591 int |
592 AudioCallbackPlaySource::getCurrentPlayingFrame() | 592 AudioCallbackPlaySource::getCurrentPlayingFrame() |
593 { | 593 { |
594 // This method attempts to estimate which audio sample frame is | 594 // This method attempts to estimate which audio sample frame is |
595 // "currently coming through the speakers". | 595 // "currently coming through the speakers". |
596 | 596 |
597 size_t targetRate = getTargetSampleRate(); | 597 int targetRate = getTargetSampleRate(); |
598 size_t latency = m_playLatency; // at target rate | 598 int latency = m_playLatency; // at target rate |
599 RealTime latency_t = RealTime::frame2RealTime(latency, targetRate); | 599 RealTime latency_t = RealTime::frame2RealTime(latency, targetRate); |
600 | 600 |
601 return getCurrentFrame(latency_t); | 601 return getCurrentFrame(latency_t); |
602 } | 602 } |
603 | 603 |
604 size_t | 604 int |
605 AudioCallbackPlaySource::getCurrentBufferedFrame() | 605 AudioCallbackPlaySource::getCurrentBufferedFrame() |
606 { | 606 { |
607 return getCurrentFrame(RealTime::zeroTime); | 607 return getCurrentFrame(RealTime::zeroTime); |
608 } | 608 } |
609 | 609 |
610 size_t | 610 int |
611 AudioCallbackPlaySource::getCurrentFrame(RealTime latency_t) | 611 AudioCallbackPlaySource::getCurrentFrame(RealTime latency_t) |
612 { | 612 { |
613 bool resample = false; | |
614 double resampleRatio = 1.0; | |
615 | |
616 // We resample when filling the ring buffer, and time-stretch when | 613 // We resample when filling the ring buffer, and time-stretch when |
617 // draining it. The buffer contains data at the "target rate" and | 614 // draining it. The buffer contains data at the "target rate" and |
618 // the latency provided by the target is also at the target rate. | 615 // the latency provided by the target is also at the target rate. |
619 // Because of the multiple rates involved, we do the actual | 616 // Because of the multiple rates involved, we do the actual |
620 // calculation using RealTime instead. | 617 // calculation using RealTime instead. |
621 | 618 |
622 size_t sourceRate = getSourceSampleRate(); | 619 int sourceRate = getSourceSampleRate(); |
623 size_t targetRate = getTargetSampleRate(); | 620 int targetRate = getTargetSampleRate(); |
624 | 621 |
625 if (sourceRate == 0 || targetRate == 0) return 0; | 622 if (sourceRate == 0 || targetRate == 0) return 0; |
626 | 623 |
627 size_t inbuffer = 0; // at target rate | 624 int inbuffer = 0; // at target rate |
628 | 625 |
629 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | 626 for (int c = 0; c < getTargetChannelCount(); ++c) { |
630 RingBuffer<float> *rb = getReadRingBuffer(c); | 627 RingBuffer<float> *rb = getReadRingBuffer(c); |
631 if (rb) { | 628 if (rb) { |
632 size_t here = rb->getReadSpace(); | 629 int here = rb->getReadSpace(); |
633 if (c == 0 || here < inbuffer) inbuffer = here; | 630 if (c == 0 || here < inbuffer) inbuffer = here; |
634 } | 631 } |
635 } | 632 } |
636 | 633 |
637 size_t readBufferFill = m_readBufferFill; | 634 int readBufferFill = m_readBufferFill; |
638 size_t lastRetrievedBlockSize = m_lastRetrievedBlockSize; | 635 int lastRetrievedBlockSize = m_lastRetrievedBlockSize; |
639 double lastRetrievalTimestamp = m_lastRetrievalTimestamp; | 636 double lastRetrievalTimestamp = m_lastRetrievalTimestamp; |
640 double currentTime = 0.0; | 637 double currentTime = 0.0; |
641 if (m_target) currentTime = m_target->getCurrentTime(); | 638 if (m_target) currentTime = m_target->getCurrentTime(); |
642 | 639 |
643 bool looping = m_viewManager->getPlayLoopMode(); | 640 bool looping = m_viewManager->getPlayLoopMode(); |
644 | 641 |
645 RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, targetRate); | 642 RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, targetRate); |
646 | 643 |
647 size_t stretchlat = 0; | 644 int stretchlat = 0; |
648 double timeRatio = 1.0; | 645 double timeRatio = 1.0; |
649 | 646 |
650 if (m_timeStretcher) { | 647 if (m_timeStretcher) { |
651 stretchlat = m_timeStretcher->getLatency(); | 648 stretchlat = m_timeStretcher->getLatency(); |
652 timeRatio = m_timeStretcher->getTimeRatio(); | 649 timeRatio = m_timeStretcher->getTimeRatio(); |
702 | 699 |
703 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 700 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
704 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; | 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; |
705 #endif | 702 #endif |
706 | 703 |
707 RealTime end = RealTime::frame2RealTime(m_lastModelEndFrame, sourceRate); | |
708 | |
709 // Normally the range lists should contain at least one item each | 704 // Normally the range lists should contain at least one item each |
710 // -- if playback is unconstrained, that item should report the | 705 // -- if playback is unconstrained, that item should report the |
711 // entire source audio duration. | 706 // entire source audio duration. |
712 | 707 |
713 if (m_rangeStarts.empty()) { | 708 if (m_rangeStarts.empty()) { |
718 // this code is only used in case of error in rebuildRangeLists | 713 // this code is only used in case of error in rebuildRangeLists |
719 RealTime playing_t = bufferedto_t | 714 RealTime playing_t = bufferedto_t |
720 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t | 715 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t |
721 + sincerequest_t; | 716 + sincerequest_t; |
722 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; | 717 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; |
723 size_t frame = RealTime::realTime2Frame(playing_t, sourceRate); | 718 int frame = RealTime::realTime2Frame(playing_t, sourceRate); |
724 return m_viewManager->alignPlaybackFrameToReference(frame); | 719 return m_viewManager->alignPlaybackFrameToReference(frame); |
725 } | 720 } |
726 | 721 |
727 int inRange = 0; | 722 int inRange = 0; |
728 int index = 0; | 723 int index = 0; |
729 | 724 |
730 for (size_t i = 0; i < m_rangeStarts.size(); ++i) { | 725 for (int i = 0; i < (int)m_rangeStarts.size(); ++i) { |
731 if (bufferedto_t >= m_rangeStarts[i]) { | 726 if (bufferedto_t >= m_rangeStarts[i]) { |
732 inRange = index; | 727 inRange = index; |
733 } else { | 728 } else { |
734 break; | 729 break; |
735 } | 730 } |
736 ++index; | 731 ++index; |
737 } | 732 } |
738 | 733 |
739 if (inRange >= m_rangeStarts.size()) inRange = m_rangeStarts.size()-1; | 734 if (inRange >= (int)m_rangeStarts.size()) inRange = m_rangeStarts.size()-1; |
740 | 735 |
741 RealTime playing_t = bufferedto_t; | 736 RealTime playing_t = bufferedto_t; |
742 | 737 |
743 playing_t = playing_t | 738 playing_t = playing_t |
744 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t | 739 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t |
803 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 798 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
804 cerr << " playing time: " << playing_t << endl; | 799 cerr << " playing time: " << playing_t << endl; |
805 #endif | 800 #endif |
806 | 801 |
807 if (!looping) { | 802 if (!looping) { |
808 if (inRange == m_rangeStarts.size()-1 && | 803 if (inRange == (int)m_rangeStarts.size()-1 && |
809 playing_t >= m_rangeStarts[inRange] + m_rangeDurations[inRange]) { | 804 playing_t >= m_rangeStarts[inRange] + m_rangeDurations[inRange]) { |
810 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; | 805 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; |
811 stop(); | 806 stop(); |
812 } | 807 } |
813 } | 808 } |
814 | 809 |
815 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; | 810 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; |
816 | 811 |
817 size_t frame = RealTime::realTime2Frame(playing_t, sourceRate); | 812 int frame = RealTime::realTime2Frame(playing_t, sourceRate); |
818 | 813 |
819 if (m_lastCurrentFrame > 0 && !looping) { | 814 if (m_lastCurrentFrame > 0 && !looping) { |
820 if (frame < m_lastCurrentFrame) { | 815 if (frame < m_lastCurrentFrame) { |
821 frame = m_lastCurrentFrame; | 816 frame = m_lastCurrentFrame; |
822 } | 817 } |
833 bool constrained = (m_viewManager->getPlaySelectionMode()); | 828 bool constrained = (m_viewManager->getPlaySelectionMode()); |
834 | 829 |
835 m_rangeStarts.clear(); | 830 m_rangeStarts.clear(); |
836 m_rangeDurations.clear(); | 831 m_rangeDurations.clear(); |
837 | 832 |
838 size_t sourceRate = getSourceSampleRate(); | 833 int sourceRate = getSourceSampleRate(); |
839 if (sourceRate == 0) return; | 834 if (sourceRate == 0) return; |
840 | 835 |
841 RealTime end = RealTime::frame2RealTime(m_lastModelEndFrame, sourceRate); | 836 RealTime end = RealTime::frame2RealTime(m_lastModelEndFrame, sourceRate); |
842 if (end == RealTime::zeroTime) return; | 837 if (end == RealTime::zeroTime) return; |
843 | 838 |
895 right = m_outputRight; | 890 right = m_outputRight; |
896 return true; | 891 return true; |
897 } | 892 } |
898 | 893 |
899 void | 894 void |
900 AudioCallbackPlaySource::setTargetSampleRate(size_t sr) | 895 AudioCallbackPlaySource::setTargetSampleRate(int sr) |
901 { | 896 { |
902 bool first = (m_targetSampleRate == 0); | 897 bool first = (m_targetSampleRate == 0); |
903 | 898 |
904 m_targetSampleRate = sr; | 899 m_targetSampleRate = sr; |
905 initialiseConverter(); | 900 initialiseConverter(); |
1012 { | 1007 { |
1013 m_audioGenerator->clearSoloModelSet(); | 1008 m_audioGenerator->clearSoloModelSet(); |
1014 clearRingBuffers(); | 1009 clearRingBuffers(); |
1015 } | 1010 } |
1016 | 1011 |
1017 size_t | 1012 int |
1018 AudioCallbackPlaySource::getTargetSampleRate() const | 1013 AudioCallbackPlaySource::getTargetSampleRate() const |
1019 { | 1014 { |
1020 if (m_targetSampleRate) return m_targetSampleRate; | 1015 if (m_targetSampleRate) return m_targetSampleRate; |
1021 else return getSourceSampleRate(); | 1016 else return getSourceSampleRate(); |
1022 } | 1017 } |
1023 | 1018 |
1024 size_t | 1019 int |
1025 AudioCallbackPlaySource::getSourceChannelCount() const | 1020 AudioCallbackPlaySource::getSourceChannelCount() const |
1026 { | 1021 { |
1027 return m_sourceChannelCount; | 1022 return m_sourceChannelCount; |
1028 } | 1023 } |
1029 | 1024 |
1030 size_t | 1025 int |
1031 AudioCallbackPlaySource::getTargetChannelCount() const | 1026 AudioCallbackPlaySource::getTargetChannelCount() const |
1032 { | 1027 { |
1033 if (m_sourceChannelCount < 2) return 2; | 1028 if (m_sourceChannelCount < 2) return 2; |
1034 return m_sourceChannelCount; | 1029 return m_sourceChannelCount; |
1035 } | 1030 } |
1036 | 1031 |
1037 size_t | 1032 int |
1038 AudioCallbackPlaySource::getSourceSampleRate() const | 1033 AudioCallbackPlaySource::getSourceSampleRate() const |
1039 { | 1034 { |
1040 return m_sourceSampleRate; | 1035 return m_sourceSampleRate; |
1041 } | 1036 } |
1042 | 1037 |
1060 (getTargetSampleRate(), | 1055 (getTargetSampleRate(), |
1061 1, | 1056 1, |
1062 RubberBandStretcher::OptionProcessRealTime, | 1057 RubberBandStretcher::OptionProcessRealTime, |
1063 factor); | 1058 factor); |
1064 m_stretcherInputs = new float *[m_stretcherInputCount]; | 1059 m_stretcherInputs = new float *[m_stretcherInputCount]; |
1065 m_stretcherInputSizes = new size_t[m_stretcherInputCount]; | 1060 m_stretcherInputSizes = new int[m_stretcherInputCount]; |
1066 for (size_t c = 0; c < m_stretcherInputCount; ++c) { | 1061 for (int c = 0; c < m_stretcherInputCount; ++c) { |
1067 m_stretcherInputSizes[c] = 16384; | 1062 m_stretcherInputSizes[c] = 16384; |
1068 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]]; | 1063 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]]; |
1069 } | 1064 } |
1070 m_monoStretcher = monoStretcher; | 1065 m_monoStretcher = monoStretcher; |
1071 m_timeStretcher = stretcher; | 1066 m_timeStretcher = stretcher; |
1072 } | 1067 } |
1073 | 1068 |
1074 emit activity(tr("Change time-stretch factor to %1").arg(factor)); | 1069 emit activity(tr("Change time-stretch factor to %1").arg(factor)); |
1075 } | 1070 } |
1076 | 1071 |
1077 size_t | 1072 int |
1078 AudioCallbackPlaySource::getSourceSamples(size_t ucount, float **buffer) | 1073 AudioCallbackPlaySource::getSourceSamples(int ucount, float **buffer) |
1079 { | 1074 { |
1080 int count = ucount; | 1075 int count = ucount; |
1081 | 1076 |
1082 if (!m_playing) { | 1077 if (!m_playing) { |
1083 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 1078 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
1084 SVDEBUG << "AudioCallbackPlaySource::getSourceSamples: Not playing" << endl; | 1079 SVDEBUG << "AudioCallbackPlaySource::getSourceSamples: Not playing" << endl; |
1085 #endif | 1080 #endif |
1086 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { | 1081 for (int ch = 0; ch < getTargetChannelCount(); ++ch) { |
1087 for (int i = 0; i < count; ++i) { | 1082 for (int i = 0; i < count; ++i) { |
1088 buffer[ch][i] = 0.0; | 1083 buffer[ch][i] = 0.0; |
1089 } | 1084 } |
1090 } | 1085 } |
1091 return 0; | 1086 return 0; |
1096 #endif | 1091 #endif |
1097 | 1092 |
1098 // Ensure that all buffers have at least the amount of data we | 1093 // Ensure that all buffers have at least the amount of data we |
1099 // need -- else reduce the size of our requests correspondingly | 1094 // need -- else reduce the size of our requests correspondingly |
1100 | 1095 |
1101 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { | 1096 for (int ch = 0; ch < getTargetChannelCount(); ++ch) { |
1102 | 1097 |
1103 RingBuffer<float> *rb = getReadRingBuffer(ch); | 1098 RingBuffer<float> *rb = getReadRingBuffer(ch); |
1104 | 1099 |
1105 if (!rb) { | 1100 if (!rb) { |
1106 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: " | 1101 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: " |
1108 << ", returning no data here" << endl; | 1103 << ", returning no data here" << endl; |
1109 count = 0; | 1104 count = 0; |
1110 break; | 1105 break; |
1111 } | 1106 } |
1112 | 1107 |
1113 size_t rs = rb->getReadSpace(); | 1108 int rs = rb->getReadSpace(); |
1114 if (rs < count) { | 1109 if (rs < count) { |
1115 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1110 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1116 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: " | 1111 cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: " |
1117 << "Ring buffer for channel " << ch << " has only " | 1112 << "Ring buffer for channel " << ch << " has only " |
1118 << rs << " (of " << count << ") samples available (" | 1113 << rs << " (of " << count << ") samples available (" |
1159 | 1154 |
1160 if (!ts || ratio == 1.f) { | 1155 if (!ts || ratio == 1.f) { |
1161 | 1156 |
1162 int got = 0; | 1157 int got = 0; |
1163 | 1158 |
1164 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { | 1159 for (int ch = 0; ch < getTargetChannelCount(); ++ch) { |
1165 | 1160 |
1166 RingBuffer<float> *rb = getReadRingBuffer(ch); | 1161 RingBuffer<float> *rb = getReadRingBuffer(ch); |
1167 | 1162 |
1168 if (rb) { | 1163 if (rb) { |
1169 | 1164 |
1170 // this is marginally more likely to leave our channels in | 1165 // this is marginally more likely to leave our channels in |
1171 // sync after a processing failure than just passing "count": | 1166 // sync after a processing failure than just passing "count": |
1172 size_t request = count; | 1167 int request = count; |
1173 if (ch > 0) request = got; | 1168 if (ch > 0) request = got; |
1174 | 1169 |
1175 got = rb->read(buffer[ch], request); | 1170 got = rb->read(buffer[ch], request); |
1176 | 1171 |
1177 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 1172 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
1178 cout << "AudioCallbackPlaySource::getSamples: got " << got << " (of " << count << ") samples on channel " << ch << ", signalling for more (possibly)" << endl; | 1173 cout << "AudioCallbackPlaySource::getSamples: got " << got << " (of " << count << ") samples on channel " << ch << ", signalling for more (possibly)" << endl; |
1179 #endif | 1174 #endif |
1180 } | 1175 } |
1181 | 1176 |
1182 for (size_t ch = 0; ch < getTargetChannelCount(); ++ch) { | 1177 for (int ch = 0; ch < getTargetChannelCount(); ++ch) { |
1183 for (int i = got; i < count; ++i) { | 1178 for (int i = got; i < count; ++i) { |
1184 buffer[ch][i] = 0.0; | 1179 buffer[ch][i] = 0.0; |
1185 } | 1180 } |
1186 } | 1181 } |
1187 } | 1182 } |
1195 m_condition.wakeAll(); | 1190 m_condition.wakeAll(); |
1196 | 1191 |
1197 return got; | 1192 return got; |
1198 } | 1193 } |
1199 | 1194 |
1200 size_t channels = getTargetChannelCount(); | 1195 int channels = getTargetChannelCount(); |
1201 size_t available; | 1196 int available; |
1202 int warned = 0; | 1197 int warned = 0; |
1203 size_t fedToStretcher = 0; | 1198 int fedToStretcher = 0; |
1204 | 1199 |
1205 // The input block for a given output is approx output / ratio, | 1200 // The input block for a given output is approx output / ratio, |
1206 // but we can't predict it exactly, for an adaptive timestretcher. | 1201 // but we can't predict it exactly, for an adaptive timestretcher. |
1207 | 1202 |
1208 while ((available = ts->available()) < count) { | 1203 while ((available = ts->available()) < count) { |
1209 | 1204 |
1210 size_t reqd = lrintf((count - available) / ratio); | 1205 int reqd = lrintf((count - available) / ratio); |
1211 reqd = std::max(reqd, ts->getSamplesRequired()); | 1206 reqd = std::max(reqd, (int)ts->getSamplesRequired()); |
1212 if (reqd == 0) reqd = 1; | 1207 if (reqd == 0) reqd = 1; |
1213 | 1208 |
1214 size_t got = reqd; | 1209 int got = reqd; |
1215 | 1210 |
1216 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 1211 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
1217 cerr << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << endl; | 1212 cerr << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << endl; |
1218 #endif | 1213 #endif |
1219 | 1214 |
1220 for (size_t c = 0; c < channels; ++c) { | 1215 for (int c = 0; c < channels; ++c) { |
1221 if (c >= m_stretcherInputCount) continue; | 1216 if (c >= m_stretcherInputCount) continue; |
1222 if (reqd > m_stretcherInputSizes[c]) { | 1217 if (reqd > m_stretcherInputSizes[c]) { |
1223 if (c == 0) { | 1218 if (c == 0) { |
1224 cerr << "WARNING: resizing stretcher input buffer from " << m_stretcherInputSizes[c] << " to " << (reqd * 2) << endl; | 1219 cerr << "WARNING: resizing stretcher input buffer from " << m_stretcherInputSizes[c] << " to " << (reqd * 2) << endl; |
1225 } | 1220 } |
1227 m_stretcherInputSizes[c] = reqd * 2; | 1222 m_stretcherInputSizes[c] = reqd * 2; |
1228 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]]; | 1223 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]]; |
1229 } | 1224 } |
1230 } | 1225 } |
1231 | 1226 |
1232 for (size_t c = 0; c < channels; ++c) { | 1227 for (int c = 0; c < channels; ++c) { |
1233 if (c >= m_stretcherInputCount) continue; | 1228 if (c >= m_stretcherInputCount) continue; |
1234 RingBuffer<float> *rb = getReadRingBuffer(c); | 1229 RingBuffer<float> *rb = getReadRingBuffer(c); |
1235 if (rb) { | 1230 if (rb) { |
1236 size_t gotHere; | 1231 int gotHere; |
1237 if (stretchChannels == 1 && c > 0) { | 1232 if (stretchChannels == 1 && c > 0) { |
1238 gotHere = rb->readAdding(m_stretcherInputs[0], got); | 1233 gotHere = rb->readAdding(m_stretcherInputs[0], got); |
1239 } else { | 1234 } else { |
1240 gotHere = rb->read(m_stretcherInputs[c], got); | 1235 gotHere = rb->read(m_stretcherInputs[c], got); |
1241 } | 1236 } |
1288 | 1283 |
1289 return count; | 1284 return count; |
1290 } | 1285 } |
1291 | 1286 |
1292 void | 1287 void |
1293 AudioCallbackPlaySource::applyAuditioningEffect(size_t count, float **buffers) | 1288 AudioCallbackPlaySource::applyAuditioningEffect(int count, float **buffers) |
1294 { | 1289 { |
1295 if (m_auditioningPluginBypassed) return; | 1290 if (m_auditioningPluginBypassed) return; |
1296 RealTimePluginInstance *plugin = m_auditioningPlugin; | 1291 RealTimePluginInstance *plugin = m_auditioningPlugin; |
1297 if (!plugin) return; | 1292 if (!plugin) return; |
1298 | 1293 |
1299 if (plugin->getAudioInputCount() != getTargetChannelCount()) { | 1294 if ((int)plugin->getAudioInputCount() != getTargetChannelCount()) { |
1300 // cerr << "plugin input count " << plugin->getAudioInputCount() | 1295 // cerr << "plugin input count " << plugin->getAudioInputCount() |
1301 // << " != our channel count " << getTargetChannelCount() | 1296 // << " != our channel count " << getTargetChannelCount() |
1302 // << endl; | 1297 // << endl; |
1303 return; | 1298 return; |
1304 } | 1299 } |
1305 if (plugin->getAudioOutputCount() != getTargetChannelCount()) { | 1300 if ((int)plugin->getAudioOutputCount() != getTargetChannelCount()) { |
1306 // cerr << "plugin output count " << plugin->getAudioOutputCount() | 1301 // cerr << "plugin output count " << plugin->getAudioOutputCount() |
1307 // << " != our channel count " << getTargetChannelCount() | 1302 // << " != our channel count " << getTargetChannelCount() |
1308 // << endl; | 1303 // << endl; |
1309 return; | 1304 return; |
1310 } | 1305 } |
1311 if (plugin->getBufferSize() < count) { | 1306 if ((int)plugin->getBufferSize() < count) { |
1312 // cerr << "plugin buffer size " << plugin->getBufferSize() | 1307 // cerr << "plugin buffer size " << plugin->getBufferSize() |
1313 // << " < our block size " << count | 1308 // << " < our block size " << count |
1314 // << endl; | 1309 // << endl; |
1315 return; | 1310 return; |
1316 } | 1311 } |
1317 | 1312 |
1318 float **ib = plugin->getAudioInputBuffers(); | 1313 float **ib = plugin->getAudioInputBuffers(); |
1319 float **ob = plugin->getAudioOutputBuffers(); | 1314 float **ob = plugin->getAudioOutputBuffers(); |
1320 | 1315 |
1321 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | 1316 for (int c = 0; c < getTargetChannelCount(); ++c) { |
1322 for (size_t i = 0; i < count; ++i) { | 1317 for (int i = 0; i < count; ++i) { |
1323 ib[c][i] = buffers[c][i]; | 1318 ib[c][i] = buffers[c][i]; |
1324 } | 1319 } |
1325 } | 1320 } |
1326 | 1321 |
1327 plugin->run(Vamp::RealTime::zeroTime, count); | 1322 plugin->run(Vamp::RealTime::zeroTime, count); |
1328 | 1323 |
1329 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | 1324 for (int c = 0; c < getTargetChannelCount(); ++c) { |
1330 for (size_t i = 0; i < count; ++i) { | 1325 for (int i = 0; i < count; ++i) { |
1331 buffers[c][i] = ob[c][i]; | 1326 buffers[c][i] = ob[c][i]; |
1332 } | 1327 } |
1333 } | 1328 } |
1334 } | 1329 } |
1335 | 1330 |
1336 // Called from fill thread, m_playing true, mutex held | 1331 // Called from fill thread, m_playing true, mutex held |
1337 bool | 1332 bool |
1338 AudioCallbackPlaySource::fillBuffers() | 1333 AudioCallbackPlaySource::fillBuffers() |
1339 { | 1334 { |
1340 static float *tmp = 0; | 1335 static float *tmp = 0; |
1341 static size_t tmpSize = 0; | 1336 static int tmpSize = 0; |
1342 | 1337 |
1343 size_t space = 0; | 1338 int space = 0; |
1344 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | 1339 for (int c = 0; c < getTargetChannelCount(); ++c) { |
1345 RingBuffer<float> *wb = getWriteRingBuffer(c); | 1340 RingBuffer<float> *wb = getWriteRingBuffer(c); |
1346 if (wb) { | 1341 if (wb) { |
1347 size_t spaceHere = wb->getWriteSpace(); | 1342 int spaceHere = wb->getWriteSpace(); |
1348 if (c == 0 || spaceHere < space) space = spaceHere; | 1343 if (c == 0 || spaceHere < space) space = spaceHere; |
1349 } | 1344 } |
1350 } | 1345 } |
1351 | 1346 |
1352 if (space == 0) { | 1347 if (space == 0) { |
1354 cout << "AudioCallbackPlaySourceFillThread: no space to fill" << endl; | 1349 cout << "AudioCallbackPlaySourceFillThread: no space to fill" << endl; |
1355 #endif | 1350 #endif |
1356 return false; | 1351 return false; |
1357 } | 1352 } |
1358 | 1353 |
1359 size_t f = m_writeBufferFill; | 1354 int f = m_writeBufferFill; |
1360 | 1355 |
1361 bool readWriteEqual = (m_readBuffers == m_writeBuffers); | 1356 bool readWriteEqual = (m_readBuffers == m_writeBuffers); |
1362 | 1357 |
1363 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1358 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1364 if (!readWriteEqual) { | 1359 if (!readWriteEqual) { |
1375 | 1370 |
1376 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1371 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1377 cout << (resample ? "" : "not ") << "resampling (source " << getSourceSampleRate() << ", target " << getTargetSampleRate() << ")" << endl; | 1372 cout << (resample ? "" : "not ") << "resampling (source " << getSourceSampleRate() << ", target " << getTargetSampleRate() << ")" << endl; |
1378 #endif | 1373 #endif |
1379 | 1374 |
1380 size_t channels = getTargetChannelCount(); | 1375 int channels = getTargetChannelCount(); |
1381 | 1376 |
1382 size_t orig = space; | 1377 int orig = space; |
1383 size_t got = 0; | 1378 int got = 0; |
1384 | 1379 |
1385 static float **bufferPtrs = 0; | 1380 static float **bufferPtrs = 0; |
1386 static size_t bufferPtrCount = 0; | 1381 static int bufferPtrCount = 0; |
1387 | 1382 |
1388 if (bufferPtrCount < channels) { | 1383 if (bufferPtrCount < channels) { |
1389 if (bufferPtrs) delete[] bufferPtrs; | 1384 if (bufferPtrs) delete[] bufferPtrs; |
1390 bufferPtrs = new float *[channels]; | 1385 bufferPtrs = new float *[channels]; |
1391 bufferPtrCount = channels; | 1386 bufferPtrCount = channels; |
1392 } | 1387 } |
1393 | 1388 |
1394 size_t generatorBlockSize = m_audioGenerator->getBlockSize(); | 1389 int generatorBlockSize = m_audioGenerator->getBlockSize(); |
1395 | 1390 |
1396 if (resample && !m_converter) { | 1391 if (resample && !m_converter) { |
1397 static bool warned = false; | 1392 static bool warned = false; |
1398 if (!warned) { | 1393 if (!warned) { |
1399 cerr << "WARNING: sample rates differ, but no converter available!" << endl; | 1394 cerr << "WARNING: sample rates differ, but no converter available!" << endl; |
1403 | 1398 |
1404 if (resample && m_converter) { | 1399 if (resample && m_converter) { |
1405 | 1400 |
1406 double ratio = | 1401 double ratio = |
1407 double(getTargetSampleRate()) / double(getSourceSampleRate()); | 1402 double(getTargetSampleRate()) / double(getSourceSampleRate()); |
1408 orig = size_t(orig / ratio + 0.1); | 1403 orig = int(orig / ratio + 0.1); |
1409 | 1404 |
1410 // orig must be a multiple of generatorBlockSize | 1405 // orig must be a multiple of generatorBlockSize |
1411 orig = (orig / generatorBlockSize) * generatorBlockSize; | 1406 orig = (orig / generatorBlockSize) * generatorBlockSize; |
1412 if (orig == 0) return false; | 1407 if (orig == 0) return false; |
1413 | 1408 |
1414 size_t work = std::max(orig, space); | 1409 int work = std::max(orig, space); |
1415 | 1410 |
1416 // We only allocate one buffer, but we use it in two halves. | 1411 // We only allocate one buffer, but we use it in two halves. |
1417 // We place the non-interleaved values in the second half of | 1412 // We place the non-interleaved values in the second half of |
1418 // the buffer (orig samples for channel 0, orig samples for | 1413 // the buffer (orig samples for channel 0, orig samples for |
1419 // channel 1 etc), and then interleave them into the first | 1414 // channel 1 etc), and then interleave them into the first |
1432 | 1427 |
1433 float *nonintlv = tmp + channels * work; | 1428 float *nonintlv = tmp + channels * work; |
1434 float *intlv = tmp; | 1429 float *intlv = tmp; |
1435 float *srcout = tmp + channels * work; | 1430 float *srcout = tmp + channels * work; |
1436 | 1431 |
1437 for (size_t c = 0; c < channels; ++c) { | 1432 for (int c = 0; c < channels; ++c) { |
1438 for (size_t i = 0; i < orig; ++i) { | 1433 for (int i = 0; i < orig; ++i) { |
1439 nonintlv[channels * i + c] = 0.0f; | 1434 nonintlv[channels * i + c] = 0.0f; |
1440 } | 1435 } |
1441 } | 1436 } |
1442 | 1437 |
1443 for (size_t c = 0; c < channels; ++c) { | 1438 for (int c = 0; c < channels; ++c) { |
1444 bufferPtrs[c] = nonintlv + c * orig; | 1439 bufferPtrs[c] = nonintlv + c * orig; |
1445 } | 1440 } |
1446 | 1441 |
1447 got = mixModels(f, orig, bufferPtrs); // also modifies f | 1442 got = mixModels(f, orig, bufferPtrs); // also modifies f |
1448 | 1443 |
1449 // and interleave into first half | 1444 // and interleave into first half |
1450 for (size_t c = 0; c < channels; ++c) { | 1445 for (int c = 0; c < channels; ++c) { |
1451 for (size_t i = 0; i < got; ++i) { | 1446 for (int i = 0; i < got; ++i) { |
1452 float sample = nonintlv[c * got + i]; | 1447 float sample = nonintlv[c * got + i]; |
1453 intlv[channels * i + c] = sample; | 1448 intlv[channels * i + c] = sample; |
1454 } | 1449 } |
1455 } | 1450 } |
1456 | 1451 |
1471 err = src_process(m_crapConverter, &data); | 1466 err = src_process(m_crapConverter, &data); |
1472 } else { | 1467 } else { |
1473 err = src_process(m_converter, &data); | 1468 err = src_process(m_converter, &data); |
1474 } | 1469 } |
1475 | 1470 |
1476 size_t toCopy = size_t(got * ratio + 0.1); | 1471 int toCopy = int(got * ratio + 0.1); |
1477 | 1472 |
1478 if (err) { | 1473 if (err) { |
1479 cerr | 1474 cerr |
1480 << "AudioCallbackPlaySourceFillThread: ERROR in samplerate conversion: " | 1475 << "AudioCallbackPlaySourceFillThread: ERROR in samplerate conversion: " |
1481 << src_strerror(err) << endl; | 1476 << src_strerror(err) << endl; |
1486 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1481 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1487 cout << "Resampled " << got << " frames to " << toCopy << " frames" << endl; | 1482 cout << "Resampled " << got << " frames to " << toCopy << " frames" << endl; |
1488 #endif | 1483 #endif |
1489 } | 1484 } |
1490 | 1485 |
1491 for (size_t c = 0; c < channels; ++c) { | 1486 for (int c = 0; c < channels; ++c) { |
1492 for (size_t i = 0; i < toCopy; ++i) { | 1487 for (int i = 0; i < toCopy; ++i) { |
1493 tmp[i] = srcout[channels * i + c]; | 1488 tmp[i] = srcout[channels * i + c]; |
1494 } | 1489 } |
1495 RingBuffer<float> *wb = getWriteRingBuffer(c); | 1490 RingBuffer<float> *wb = getWriteRingBuffer(c); |
1496 if (wb) wb->write(tmp, toCopy); | 1491 if (wb) wb->write(tmp, toCopy); |
1497 } | 1492 } |
1500 if (readWriteEqual) m_readBufferFill = f; | 1495 if (readWriteEqual) m_readBufferFill = f; |
1501 | 1496 |
1502 } else { | 1497 } else { |
1503 | 1498 |
1504 // space must be a multiple of generatorBlockSize | 1499 // space must be a multiple of generatorBlockSize |
1505 size_t reqSpace = space; | 1500 int reqSpace = space; |
1506 space = (reqSpace / generatorBlockSize) * generatorBlockSize; | 1501 space = (reqSpace / generatorBlockSize) * generatorBlockSize; |
1507 if (space == 0) { | 1502 if (space == 0) { |
1508 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1503 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1509 cout << "requested fill of " << reqSpace | 1504 cout << "requested fill of " << reqSpace |
1510 << " is less than generator block size of " | 1505 << " is less than generator block size of " |
1517 delete[] tmp; | 1512 delete[] tmp; |
1518 tmp = new float[channels * space]; | 1513 tmp = new float[channels * space]; |
1519 tmpSize = channels * space; | 1514 tmpSize = channels * space; |
1520 } | 1515 } |
1521 | 1516 |
1522 for (size_t c = 0; c < channels; ++c) { | 1517 for (int c = 0; c < channels; ++c) { |
1523 | 1518 |
1524 bufferPtrs[c] = tmp + c * space; | 1519 bufferPtrs[c] = tmp + c * space; |
1525 | 1520 |
1526 for (size_t i = 0; i < space; ++i) { | 1521 for (int i = 0; i < space; ++i) { |
1527 tmp[c * space + i] = 0.0f; | 1522 tmp[c * space + i] = 0.0f; |
1528 } | 1523 } |
1529 } | 1524 } |
1530 | 1525 |
1531 size_t got = mixModels(f, space, bufferPtrs); // also modifies f | 1526 int got = mixModels(f, space, bufferPtrs); // also modifies f |
1532 | 1527 |
1533 for (size_t c = 0; c < channels; ++c) { | 1528 for (int c = 0; c < channels; ++c) { |
1534 | 1529 |
1535 RingBuffer<float> *wb = getWriteRingBuffer(c); | 1530 RingBuffer<float> *wb = getWriteRingBuffer(c); |
1536 if (wb) { | 1531 if (wb) { |
1537 size_t actual = wb->write(bufferPtrs[c], got); | 1532 int actual = wb->write(bufferPtrs[c], got); |
1538 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1533 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1539 cout << "Wrote " << actual << " samples for ch " << c << ", now " | 1534 cout << "Wrote " << actual << " samples for ch " << c << ", now " |
1540 << wb->getReadSpace() << " to read" | 1535 << wb->getReadSpace() << " to read" |
1541 << endl; | 1536 << endl; |
1542 #endif | 1537 #endif |
1559 } | 1554 } |
1560 | 1555 |
1561 return true; | 1556 return true; |
1562 } | 1557 } |
1563 | 1558 |
1564 size_t | 1559 int |
1565 AudioCallbackPlaySource::mixModels(size_t &frame, size_t count, float **buffers) | 1560 AudioCallbackPlaySource::mixModels(int &frame, int count, float **buffers) |
1566 { | 1561 { |
1567 size_t processed = 0; | 1562 int processed = 0; |
1568 size_t chunkStart = frame; | 1563 int chunkStart = frame; |
1569 size_t chunkSize = count; | 1564 int chunkSize = count; |
1570 size_t selectionSize = 0; | 1565 int selectionSize = 0; |
1571 size_t nextChunkStart = chunkStart + chunkSize; | 1566 int nextChunkStart = chunkStart + chunkSize; |
1572 | 1567 |
1573 bool looping = m_viewManager->getPlayLoopMode(); | 1568 bool looping = m_viewManager->getPlayLoopMode(); |
1574 bool constrained = (m_viewManager->getPlaySelectionMode() && | 1569 bool constrained = (m_viewManager->getPlaySelectionMode() && |
1575 !m_viewManager->getSelections().empty()); | 1570 !m_viewManager->getSelections().empty()); |
1576 | 1571 |
1577 static float **chunkBufferPtrs = 0; | 1572 static float **chunkBufferPtrs = 0; |
1578 static size_t chunkBufferPtrCount = 0; | 1573 static int chunkBufferPtrCount = 0; |
1579 size_t channels = getTargetChannelCount(); | 1574 int channels = getTargetChannelCount(); |
1580 | 1575 |
1581 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1576 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1582 cout << "Selection playback: start " << frame << ", size " << count <<", channels " << channels << endl; | 1577 cout << "Selection playback: start " << frame << ", size " << count <<", channels " << channels << endl; |
1583 #endif | 1578 #endif |
1584 | 1579 |
1586 if (chunkBufferPtrs) delete[] chunkBufferPtrs; | 1581 if (chunkBufferPtrs) delete[] chunkBufferPtrs; |
1587 chunkBufferPtrs = new float *[channels]; | 1582 chunkBufferPtrs = new float *[channels]; |
1588 chunkBufferPtrCount = channels; | 1583 chunkBufferPtrCount = channels; |
1589 } | 1584 } |
1590 | 1585 |
1591 for (size_t c = 0; c < channels; ++c) { | 1586 for (int c = 0; c < channels; ++c) { |
1592 chunkBufferPtrs[c] = buffers[c]; | 1587 chunkBufferPtrs[c] = buffers[c]; |
1593 } | 1588 } |
1594 | 1589 |
1595 while (processed < count) { | 1590 while (processed < count) { |
1596 | 1591 |
1597 chunkSize = count - processed; | 1592 chunkSize = count - processed; |
1598 nextChunkStart = chunkStart + chunkSize; | 1593 nextChunkStart = chunkStart + chunkSize; |
1599 selectionSize = 0; | 1594 selectionSize = 0; |
1600 | 1595 |
1601 size_t fadeIn = 0, fadeOut = 0; | 1596 int fadeIn = 0, fadeOut = 0; |
1602 | 1597 |
1603 if (constrained) { | 1598 if (constrained) { |
1604 | 1599 |
1605 size_t rChunkStart = | 1600 int rChunkStart = |
1606 m_viewManager->alignPlaybackFrameToReference(chunkStart); | 1601 m_viewManager->alignPlaybackFrameToReference(chunkStart); |
1607 | 1602 |
1608 Selection selection = | 1603 Selection selection = |
1609 m_viewManager->getContainingSelection(rChunkStart, true); | 1604 m_viewManager->getContainingSelection(rChunkStart, true); |
1610 | 1605 |
1622 chunkSize = 0; | 1617 chunkSize = 0; |
1623 nextChunkStart = chunkStart; | 1618 nextChunkStart = chunkStart; |
1624 | 1619 |
1625 } else { | 1620 } else { |
1626 | 1621 |
1627 size_t sf = m_viewManager->alignReferenceToPlaybackFrame | 1622 int sf = m_viewManager->alignReferenceToPlaybackFrame |
1628 (selection.getStartFrame()); | 1623 (selection.getStartFrame()); |
1629 size_t ef = m_viewManager->alignReferenceToPlaybackFrame | 1624 int ef = m_viewManager->alignReferenceToPlaybackFrame |
1630 (selection.getEndFrame()); | 1625 (selection.getEndFrame()); |
1631 | 1626 |
1632 selectionSize = ef - sf; | 1627 selectionSize = ef - sf; |
1633 | 1628 |
1634 if (chunkStart < sf) { | 1629 if (chunkStart < sf) { |
1672 | 1667 |
1673 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1668 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1674 cout << "Selection playback: chunk at " << chunkStart << " -> " << nextChunkStart << " (size " << chunkSize << ")" << endl; | 1669 cout << "Selection playback: chunk at " << chunkStart << " -> " << nextChunkStart << " (size " << chunkSize << ")" << endl; |
1675 #endif | 1670 #endif |
1676 | 1671 |
1677 size_t got = 0; | |
1678 | |
1679 if (selectionSize < 100) { | 1672 if (selectionSize < 100) { |
1680 fadeIn = 0; | 1673 fadeIn = 0; |
1681 fadeOut = 0; | 1674 fadeOut = 0; |
1682 } else if (selectionSize < 300) { | 1675 } else if (selectionSize < 300) { |
1683 if (fadeIn > 0) fadeIn = 10; | 1676 if (fadeIn > 0) fadeIn = 10; |
1697 } | 1690 } |
1698 | 1691 |
1699 for (std::set<Model *>::iterator mi = m_models.begin(); | 1692 for (std::set<Model *>::iterator mi = m_models.begin(); |
1700 mi != m_models.end(); ++mi) { | 1693 mi != m_models.end(); ++mi) { |
1701 | 1694 |
1702 got = m_audioGenerator->mixModel(*mi, chunkStart, | 1695 (void) m_audioGenerator->mixModel(*mi, chunkStart, |
1703 chunkSize, chunkBufferPtrs, | 1696 chunkSize, chunkBufferPtrs, |
1704 fadeIn, fadeOut); | 1697 fadeIn, fadeOut); |
1705 } | 1698 } |
1706 | 1699 |
1707 for (size_t c = 0; c < channels; ++c) { | 1700 for (int c = 0; c < channels; ++c) { |
1708 chunkBufferPtrs[c] += chunkSize; | 1701 chunkBufferPtrs[c] += chunkSize; |
1709 } | 1702 } |
1710 | 1703 |
1711 processed += chunkSize; | 1704 processed += chunkSize; |
1712 chunkStart = nextChunkStart; | 1705 chunkStart = nextChunkStart; |
1724 AudioCallbackPlaySource::unifyRingBuffers() | 1717 AudioCallbackPlaySource::unifyRingBuffers() |
1725 { | 1718 { |
1726 if (m_readBuffers == m_writeBuffers) return; | 1719 if (m_readBuffers == m_writeBuffers) return; |
1727 | 1720 |
1728 // only unify if there will be something to read | 1721 // only unify if there will be something to read |
1729 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | 1722 for (int c = 0; c < getTargetChannelCount(); ++c) { |
1730 RingBuffer<float> *wb = getWriteRingBuffer(c); | 1723 RingBuffer<float> *wb = getWriteRingBuffer(c); |
1731 if (wb) { | 1724 if (wb) { |
1732 if (wb->getReadSpace() < m_blockSize * 2) { | 1725 if (wb->getReadSpace() < m_blockSize * 2) { |
1733 if ((m_writeBufferFill + m_blockSize * 2) < | 1726 if ((m_writeBufferFill + m_blockSize * 2) < |
1734 m_lastModelEndFrame) { | 1727 m_lastModelEndFrame) { |
1742 } | 1735 } |
1743 break; | 1736 break; |
1744 } | 1737 } |
1745 } | 1738 } |
1746 | 1739 |
1747 size_t rf = m_readBufferFill; | 1740 int rf = m_readBufferFill; |
1748 RingBuffer<float> *rb = getReadRingBuffer(0); | 1741 RingBuffer<float> *rb = getReadRingBuffer(0); |
1749 if (rb) { | 1742 if (rb) { |
1750 size_t rs = rb->getReadSpace(); | 1743 int rs = rb->getReadSpace(); |
1751 //!!! incorrect when in non-contiguous selection, see comments elsewhere | 1744 //!!! incorrect when in non-contiguous selection, see comments elsewhere |
1752 // cout << "rs = " << rs << endl; | 1745 // cout << "rs = " << rs << endl; |
1753 if (rs < rf) rf -= rs; | 1746 if (rs < rf) rf -= rs; |
1754 else rf = 0; | 1747 else rf = 0; |
1755 } | 1748 } |
1756 | 1749 |
1757 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 1750 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
1758 SVDEBUG << "AudioCallbackPlaySource::unifyRingBuffers: m_readBufferFill = " << m_readBufferFill << ", rf = " << rf << ", m_writeBufferFill = " << m_writeBufferFill << endl; | 1751 SVDEBUG << "AudioCallbackPlaySource::unifyRingBuffers: m_readBufferFill = " << m_readBufferFill << ", rf = " << rf << ", m_writeBufferFill = " << m_writeBufferFill << endl; |
1759 #endif | 1752 #endif |
1760 | 1753 |
1761 size_t wf = m_writeBufferFill; | 1754 int wf = m_writeBufferFill; |
1762 size_t skip = 0; | 1755 int skip = 0; |
1763 for (size_t c = 0; c < getTargetChannelCount(); ++c) { | 1756 for (int c = 0; c < getTargetChannelCount(); ++c) { |
1764 RingBuffer<float> *wb = getWriteRingBuffer(c); | 1757 RingBuffer<float> *wb = getWriteRingBuffer(c); |
1765 if (wb) { | 1758 if (wb) { |
1766 if (c == 0) { | 1759 if (c == 0) { |
1767 | 1760 |
1768 size_t wrs = wb->getReadSpace(); | 1761 int wrs = wb->getReadSpace(); |
1769 // cout << "wrs = " << wrs << endl; | 1762 // cout << "wrs = " << wrs << endl; |
1770 | 1763 |
1771 if (wrs < wf) wf -= wrs; | 1764 if (wrs < wf) wf -= wrs; |
1772 else wf = 0; | 1765 else wf = 0; |
1773 // cout << "wf = " << wf << endl; | 1766 // cout << "wf = " << wf << endl; |
1831 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1824 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1832 if (!s.m_playing) cout << endl; | 1825 if (!s.m_playing) cout << endl; |
1833 cout << "AudioCallbackPlaySourceFillThread: waiting for " << ms << "ms..." << endl; | 1826 cout << "AudioCallbackPlaySourceFillThread: waiting for " << ms << "ms..." << endl; |
1834 #endif | 1827 #endif |
1835 | 1828 |
1836 s.m_condition.wait(&s.m_mutex, size_t(ms)); | 1829 s.m_condition.wait(&s.m_mutex, int(ms)); |
1837 } | 1830 } |
1838 | 1831 |
1839 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1832 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1840 cout << "AudioCallbackPlaySourceFillThread: awoken" << endl; | 1833 cout << "AudioCallbackPlaySourceFillThread: awoken" << endl; |
1841 #endif | 1834 #endif |
1853 | 1846 |
1854 if (playing && !previouslyPlaying) { | 1847 if (playing && !previouslyPlaying) { |
1855 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1848 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1856 cout << "AudioCallbackPlaySourceFillThread: playback state changed, resetting" << endl; | 1849 cout << "AudioCallbackPlaySourceFillThread: playback state changed, resetting" << endl; |
1857 #endif | 1850 #endif |
1858 for (size_t c = 0; c < s.getTargetChannelCount(); ++c) { | 1851 for (int c = 0; c < s.getTargetChannelCount(); ++c) { |
1859 RingBuffer<float> *rb = s.getReadRingBuffer(c); | 1852 RingBuffer<float> *rb = s.getReadRingBuffer(c); |
1860 if (rb) rb->reset(); | 1853 if (rb) rb->reset(); |
1861 } | 1854 } |
1862 } | 1855 } |
1863 previouslyPlaying = playing; | 1856 previouslyPlaying = playing; |