1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Sonic Visualiser
5     An audio file viewer and annotation editor.
6     Centre for Digital Music, Queen Mary, University of London.
7     This file copyright 2006 Chris Cannam and QMUL.
8 
9     This program is free software; you can redistribute it and/or
10     modify it under the terms of the GNU General Public License as
11     published by the Free Software Foundation; either version 2 of the
12     License, or (at your option) any later version.  See the file
13     COPYING included with this distribution for more information.
14 */
15 
16 #include "AudioCallbackPlaySource.h"
17 
18 #include "AudioGenerator.h"
19 
20 #include "data/model/Model.h"
21 #include "base/ViewManagerBase.h"
22 #include "base/PlayParameterRepository.h"
23 #include "base/Preferences.h"
24 #include "data/model/DenseTimeValueModel.h"
25 #include "data/model/WaveFileModel.h"
26 #include "data/model/ReadOnlyWaveFileModel.h"
27 #include "data/model/SparseOneDimensionalModel.h"
28 #include "plugin/RealTimePluginInstance.h"
29 
30 #include "bqaudioio/SystemPlaybackTarget.h"
31 #include "bqaudioio/ResamplerWrapper.h"
32 
33 #include "bqvec/VectorOps.h"
34 
35 #include <rubberband/RubberBandStretcher.h>
36 using namespace RubberBand;
37 
38 using breakfastquay::v_zero_channels;
39 
40 #include <iostream>
41 #include <cassert>
42 
43 //#define DEBUG_AUDIO_PLAY_SOURCE 1
44 //#define DEBUG_AUDIO_PLAY_SOURCE_PLAYING 1
45 
46 static const int DEFAULT_RING_BUFFER_SIZE = 131071;
47 
AudioCallbackPlaySource(ViewManagerBase * manager,QString clientName)48 AudioCallbackPlaySource::AudioCallbackPlaySource(ViewManagerBase *manager,
49                                                  QString clientName) :
50     m_viewManager(manager),
51     m_audioGenerator(new AudioGenerator()),
52     m_clientName(clientName.toUtf8().data()),
53     m_readBuffers(nullptr),
54     m_writeBuffers(nullptr),
55     m_readBufferFill(0),
56     m_writeBufferFill(0),
57     m_bufferScavenger(1),
58     m_sourceChannelCount(0),
59     m_blockSize(1024),
60     m_sourceSampleRate(0),
61     m_deviceSampleRate(0),
62     m_deviceChannelCount(0),
63     m_playLatency(0),
64     m_target(nullptr),
65     m_lastRetrievalTimestamp(0.0),
66     m_lastRetrievedBlockSize(0),
67     m_trustworthyTimestamps(true),
68     m_lastCurrentFrame(0),
69     m_playing(false),
70     m_exiting(false),
71     m_lastModelEndFrame(0),
72     m_ringBufferSize(DEFAULT_RING_BUFFER_SIZE),
73     m_outputLeft(0.0),
74     m_outputRight(0.0),
75     m_levelsSet(false),
76     m_auditioningPlugin(nullptr),
77     m_auditioningPluginBypassed(false),
78     m_playStartFrame(0),
79     m_playStartFramePassed(false),
80     m_timeStretcher(nullptr),
81     m_monoStretcher(nullptr),
82     m_stretchRatio(1.0),
83     m_stretchMono(false),
84     m_stretcherInputCount(0),
85     m_stretcherInputs(nullptr),
86     m_stretcherInputSizes(nullptr),
87     m_fillThread(nullptr),
88     m_resamplerWrapper(nullptr)
89 {
90     m_viewManager->setAudioPlaySource(this);
91 
92     connect(m_viewManager, SIGNAL(selectionChanged()),
93             this, SLOT(selectionChanged()));
94     connect(m_viewManager, SIGNAL(playLoopModeChanged()),
95             this, SLOT(playLoopModeChanged()));
96     connect(m_viewManager, SIGNAL(playSelectionModeChanged()),
97             this, SLOT(playSelectionModeChanged()));
98 
99     connect(this, SIGNAL(playStatusChanged(bool)),
100             m_viewManager, SLOT(playStatusChanged(bool)));
101 
102     connect(PlayParameterRepository::getInstance(),
103             SIGNAL(playParametersChanged(int)),
104             this, SLOT(playParametersChanged(int)));
105 
106     connect(Preferences::getInstance(),
107             SIGNAL(propertyChanged(PropertyContainer::PropertyName)),
108             this, SLOT(preferenceChanged(PropertyContainer::PropertyName)));
109 }
110 
~AudioCallbackPlaySource()111 AudioCallbackPlaySource::~AudioCallbackPlaySource()
112 {
113 #ifdef DEBUG_AUDIO_PLAY_SOURCE
114     SVDEBUG << "AudioCallbackPlaySource::~AudioCallbackPlaySource entering" << endl;
115 #endif
116     m_exiting = true;
117 
118     if (m_fillThread) {
119 #ifdef DEBUG_AUDIO_PLAY_SOURCE
120     cout << "AudioCallbackPlaySource dtor: awakening thread" << endl;
121 #endif
122         m_condition.wakeAll();
123         m_fillThread->wait();
124         delete m_fillThread;
125     }
126 
127     clearModels();
128 
129     if (m_readBuffers != m_writeBuffers) {
130         delete m_readBuffers;
131     }
132 
133     delete m_writeBuffers;
134 
135     delete m_audioGenerator;
136 
137     for (int i = 0; i < m_stretcherInputCount; ++i) {
138         delete[] m_stretcherInputs[i];
139     }
140     delete[] m_stretcherInputSizes;
141     delete[] m_stretcherInputs;
142 
143     delete m_timeStretcher;
144     delete m_monoStretcher;
145 
146     m_bufferScavenger.scavenge(true);
147     m_pluginScavenger.scavenge(true);
148 #ifdef DEBUG_AUDIO_PLAY_SOURCE
149     SVDEBUG << "AudioCallbackPlaySource::~AudioCallbackPlaySource finishing" << endl;
150 #endif
151 }
152 
153 void
addModel(ModelId modelId)154 AudioCallbackPlaySource::addModel(ModelId modelId)
155 {
156     if (m_models.find(modelId) != m_models.end()) return;
157 
158     bool willPlay = m_audioGenerator->addModel(modelId);
159 
160     auto model = ModelById::get(modelId);
161     if (!model) return;
162 
163     m_mutex.lock();
164 
165     m_models.insert(modelId);
166 
167     if (model->getEndFrame() > m_lastModelEndFrame) {
168         m_lastModelEndFrame = model->getEndFrame();
169     }
170 
171     bool buffersIncreased = false, srChanged = false;
172 
173     int modelChannels = 1;
174     auto rowfm = std::dynamic_pointer_cast<ReadOnlyWaveFileModel>(model);
175     if (rowfm) modelChannels = rowfm->getChannelCount();
176     if (modelChannels > m_sourceChannelCount) {
177         m_sourceChannelCount = modelChannels;
178     }
179 
180 #ifdef DEBUG_AUDIO_PLAY_SOURCE
181     cout << "AudioCallbackPlaySource: Adding model with " << modelChannels << " channels at rate " << model->getSampleRate() << endl;
182 #endif
183 
184     if (m_sourceSampleRate == 0) {
185 
186         SVDEBUG << "AudioCallbackPlaySource::addModel: Source rate changing from 0 to "
187             << model->getSampleRate() << endl;
188 
189         m_sourceSampleRate = model->getSampleRate();
190         srChanged = true;
191 
192     } else if (model->getSampleRate() != m_sourceSampleRate) {
193 
194         // If this is a read-only wave file model and we have no
195         // other, we can just switch to this model's sample rate
196 
197         if (rowfm) {
198 
199             bool conflicting = false;
200 
201             for (ModelId otherId: m_models) {
202                 // Only read-only wave file models should be
203                 // considered conflicting -- writable wave file models
204                 // are derived and we shouldn't take their rates into
205                 // account.  Also, don't give any particular weight to
206                 // a file that's already playing at the wrong rate
207                 // anyway
208                 if (otherId == modelId) continue;
209                 auto other = ModelById::getAs<ReadOnlyWaveFileModel>(otherId);
210                 if (other &&
211                     other->getSampleRate() != model->getSampleRate() &&
212                     other->getSampleRate() == m_sourceSampleRate) {
213                     SVDEBUG << "AudioCallbackPlaySource::addModel: Conflicting wave file model " << otherId << " found" << endl;
214                     conflicting = true;
215                     break;
216                 }
217             }
218 
219             if (conflicting) {
220 
221                 SVCERR << "AudioCallbackPlaySource::addModel: ERROR: "
222                           << "New model sample rate does not match" << endl
223                           << "existing model(s) (new " << model->getSampleRate()
224                           << " vs " << m_sourceSampleRate
225                           << "), playback will be wrong"
226                           << endl;
227 
228                 emit sampleRateMismatch(model->getSampleRate(),
229                                         m_sourceSampleRate,
230                                         false);
231             } else {
232                 SVDEBUG << "AudioCallbackPlaySource::addModel: Source rate changing from "
233                         << m_sourceSampleRate << " to " << model->getSampleRate() << endl;
234 
235                 m_sourceSampleRate = model->getSampleRate();
236                 srChanged = true;
237             }
238         }
239     }
240 
241     if (!m_writeBuffers || (int)m_writeBuffers->size() < getTargetChannelCount()) {
242         cerr << "m_writeBuffers size = " << (m_writeBuffers ? m_writeBuffers->size() : 0) << endl;
243         cerr << "target channel count = " << (getTargetChannelCount()) << endl;
244         clearRingBuffers(true, getTargetChannelCount());
245         buffersIncreased = true;
246     } else {
247         if (willPlay) clearRingBuffers(true);
248     }
249 
250     if (srChanged) {
251 
252         SVCERR << "AudioCallbackPlaySource: Source rate changed" << endl;
253 
254         if (m_resamplerWrapper) {
255             SVCERR << "AudioCallbackPlaySource: Source sample rate changed to "
256                 << m_sourceSampleRate << ", updating resampler wrapper" << endl;
257             m_resamplerWrapper->changeApplicationSampleRate
258                 (int(round(m_sourceSampleRate)));
259             m_resamplerWrapper->reset();
260         }
261 
262         delete m_timeStretcher;
263         delete m_monoStretcher;
264         m_timeStretcher = nullptr;
265         m_monoStretcher = nullptr;
266 
267         if (m_stretchRatio != 1.f) {
268             setTimeStretch(m_stretchRatio);
269         }
270     }
271 
272     rebuildRangeLists();
273 
274     m_mutex.unlock();
275 
276     m_audioGenerator->setTargetChannelCount(getTargetChannelCount());
277 
278     if (buffersIncreased) {
279         SVDEBUG << "AudioCallbackPlaySource::addModel: Number of buffers increased to " << getTargetChannelCount() << endl;
280         if (getTargetChannelCount() > getDeviceChannelCount()) {
281             SVDEBUG << "AudioCallbackPlaySource::addModel: This is more than the device channel count, signalling channelCountIncreased" << endl;
282             emit channelCountIncreased(getTargetChannelCount());
283         } else {
284             SVDEBUG << "AudioCallbackPlaySource::addModel: This is no more than the device channel count (" << getDeviceChannelCount() << "), so taking no action" << endl;
285         }
286     }
287 
288     if (!m_fillThread) {
289         m_fillThread = new FillThread(*this);
290         m_fillThread->start();
291     }
292 
293 #ifdef DEBUG_AUDIO_PLAY_SOURCE
294     SVDEBUG << "AudioCallbackPlaySource::addModel: now have " << m_models.size() << " model(s)" << endl;
295 #endif
296 
297     connect(model.get(), SIGNAL(modelChangedWithin(ModelId, sv_frame_t, sv_frame_t)),
298             this, SLOT(modelChangedWithin(ModelId, sv_frame_t, sv_frame_t)));
299 
300 #ifdef DEBUG_AUDIO_PLAY_SOURCE
301     cout << "AudioCallbackPlaySource::addModel: awakening thread" << endl;
302 #endif
303 
304     m_condition.wakeAll();
305 }
306 
307 void
modelChangedWithin(ModelId,sv_frame_t startFrame,sv_frame_t endFrame)308 AudioCallbackPlaySource::modelChangedWithin(ModelId, sv_frame_t
309 #ifdef DEBUG_AUDIO_PLAY_SOURCE
310                                             startFrame
311 #endif
312                                             , sv_frame_t endFrame)
313 {
314 #ifdef DEBUG_AUDIO_PLAY_SOURCE
315     SVDEBUG << "AudioCallbackPlaySource::modelChangedWithin(" << startFrame << "," << endFrame << ")" << endl;
316 #endif
317     if (endFrame > m_lastModelEndFrame) {
318         m_lastModelEndFrame = endFrame;
319         rebuildRangeLists();
320     }
321 }
322 
323 void
removeModel(ModelId modelId)324 AudioCallbackPlaySource::removeModel(ModelId modelId)
325 {
326     auto model = ModelById::get(modelId);
327     if (!model) return;
328 
329     m_mutex.lock();
330 
331 #ifdef DEBUG_AUDIO_PLAY_SOURCE
332     cout << "AudioCallbackPlaySource::removeModel(" << modelId << ")" << endl;
333 #endif
334 
335     disconnect(model.get(), SIGNAL(modelChangedWithin(ModelId, sv_frame_t, sv_frame_t)),
336                this, SLOT(modelChangedWithin(ModelId, sv_frame_t, sv_frame_t)));
337 
338     m_models.erase(modelId);
339 
340     sv_frame_t lastEnd = 0;
341     for (ModelId otherId: m_models) {
342 #ifdef DEBUG_AUDIO_PLAY_SOURCE
343         cout << "AudioCallbackPlaySource::removeModel(" << modelId << "): checking end frame on model " << otherId << endl;
344 #endif
345         if (auto other = ModelById::get(otherId)) {
346             if (other->getEndFrame() > lastEnd) {
347                 lastEnd = other->getEndFrame();
348             }
349         }
350 #ifdef DEBUG_AUDIO_PLAY_SOURCE
351         cout << "(done, lastEnd now " << lastEnd << ")" << endl;
352 #endif
353     }
354     m_lastModelEndFrame = lastEnd;
355 
356     m_audioGenerator->removeModel(modelId);
357 
358     if (m_models.empty()) {
359         m_sourceSampleRate = 0;
360     }
361 
362     m_mutex.unlock();
363 
364     clearRingBuffers();
365 }
366 
367 void
clearModels()368 AudioCallbackPlaySource::clearModels()
369 {
370     m_mutex.lock();
371 
372 #ifdef DEBUG_AUDIO_PLAY_SOURCE
373     cout << "AudioCallbackPlaySource::clearModels()" << endl;
374 #endif
375 
376     m_models.clear();
377 
378     m_lastModelEndFrame = 0;
379 
380     m_sourceSampleRate = 0;
381 
382     m_mutex.unlock();
383 
384     m_audioGenerator->clearModels();
385 
386     clearRingBuffers();
387 }
388 
389 void
clearRingBuffers(bool haveLock,int count)390 AudioCallbackPlaySource::clearRingBuffers(bool haveLock, int count)
391 {
392     if (!haveLock) m_mutex.lock();
393 
394 #ifdef DEBUG_AUDIO_PLAY_SOURCE
395     cout << "clearRingBuffers" << endl;
396 #endif
397 
398     rebuildRangeLists();
399 
400     if (count == 0) {
401         if (m_writeBuffers) count = int(m_writeBuffers->size());
402     }
403 
404 #ifdef DEBUG_AUDIO_PLAY_SOURCE
405     cout << "current playing frame = " << getCurrentPlayingFrame() << endl;
406 
407     cout << "write buffer fill (before) = " << m_writeBufferFill << endl;
408 #endif
409 
410     m_writeBufferFill = getCurrentBufferedFrame();
411 
412 #ifdef DEBUG_AUDIO_PLAY_SOURCE
413     cout << "current buffered frame = " << m_writeBufferFill << endl;
414 #endif
415 
416     if (m_readBuffers != m_writeBuffers) {
417         delete m_writeBuffers;
418     }
419 
420     m_writeBuffers = new RingBufferVector;
421 
422     for (int i = 0; i < count; ++i) {
423         m_writeBuffers->push_back(new RingBuffer<float>(m_ringBufferSize));
424     }
425 
426     m_audioGenerator->reset();
427 
428 //    cout << "AudioCallbackPlaySource::clearRingBuffers: Created "
429 //              << count << " write buffers" << endl;
430 
431     if (!haveLock) {
432         m_mutex.unlock();
433     }
434 }
435 
436 void
play(sv_frame_t startFrame)437 AudioCallbackPlaySource::play(sv_frame_t startFrame)
438 {
439     if (!m_target) return;
440 
441     if (!m_sourceSampleRate) {
442         SVCERR << "AudioCallbackPlaySource::play: No source sample rate available, not playing" << endl;
443         return;
444     }
445 
446     if (m_viewManager->getPlaySelectionMode() &&
447         !m_viewManager->getSelections().empty()) {
448 
449 #ifdef DEBUG_AUDIO_PLAY_SOURCE
450         cout << "AudioCallbackPlaySource::play: constraining frame " << startFrame << " to selection = ";
451 #endif
452 
453         startFrame = m_viewManager->constrainFrameToSelection(startFrame);
454 
455 #ifdef DEBUG_AUDIO_PLAY_SOURCE
456         cout << startFrame << endl;
457 #endif
458 
459     } else {
460         if (startFrame < 0) {
461             startFrame = 0;
462         }
463         if (startFrame >= m_lastModelEndFrame) {
464             startFrame = 0;
465         }
466     }
467 
468 #ifdef DEBUG_AUDIO_PLAY_SOURCE
469     cout << "play(" << startFrame << ") -> aligned playback model ";
470 #endif
471 
472     startFrame = m_viewManager->alignReferenceToPlaybackFrame(startFrame);
473 
474 #ifdef DEBUG_AUDIO_PLAY_SOURCE
475     cout << startFrame << endl;
476 #endif
477 
478     // The fill thread will automatically empty its buffers before
479     // starting again if we have not so far been playing, but not if
480     // we're just re-seeking.
481     // NO -- we can end up playing some first -- always reset here
482 
483     m_mutex.lock();
484 
485     if (m_timeStretcher) {
486         m_timeStretcher->reset();
487     }
488     if (m_monoStretcher) {
489         m_monoStretcher->reset();
490     }
491 
492     m_readBufferFill = m_writeBufferFill = startFrame;
493     if (m_readBuffers) {
494         for (int c = 0; c < getTargetChannelCount(); ++c) {
495             RingBuffer<float> *rb = getReadRingBuffer(c);
496 #ifdef DEBUG_AUDIO_PLAY_SOURCE
497             cout << "reset ring buffer for channel " << c << endl;
498 #endif
499             if (rb) rb->reset();
500         }
501     }
502 
503     m_mutex.unlock();
504 
505     m_audioGenerator->reset();
506 
507     m_playStartFrame = startFrame;
508     m_playStartFramePassed = false;
509     m_playStartedAt = RealTime::zeroTime;
510     if (m_target) {
511         m_playStartedAt = RealTime::fromSeconds(m_target->getCurrentTime());
512     }
513 
514     bool changed = !m_playing;
515     m_lastRetrievalTimestamp = 0;
516     m_lastCurrentFrame = 0;
517     m_playing = true;
518 
519 #ifdef DEBUG_AUDIO_PLAY_SOURCE
520     cout << "AudioCallbackPlaySource::play: awakening thread" << endl;
521 #endif
522 
523     m_condition.wakeAll();
524     if (changed) {
525         emit playStatusChanged(m_playing);
526         emit activity(tr("Play from %1").arg
527                       (RealTime::frame2RealTime
528                        (m_playStartFrame, m_sourceSampleRate).toText().c_str()));
529     }
530 }
531 
532 void
stop()533 AudioCallbackPlaySource::stop()
534 {
535 #ifdef DEBUG_AUDIO_PLAY_SOURCE
536     SVDEBUG << "AudioCallbackPlaySource::stop()" << endl;
537 #endif
538     bool changed = m_playing;
539     m_playing = false;
540 
541 #ifdef DEBUG_AUDIO_PLAY_SOURCE
542     cout << "AudioCallbackPlaySource::stop: awakening thread" << endl;
543 #endif
544 
545     m_condition.wakeAll();
546     m_lastRetrievalTimestamp = 0;
547     if (changed) {
548         emit playStatusChanged(m_playing);
549         if (m_sourceSampleRate) {
550             emit activity(tr("Stop at %1").arg
551                           (RealTime::frame2RealTime
552                            (m_lastCurrentFrame, m_sourceSampleRate)
553                            .toText().c_str()));
554         } else {
555             emit activity(tr("Stop"));
556         }
557     }
558     m_lastCurrentFrame = 0;
559 }
560 
561 void
selectionChanged()562 AudioCallbackPlaySource::selectionChanged()
563 {
564     if (m_viewManager->getPlaySelectionMode()) {
565         clearRingBuffers();
566     }
567 }
568 
569 void
playLoopModeChanged()570 AudioCallbackPlaySource::playLoopModeChanged()
571 {
572     clearRingBuffers();
573 }
574 
575 void
playSelectionModeChanged()576 AudioCallbackPlaySource::playSelectionModeChanged()
577 {
578     if (!m_viewManager->getSelections().empty()) {
579         clearRingBuffers();
580     }
581 }
582 
583 void
playParametersChanged(int)584 AudioCallbackPlaySource::playParametersChanged(int)
585 {
586     clearRingBuffers();
587 }
588 
589 void
preferenceChanged(PropertyContainer::PropertyName)590 AudioCallbackPlaySource::preferenceChanged(PropertyContainer::PropertyName)
591 {
592 }
593 
594 void
audioProcessingOverload()595 AudioCallbackPlaySource::audioProcessingOverload()
596 {
597     SVCERR << "Audio processing overload!" << endl;
598 
599     if (!m_playing) return;
600 
601     RealTimePluginInstance *ap = m_auditioningPlugin;
602     if (ap && !m_auditioningPluginBypassed) {
603         m_auditioningPluginBypassed = true;
604         emit audioOverloadPluginDisabled();
605         return;
606     }
607 
608     if (m_timeStretcher &&
609         m_timeStretcher->getTimeRatio() < 1.0 &&
610         m_stretcherInputCount > 1 &&
611         m_monoStretcher && !m_stretchMono) {
612         m_stretchMono = true;
613         emit audioTimeStretchMultiChannelDisabled();
614         return;
615     }
616 }
617 
618 void
setSystemPlaybackTarget(breakfastquay::SystemPlaybackTarget * target)619 AudioCallbackPlaySource::setSystemPlaybackTarget(breakfastquay::SystemPlaybackTarget *target)
620 {
621     if (target == nullptr) {
622         // reset target-related facts and figures
623         m_deviceSampleRate = 0;
624         m_deviceChannelCount = 0;
625     }
626     m_target = target;
627 }
628 
629 void
setResamplerWrapper(breakfastquay::ResamplerWrapper * w)630 AudioCallbackPlaySource::setResamplerWrapper(breakfastquay::ResamplerWrapper *w)
631 {
632     m_resamplerWrapper = w;
633     if (m_resamplerWrapper && m_sourceSampleRate != 0) {
634         m_resamplerWrapper->changeApplicationSampleRate
635             (int(round(m_sourceSampleRate)));
636     }
637 }
638 
639 void
setSystemPlaybackBlockSize(int size)640 AudioCallbackPlaySource::setSystemPlaybackBlockSize(int size)
641 {
642     cout << "AudioCallbackPlaySource::setTarget: Block size -> " << size << endl;
643     if (size != 0) {
644         m_blockSize = size;
645     }
646     if (size * 4 > m_ringBufferSize) {
647 #ifdef DEBUG_AUDIO_PLAY_SOURCE
648         cout << "AudioCallbackPlaySource::setTarget: Buffer size "
649              << size << " > a quarter of ring buffer size "
650              << m_ringBufferSize << ", calling for more ring buffer"
651              << endl;
652 #endif
653         m_ringBufferSize = size * 4;
654         if (m_writeBuffers && !m_writeBuffers->empty()) {
655             clearRingBuffers();
656         }
657     }
658 }
659 
660 int
getTargetBlockSize() const661 AudioCallbackPlaySource::getTargetBlockSize() const
662 {
663 //    cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << endl;
664     return int(m_blockSize);
665 }
666 
667 void
setSystemPlaybackLatency(int latency)668 AudioCallbackPlaySource::setSystemPlaybackLatency(int latency)
669 {
670     m_playLatency = latency;
671 }
672 
673 sv_frame_t
getTargetPlayLatency() const674 AudioCallbackPlaySource::getTargetPlayLatency() const
675 {
676     return m_playLatency;
677 }
678 
679 sv_frame_t
getCurrentPlayingFrame()680 AudioCallbackPlaySource::getCurrentPlayingFrame()
681 {
682     // This method attempts to estimate which audio sample frame is
683     // "currently coming through the speakers".
684 
685     sv_samplerate_t deviceRate = getDeviceSampleRate();
686     sv_frame_t latency = m_playLatency; // at target rate
687     RealTime latency_t = RealTime::zeroTime;
688 
689     if (deviceRate != 0) {
690         latency_t = RealTime::frame2RealTime(latency, deviceRate);
691     }
692 
693     return getCurrentFrame(latency_t);
694 }
695 
696 sv_frame_t
getCurrentBufferedFrame()697 AudioCallbackPlaySource::getCurrentBufferedFrame()
698 {
699     return getCurrentFrame(RealTime::zeroTime);
700 }
701 
702 sv_frame_t
getCurrentFrame(RealTime latency_t)703 AudioCallbackPlaySource::getCurrentFrame(RealTime latency_t)
704 {
705     // The ring buffers contain data at the source sample rate and all
706     // processing (including time stretching) happens at this
707     // rate. Resampling only happens after the audio data leaves this
708     // class.
709 
710     // (But because historically more than one sample rate could have
711     // been involved here, we do latency calculations using RealTime
712     // values instead of samples.)
713 
714     sv_samplerate_t rate = getSourceSampleRate();
715 
716     if (rate == 0) return 0;
717 
718     int inbuffer = 0; // at target rate
719 
720     for (int c = 0; c < getTargetChannelCount(); ++c) {
721         RingBuffer<float> *rb = getReadRingBuffer(c);
722         if (rb) {
723             int here = rb->getReadSpace();
724             if (c == 0 || here < inbuffer) inbuffer = here;
725         }
726     }
727 
728     sv_frame_t readBufferFill = m_readBufferFill;
729     sv_frame_t lastRetrievedBlockSize = m_lastRetrievedBlockSize;
730     double lastRetrievalTimestamp = m_lastRetrievalTimestamp;
731     double currentTime = 0.0;
732     if (m_target) currentTime = m_target->getCurrentTime();
733 
734     bool looping = m_viewManager->getPlayLoopMode();
735 
736     RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, rate);
737 
738     sv_frame_t stretchlat = 0;
739     double timeRatio = 1.0;
740 
741     if (m_timeStretcher) {
742         stretchlat = m_timeStretcher->getLatency();
743         timeRatio = m_timeStretcher->getTimeRatio();
744     }
745 
746     RealTime stretchlat_t = RealTime::frame2RealTime(stretchlat, rate);
747 
748     // When the target has just requested a block from us, the last
749     // sample it obtained was our buffer fill frame count minus the
750     // amount of read space (converted back to source sample rate)
751     // remaining now.  That sample is not expected to be played until
752     // the target's play latency has elapsed.  By the time the
753     // following block is requested, that sample will be at the
754     // target's play latency minus the last requested block size away
755     // from being played.
756 
757     RealTime sincerequest_t = RealTime::zeroTime;
758     RealTime lastretrieved_t = RealTime::zeroTime;
759 
760     if (m_target &&
761         m_trustworthyTimestamps &&
762         lastRetrievalTimestamp != 0.0) {
763 
764         lastretrieved_t = RealTime::frame2RealTime(lastRetrievedBlockSize, rate);
765 
766         // calculate number of frames at target rate that have elapsed
767         // since the end of the last call to getSourceSamples
768 
769         if (m_trustworthyTimestamps && !looping) {
770 
771             // this adjustment seems to cause more problems when looping
772             double elapsed = currentTime - lastRetrievalTimestamp;
773 
774             if (elapsed > 0.0) {
775                 sincerequest_t = RealTime::fromSeconds(elapsed);
776             }
777         }
778 
779     } else {
780 
781         lastretrieved_t = RealTime::frame2RealTime(getTargetBlockSize(), rate);
782     }
783 
784     RealTime bufferedto_t = RealTime::frame2RealTime(readBufferFill, rate);
785 
786     if (timeRatio != 1.0) {
787         lastretrieved_t = lastretrieved_t / timeRatio;
788         sincerequest_t = sincerequest_t / timeRatio;
789         latency_t = latency_t / timeRatio;
790     }
791 
792 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
793     cout << "\nbuffered to: " << bufferedto_t << ", in buffer: " << inbuffer_t << ", time ratio " << timeRatio << "\n  stretcher latency: " << stretchlat_t << ", device latency: " << latency_t << "\n  since request: " << sincerequest_t << ", last retrieved quantity: " << lastretrieved_t << endl;
794 #endif
795 
796     // Normally the range lists should contain at least one item each
797     // -- if playback is unconstrained, that item should report the
798     // entire source audio duration.
799 
800     if (m_rangeStarts.empty()) {
801         rebuildRangeLists();
802     }
803 
804     if (m_rangeStarts.empty()) {
805         // this code is only used in case of error in rebuildRangeLists
806         RealTime playing_t = bufferedto_t
807             - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t
808             + sincerequest_t;
809         if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime;
810         sv_frame_t frame = RealTime::realTime2Frame(playing_t, rate);
811         return m_viewManager->alignPlaybackFrameToReference(frame);
812     }
813 
814     int inRange = 0;
815     int index = 0;
816 
817     for (int i = 0; i < (int)m_rangeStarts.size(); ++i) {
818         if (bufferedto_t >= m_rangeStarts[i]) {
819             inRange = index;
820         } else {
821             break;
822         }
823         ++index;
824     }
825 
826     if (inRange >= int(m_rangeStarts.size())) {
827         inRange = int(m_rangeStarts.size())-1;
828     }
829 
830     RealTime playing_t = bufferedto_t;
831 
832     playing_t = playing_t
833         - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t
834         + sincerequest_t;
835 
836     // This rather gross little hack is used to ensure that latency
837     // compensation doesn't result in the playback pointer appearing
838     // to start earlier than the actual playback does.  It doesn't
839     // work properly (hence the bail-out in the middle) because if we
840     // are playing a relatively short looped region, the playing time
841     // estimated from the buffer fill frame may have wrapped around
842     // the region boundary and end up being much smaller than the
843     // theoretical play start frame, perhaps even for the entire
844     // duration of playback!
845 
846     if (!m_playStartFramePassed) {
847         RealTime playstart_t = RealTime::frame2RealTime(m_playStartFrame, rate);
848         if (playing_t < playstart_t) {
849 //            cout << "playing_t " << playing_t << " < playstart_t "
850 //                      << playstart_t << endl;
851             if (/*!!! sincerequest_t > RealTime::zeroTime && */
852                 m_playStartedAt + latency_t + stretchlat_t <
853                 RealTime::fromSeconds(currentTime)) {
854 //                cout << "but we've been playing for long enough that I think we should disregard it (it probably results from loop wrapping)" << endl;
855                 m_playStartFramePassed = true;
856             } else {
857                 playing_t = playstart_t;
858             }
859         } else {
860             m_playStartFramePassed = true;
861         }
862     }
863 
864 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
865     cout << "playing_t " << playing_t;
866 #endif
867 
868     playing_t = playing_t - m_rangeStarts[inRange];
869 
870 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
871     cout << " as offset into range " << inRange << " (start =" << m_rangeStarts[inRange] << " duration =" << m_rangeDurations[inRange] << ") = " << playing_t << endl;
872 #endif
873 
874     while (playing_t < RealTime::zeroTime) {
875 
876         if (inRange == 0) {
877             if (looping) {
878                 inRange = int(m_rangeStarts.size()) - 1;
879             } else {
880                 break;
881             }
882         } else {
883             --inRange;
884         }
885 
886         playing_t = playing_t + m_rangeDurations[inRange];
887     }
888 
889     playing_t = playing_t + m_rangeStarts[inRange];
890 
891 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
892     cout << "  playing time: " << playing_t << endl;
893 #endif
894 
895     if (!looping) {
896         if (inRange == (int)m_rangeStarts.size()-1 &&
897             playing_t >= m_rangeStarts[inRange] + m_rangeDurations[inRange]) {
898 cout << "Not looping, inRange " << inRange << " == rangeStarts.size()-1, playing_t " << playing_t << " >= m_rangeStarts[inRange] " << m_rangeStarts[inRange] << " + m_rangeDurations[inRange] " << m_rangeDurations[inRange] << " -- stopping" << endl;
899             stop();
900         }
901     }
902 
903     if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime;
904 
905     sv_frame_t frame = RealTime::realTime2Frame(playing_t, rate);
906 
907     if (m_lastCurrentFrame > 0 && !looping) {
908         if (frame < m_lastCurrentFrame) {
909             frame = m_lastCurrentFrame;
910         }
911     }
912 
913     m_lastCurrentFrame = frame;
914 
915     return m_viewManager->alignPlaybackFrameToReference(frame);
916 }
917 
918 void
rebuildRangeLists()919 AudioCallbackPlaySource::rebuildRangeLists()
920 {
921     bool constrained = (m_viewManager->getPlaySelectionMode());
922 
923     m_rangeStarts.clear();
924     m_rangeDurations.clear();
925 
926     sv_samplerate_t sourceRate = getSourceSampleRate();
927     if (sourceRate == 0) return;
928 
929     RealTime end = RealTime::frame2RealTime(m_lastModelEndFrame, sourceRate);
930     if (end == RealTime::zeroTime) return;
931 
932     if (!constrained) {
933         m_rangeStarts.push_back(RealTime::zeroTime);
934         m_rangeDurations.push_back(end);
935         return;
936     }
937 
938     MultiSelection::SelectionList selections = m_viewManager->getSelections();
939     MultiSelection::SelectionList::const_iterator i;
940 
941 #ifdef DEBUG_AUDIO_PLAY_SOURCE
942     SVDEBUG << "AudioCallbackPlaySource::rebuildRangeLists" << endl;
943 #endif
944 
945     if (!selections.empty()) {
946 
947         for (i = selections.begin(); i != selections.end(); ++i) {
948 
949             RealTime start =
950                 (RealTime::frame2RealTime
951                  (m_viewManager->alignReferenceToPlaybackFrame(i->getStartFrame()),
952                   sourceRate));
953             RealTime duration =
954                 (RealTime::frame2RealTime
955                  (m_viewManager->alignReferenceToPlaybackFrame(i->getEndFrame()) -
956                   m_viewManager->alignReferenceToPlaybackFrame(i->getStartFrame()),
957                   sourceRate));
958 
959             m_rangeStarts.push_back(start);
960             m_rangeDurations.push_back(duration);
961         }
962     } else {
963         m_rangeStarts.push_back(RealTime::zeroTime);
964         m_rangeDurations.push_back(end);
965     }
966 
967 #ifdef DEBUG_AUDIO_PLAY_SOURCE
968     cout << "Now have " << m_rangeStarts.size() << " play ranges" << endl;
969 #endif
970 }
971 
972 void
setOutputLevels(float left,float right)973 AudioCallbackPlaySource::setOutputLevels(float left, float right)
974 {
975     if (left > m_outputLeft) m_outputLeft = left;
976     if (right > m_outputRight) m_outputRight = right;
977     m_levelsSet = true;
978 }
979 
980 bool
getOutputLevels(float & left,float & right)981 AudioCallbackPlaySource::getOutputLevels(float &left, float &right)
982 {
983     left = m_outputLeft;
984     right = m_outputRight;
985     bool valid = m_levelsSet;
986     m_outputLeft = 0.f;
987     m_outputRight = 0.f;
988     m_levelsSet = false;
989     return valid;
990 }
991 
992 void
setSystemPlaybackSampleRate(int sr)993 AudioCallbackPlaySource::setSystemPlaybackSampleRate(int sr)
994 {
995     m_deviceSampleRate = sr;
996 }
997 
998 void
setSystemPlaybackChannelCount(int count)999 AudioCallbackPlaySource::setSystemPlaybackChannelCount(int count)
1000 {
1001     m_deviceChannelCount = count;
1002 }
1003 
1004 void
setAuditioningEffect(Auditionable * a)1005 AudioCallbackPlaySource::setAuditioningEffect(Auditionable *a)
1006 {
1007     RealTimePluginInstance *plugin = dynamic_cast<RealTimePluginInstance *>(a);
1008     if (a && !plugin) {
1009         SVCERR << "WARNING: AudioCallbackPlaySource::setAuditioningEffect: auditionable object " << a << " is not a real-time plugin instance" << endl;
1010     }
1011 
1012     m_mutex.lock();
1013     m_auditioningPlugin = plugin;
1014     m_auditioningPluginBypassed = false;
1015     m_mutex.unlock();
1016 }
1017 
1018 void
setSoloModelSet(std::set<ModelId> s)1019 AudioCallbackPlaySource::setSoloModelSet(std::set<ModelId> s)
1020 {
1021     m_audioGenerator->setSoloModelSet(s);
1022     clearRingBuffers();
1023 }
1024 
1025 void
clearSoloModelSet()1026 AudioCallbackPlaySource::clearSoloModelSet()
1027 {
1028     m_audioGenerator->clearSoloModelSet();
1029     clearRingBuffers();
1030 }
1031 
1032 sv_samplerate_t
getDeviceSampleRate() const1033 AudioCallbackPlaySource::getDeviceSampleRate() const
1034 {
1035     return m_deviceSampleRate;
1036 }
1037 
1038 int
getSourceChannelCount() const1039 AudioCallbackPlaySource::getSourceChannelCount() const
1040 {
1041     return m_sourceChannelCount;
1042 }
1043 
1044 int
getTargetChannelCount() const1045 AudioCallbackPlaySource::getTargetChannelCount() const
1046 {
1047     if (m_sourceChannelCount < 2) return 2;
1048     return m_sourceChannelCount;
1049 }
1050 
1051 int
getDeviceChannelCount() const1052 AudioCallbackPlaySource::getDeviceChannelCount() const
1053 {
1054     return m_deviceChannelCount;
1055 }
1056 
1057 sv_samplerate_t
getSourceSampleRate() const1058 AudioCallbackPlaySource::getSourceSampleRate() const
1059 {
1060     return m_sourceSampleRate;
1061 }
1062 
1063 void
setTimeStretch(double factor)1064 AudioCallbackPlaySource::setTimeStretch(double factor)
1065 {
1066     m_stretchRatio = factor;
1067 
1068     int rate = int(getSourceSampleRate());
1069     if (!rate) return; // have to make our stretcher later
1070 
1071     if (m_timeStretcher || (factor == 1.0)) {
1072         // stretch ratio will be set in next process call if appropriate
1073     } else {
1074         m_stretcherInputCount = getTargetChannelCount();
1075         RubberBandStretcher *stretcher = new RubberBandStretcher
1076             (rate,
1077              m_stretcherInputCount,
1078              RubberBandStretcher::OptionProcessRealTime,
1079              factor);
1080         RubberBandStretcher *monoStretcher = new RubberBandStretcher
1081             (rate,
1082              1,
1083              RubberBandStretcher::OptionProcessRealTime,
1084              factor);
1085         m_stretcherInputs = new float *[m_stretcherInputCount];
1086         m_stretcherInputSizes = new sv_frame_t[m_stretcherInputCount];
1087         for (int c = 0; c < m_stretcherInputCount; ++c) {
1088             m_stretcherInputSizes[c] = 16384;
1089             m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]];
1090         }
1091         m_monoStretcher = monoStretcher;
1092         m_timeStretcher = stretcher;
1093     }
1094 
1095     emit activity(tr("Change time-stretch factor to %1").arg(factor));
1096 }
1097 
1098 int
getSourceSamples(float * const * buffer,int requestedChannels,int count)1099 AudioCallbackPlaySource::getSourceSamples(float *const *buffer,
1100                                           int requestedChannels,
1101                                           int count)
1102 {
1103     // In principle, the target will handle channel mapping in cases
1104     // where our channel count differs from the device's. But that
1105     // only holds if our channel count doesn't change -- i.e. if
1106     // getApplicationChannelCount() always returns the same value as
1107     // it did when the target was created, and if this function always
1108     // returns that number of channels.
1109     //
1110     // Unfortunately that can't hold for us -- we always have at least
1111     // 2 channels but if the user opens a new main model with more
1112     // channels than that (and more than the last main model) then our
1113     // target channel count necessarily gets increased.
1114     //
1115     // We have:
1116     //
1117     // getSourceChannelCount() -> number of channels available to
1118     // provide from real model data
1119     //
1120     // getTargetChannelCount() -> number we will actually provide;
1121     // same as getSourceChannelCount() except that it is always at
1122     // least 2
1123     //
1124     // getDeviceChannelCount() -> number the device will emit, usually
1125     // equal to the value of getTargetChannelCount() at the time the
1126     // device was initialised, unless the device could not provide
1127     // that number
1128     //
1129     // requestedChannels -> number the device is expecting from us,
1130     // always equal to the value of getTargetChannelCount() at the
1131     // time the device was initialised
1132     //
1133     // If the requested channel count is at least the target channel
1134     // count, then we go ahead and provide the target channels as
1135     // expected. We just zero any spare channels.
1136     //
1137     // If the requested channel count is smaller than the target
1138     // channel count, then we don't know what to do and we provide
1139     // nothing. This shouldn't happen as long as management is on the
1140     // ball -- we emit channelCountIncreased() when the target channel
1141     // count increases, and whatever code "owns" the driver should
1142     // have reopened the audio device when it got that signal. But
1143     // there's a race condition there, which we accommodate with this
1144     // check.
1145 
1146     int channels = getTargetChannelCount();
1147 
1148     if (!m_playing) {
1149 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1150         cout << "AudioCallbackPlaySource::getSourceSamples: Not playing" << endl;
1151 #endif
1152         v_zero_channels(buffer, requestedChannels, count);
1153         return 0;
1154     }
1155     if (requestedChannels < channels) {
1156         SVDEBUG << "AudioCallbackPlaySource::getSourceSamples: Not enough device channels (" << requestedChannels << ", need " << channels << "); hoping device is about to be reopened" << endl;
1157         v_zero_channels(buffer, requestedChannels, count);
1158         return 0;
1159     }
1160     if (requestedChannels > channels) {
1161         v_zero_channels(buffer + channels, requestedChannels - channels, count);
1162     }
1163 
1164 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1165     cout << "AudioCallbackPlaySource::getSourceSamples: Playing" << endl;
1166 #endif
1167 
1168     // Ensure that all buffers have at least the amount of data we
1169     // need -- else reduce the size of our requests correspondingly
1170 
1171     for (int ch = 0; ch < channels; ++ch) {
1172 
1173         RingBuffer<float> *rb = getReadRingBuffer(ch);
1174 
1175         if (!rb) {
1176             SVCERR << "WARNING: AudioCallbackPlaySource::getSourceSamples: "
1177                       << "No ring buffer available for channel " << ch
1178                       << ", returning no data here" << endl;
1179             count = 0;
1180             break;
1181         }
1182 
1183         int rs = rb->getReadSpace();
1184         if (rs < count) {
1185 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1186             cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: "
1187                       << "Ring buffer for channel " << ch << " has only "
1188                       << rs << " (of " << count << ") samples available ("
1189                       << "ring buffer size is " << rb->getSize() << ", write "
1190                       << "space " << rb->getWriteSpace() << "), "
1191                       << "reducing request size" << endl;
1192 #endif
1193             count = rs;
1194         }
1195     }
1196 
1197     if (count == 0) return 0;
1198 
1199     RubberBandStretcher *ts = m_timeStretcher;
1200     RubberBandStretcher *ms = m_monoStretcher;
1201 
1202     double ratio = ts ? ts->getTimeRatio() : 1.0;
1203 
1204     if (ratio != m_stretchRatio) {
1205         if (!ts) {
1206             SVCERR << "WARNING: AudioCallbackPlaySource::getSourceSamples: Time ratio change to " << m_stretchRatio << " is pending, but no stretcher is set" << endl;
1207             m_stretchRatio = 1.0;
1208         } else {
1209             ts->setTimeRatio(m_stretchRatio);
1210             if (ms) ms->setTimeRatio(m_stretchRatio);
1211             if (m_stretchRatio >= 1.0) m_stretchMono = false;
1212         }
1213     }
1214 
1215     int stretchChannels = m_stretcherInputCount;
1216     if (m_stretchMono) {
1217         if (ms) {
1218             ts = ms;
1219             stretchChannels = 1;
1220         } else {
1221             m_stretchMono = false;
1222         }
1223     }
1224 
1225     if (m_target) {
1226         m_lastRetrievedBlockSize = count;
1227         m_lastRetrievalTimestamp = m_target->getCurrentTime();
1228     }
1229 
1230     if (!ts || ratio == 1.f) {
1231 
1232         int got = 0;
1233 
1234 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1235         cout << "channels == " << channels << endl;
1236 #endif
1237 
1238         for (int ch = 0; ch < channels; ++ch) {
1239 
1240             RingBuffer<float> *rb = getReadRingBuffer(ch);
1241 
1242             if (rb) {
1243 
1244                 // this is marginally more likely to leave our channels in
1245                 // sync after a processing failure than just passing "count":
1246                 sv_frame_t request = count;
1247                 if (ch > 0) request = got;
1248 
1249                 got = rb->read(buffer[ch], int(request));
1250 
1251 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1252                 cout << "AudioCallbackPlaySource::getSamples: got " << got << " (of " << count << ") samples on channel " << ch << ", signalling for more (possibly)" << endl;
1253 #endif
1254             }
1255 
1256             for (int ch = 0; ch < channels; ++ch) {
1257                 for (int i = got; i < count; ++i) {
1258                     buffer[ch][i] = 0.0;
1259                 }
1260             }
1261         }
1262 
1263         applyAuditioningEffect(count, buffer);
1264 
1265 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1266     cout << "AudioCallbackPlaySource::getSamples: awakening thread" << endl;
1267 #endif
1268 
1269         m_condition.wakeAll();
1270 
1271         return got;
1272     }
1273 
1274     sv_frame_t available;
1275     sv_frame_t fedToStretcher = 0;
1276     int warned = 0;
1277 
1278     // The input block for a given output is approx output / ratio,
1279     // but we can't predict it exactly, for an adaptive timestretcher.
1280 
1281     while ((available = ts->available()) < count) {
1282 
1283         sv_frame_t reqd = lrint(double(count - available) / ratio);
1284         reqd = std::max(reqd, sv_frame_t(ts->getSamplesRequired()));
1285         if (reqd == 0) reqd = 1;
1286 
1287         sv_frame_t got = reqd;
1288 
1289 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1290         cout << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << endl;
1291 #endif
1292 
1293         for (int c = 0; c < channels; ++c) {
1294             if (c >= m_stretcherInputCount) continue;
1295             if (reqd > m_stretcherInputSizes[c]) {
1296                 if (c == 0) {
1297                     SVDEBUG << "NOTE: resizing stretcher input buffer from " << m_stretcherInputSizes[c] << " to " << (reqd * 2) << endl;
1298                 }
1299                 delete[] m_stretcherInputs[c];
1300                 m_stretcherInputSizes[c] = reqd * 2;
1301                 m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]];
1302             }
1303         }
1304 
1305         for (int c = 0; c < channels; ++c) {
1306             if (c >= m_stretcherInputCount) continue;
1307             RingBuffer<float> *rb = getReadRingBuffer(c);
1308             if (rb) {
1309                 sv_frame_t gotHere;
1310                 if (stretchChannels == 1 && c > 0) {
1311                     gotHere = rb->readAdding(m_stretcherInputs[0], int(got));
1312                 } else {
1313                     gotHere = rb->read(m_stretcherInputs[c], int(got));
1314                 }
1315                 if (gotHere < got) got = gotHere;
1316 
1317 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1318                 if (c == 0) {
1319                     cout << "feeding stretcher: got " << gotHere
1320                               << ", " << rb->getReadSpace() << " remain" << endl;
1321                 }
1322 #endif
1323 
1324             } else {
1325                 SVCERR << "WARNING: No ring buffer available for channel " << c << " in stretcher input block" << endl;
1326             }
1327         }
1328 
1329         if (got < reqd) {
1330             SVCERR << "WARNING: Read underrun in playback ("
1331                       << got << " < " << reqd << ")" << endl;
1332         }
1333 
1334         ts->process(m_stretcherInputs, size_t(got), false);
1335 
1336         fedToStretcher += got;
1337 
1338         if (got == 0) break;
1339 
1340         if (ts->available() == available) {
1341             SVCERR << "WARNING: AudioCallbackPlaySource::getSamples: Added " << got << " samples to time stretcher, created no new available output samples (warned = " << warned << ")" << endl;
1342             if (++warned == 5) break;
1343         }
1344     }
1345 
1346     ts->retrieve(buffer, size_t(count));
1347 
1348     v_zero_channels(buffer + stretchChannels, channels - stretchChannels, count);
1349 
1350     applyAuditioningEffect(count, buffer);
1351 
1352 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1353     cout << "AudioCallbackPlaySource::getSamples [stretched]: awakening thread" << endl;
1354 #endif
1355 
1356     m_condition.wakeAll();
1357 
1358     return count;
1359 }
1360 
1361 void
applyAuditioningEffect(sv_frame_t count,float * const * buffers)1362 AudioCallbackPlaySource::applyAuditioningEffect(sv_frame_t count, float *const *buffers)
1363 {
1364     if (m_auditioningPluginBypassed) return;
1365     RealTimePluginInstance *plugin = m_auditioningPlugin;
1366     if (!plugin) return;
1367 
1368     if ((int)plugin->getAudioInputCount() != getTargetChannelCount()) {
1369 //        cout << "plugin input count " << plugin->getAudioInputCount()
1370 //                  << " != our channel count " << getTargetChannelCount()
1371 //                  << endl;
1372         return;
1373     }
1374     if ((int)plugin->getAudioOutputCount() != getTargetChannelCount()) {
1375 //        cout << "plugin output count " << plugin->getAudioOutputCount()
1376 //                  << " != our channel count " << getTargetChannelCount()
1377 //                  << endl;
1378         return;
1379     }
1380     if ((int)plugin->getBufferSize() < count) {
1381 //        cout << "plugin buffer size " << plugin->getBufferSize()
1382 //                  << " < our block size " << count
1383 //                  << endl;
1384         return;
1385     }
1386 
1387     float **ib = plugin->getAudioInputBuffers();
1388     float **ob = plugin->getAudioOutputBuffers();
1389 
1390     for (int c = 0; c < getTargetChannelCount(); ++c) {
1391         for (int i = 0; i < count; ++i) {
1392             ib[c][i] = buffers[c][i];
1393         }
1394     }
1395 
1396     plugin->run(Vamp::RealTime::zeroTime, int(count));
1397 
1398     for (int c = 0; c < getTargetChannelCount(); ++c) {
1399         for (int i = 0; i < count; ++i) {
1400             buffers[c][i] = ob[c][i];
1401         }
1402     }
1403 }
1404 
1405 // Called from fill thread, m_playing true, mutex held
1406 bool
fillBuffers()1407 AudioCallbackPlaySource::fillBuffers()
1408 {
1409     static float *tmp = nullptr;
1410     static sv_frame_t tmpSize = 0;
1411 
1412     sv_frame_t space = 0;
1413     for (int c = 0; c < getTargetChannelCount(); ++c) {
1414         RingBuffer<float> *wb = getWriteRingBuffer(c);
1415         if (wb) {
1416             sv_frame_t spaceHere = wb->getWriteSpace();
1417             if (c == 0 || spaceHere < space) space = spaceHere;
1418         }
1419     }
1420 
1421     if (space == 0) {
1422 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1423         cout << "AudioCallbackPlaySourceFillThread: no space to fill" << endl;
1424 #endif
1425         return false;
1426     }
1427 
1428     // space is now the number of samples that can be written on each
1429     // channel's write ringbuffer
1430 
1431     sv_frame_t f = m_writeBufferFill;
1432 
1433     bool readWriteEqual = (m_readBuffers == m_writeBuffers);
1434 
1435 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1436     if (!readWriteEqual) {
1437         cout << "AudioCallbackPlaySourceFillThread: note read buffers != write buffers" << endl;
1438     }
1439     cout << "AudioCallbackPlaySourceFillThread: filling " << space << " frames" << endl;
1440 #endif
1441 
1442 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1443     cout << "buffered to " << f << " already" << endl;
1444 #endif
1445 
1446     int channels = getTargetChannelCount();
1447 
1448     static float **bufferPtrs = nullptr;
1449     static int bufferPtrCount = 0;
1450 
1451     if (bufferPtrCount < channels) {
1452         if (bufferPtrs) delete[] bufferPtrs;
1453         bufferPtrs = new float *[channels];
1454         bufferPtrCount = channels;
1455     }
1456 
1457     sv_frame_t generatorBlockSize = m_audioGenerator->getBlockSize();
1458 
1459     // space must be a multiple of generatorBlockSize
1460     sv_frame_t reqSpace = space;
1461     space = (reqSpace / generatorBlockSize) * generatorBlockSize;
1462     if (space == 0) {
1463 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1464         cout << "requested fill of " << reqSpace
1465              << " is less than generator block size of "
1466              << generatorBlockSize << ", leaving it" << endl;
1467 #endif
1468         return false;
1469     }
1470 
1471     if (tmpSize < channels * space) {
1472         delete[] tmp;
1473         tmp = new float[channels * space];
1474         tmpSize = channels * space;
1475     }
1476 
1477     for (int c = 0; c < channels; ++c) {
1478 
1479         bufferPtrs[c] = tmp + c * space;
1480 
1481         for (int i = 0; i < space; ++i) {
1482             tmp[c * space + i] = 0.0f;
1483         }
1484     }
1485 
1486     sv_frame_t got = mixModels(f, space, bufferPtrs); // also modifies f
1487 
1488     for (int c = 0; c < channels; ++c) {
1489 
1490         RingBuffer<float> *wb = getWriteRingBuffer(c);
1491         if (wb) {
1492             int actual = wb->write(bufferPtrs[c], int(got));
1493 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1494             cout << "Wrote " << actual << " samples for ch " << c << ", now "
1495                  << wb->getReadSpace() << " to read"
1496                  << endl;
1497 #endif
1498             if (actual < got) {
1499                 SVCERR << "WARNING: Buffer overrun in channel " << c
1500                        << ": wrote " << actual << " of " << got
1501                        << " samples" << endl;
1502             }
1503         }
1504     }
1505 
1506     m_writeBufferFill = f;
1507     if (readWriteEqual) m_readBufferFill = f;
1508 
1509 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1510     cout << "Read buffer fill is now " << m_readBufferFill << ", write buffer fill "
1511          << m_writeBufferFill << endl;
1512 #endif
1513 
1514     //!!! 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
1515 
1516     return true;
1517 }
1518 
1519 sv_frame_t
mixModels(sv_frame_t & frame,sv_frame_t count,float ** buffers)1520 AudioCallbackPlaySource::mixModels(sv_frame_t &frame, sv_frame_t count, float **buffers)
1521 {
1522     sv_frame_t processed = 0;
1523     sv_frame_t chunkStart = frame;
1524     sv_frame_t chunkSize = count;
1525     sv_frame_t selectionSize = 0;
1526     sv_frame_t nextChunkStart = chunkStart + chunkSize;
1527 
1528     bool looping = m_viewManager->getPlayLoopMode();
1529     bool constrained = (m_viewManager->getPlaySelectionMode() &&
1530                         !m_viewManager->getSelections().empty());
1531 
1532     int channels = getTargetChannelCount();
1533 
1534 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1535     cout << "mixModels: start " << frame << ", size " << count << ", channels " << channels << endl;
1536 #endif
1537 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1538     if (constrained) {
1539         cout << "Manager has " << m_viewManager->getSelections().size() << " selection(s):" << endl;
1540         for (auto sel: m_viewManager->getSelections()) {
1541             cout << sel.getStartFrame() << " -> " << sel.getEndFrame()
1542                  << " (" << (sel.getEndFrame() - sel.getStartFrame()) << " frames)"
1543                  << endl;
1544         }
1545     }
1546 #endif
1547 
1548     static float **chunkBufferPtrs = nullptr;
1549     static int chunkBufferPtrCount = 0;
1550 
1551     if (chunkBufferPtrCount < channels) {
1552         if (chunkBufferPtrs) delete[] chunkBufferPtrs;
1553         chunkBufferPtrs = new float *[channels];
1554         chunkBufferPtrCount = channels;
1555     }
1556 
1557     for (int c = 0; c < channels; ++c) {
1558         chunkBufferPtrs[c] = buffers[c];
1559     }
1560 
1561     while (processed < count) {
1562 
1563         chunkSize = count - processed;
1564         nextChunkStart = chunkStart + chunkSize;
1565         selectionSize = 0;
1566 
1567         sv_frame_t fadeIn = 0, fadeOut = 0;
1568 
1569         if (constrained) {
1570 
1571             sv_frame_t rChunkStart =
1572                 m_viewManager->alignPlaybackFrameToReference(chunkStart);
1573 
1574             Selection selection =
1575                 m_viewManager->getContainingSelection(rChunkStart, true);
1576 
1577             if (selection.isEmpty()) {
1578                 if (looping) {
1579                     selection = *m_viewManager->getSelections().begin();
1580                     chunkStart = m_viewManager->alignReferenceToPlaybackFrame
1581                         (selection.getStartFrame());
1582                     fadeIn = 50;
1583                 }
1584             }
1585 
1586             if (selection.isEmpty()) {
1587 
1588                 chunkSize = 0;
1589                 nextChunkStart = chunkStart;
1590 
1591             } else {
1592 
1593                 sv_frame_t sf = m_viewManager->alignReferenceToPlaybackFrame
1594                     (selection.getStartFrame());
1595                 sv_frame_t ef = m_viewManager->alignReferenceToPlaybackFrame
1596                     (selection.getEndFrame());
1597 
1598                 selectionSize = ef - sf;
1599 
1600                 if (chunkStart < sf) {
1601                     chunkStart = sf;
1602                     fadeIn = 50;
1603                 }
1604 
1605                 nextChunkStart = chunkStart + chunkSize;
1606 
1607                 if (nextChunkStart >= ef) {
1608                     nextChunkStart = ef;
1609                     fadeOut = 50;
1610                 }
1611 
1612                 chunkSize = nextChunkStart - chunkStart;
1613             }
1614 
1615         } else if (looping && m_lastModelEndFrame > 0) {
1616 
1617             if (chunkStart >= m_lastModelEndFrame) {
1618                 chunkStart = 0;
1619             }
1620             if (chunkSize > m_lastModelEndFrame - chunkStart) {
1621                 chunkSize = m_lastModelEndFrame - chunkStart;
1622             }
1623             nextChunkStart = chunkStart + chunkSize;
1624         }
1625 
1626 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1627         cout << "chunkStart " << chunkStart << ", chunkSize " << chunkSize << ", nextChunkStart " << nextChunkStart << ", frame " << frame << ", count " << count << ", processed " << processed << endl;
1628 #endif
1629 
1630         if (!chunkSize) {
1631             // We need to maintain full buffers so that the other
1632             // thread can tell where it's got to in the playback -- so
1633             // return the full amount here
1634             frame = frame + count;
1635             if (frame < nextChunkStart) {
1636                 frame = nextChunkStart;
1637             }
1638 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1639             cout << "mixModels: ending at " << nextChunkStart << ", returning frame as "
1640                  << frame << endl;
1641 #endif
1642             return count;
1643         }
1644 
1645 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1646         cout << "mixModels: chunk at " << chunkStart << " -> " << nextChunkStart << " (size " << chunkSize << ")" << endl;
1647 #endif
1648 
1649         if (selectionSize < 100) {
1650             fadeIn = 0;
1651             fadeOut = 0;
1652         } else if (selectionSize < 300) {
1653             if (fadeIn > 0) fadeIn = 10;
1654             if (fadeOut > 0) fadeOut = 10;
1655         }
1656 
1657         if (fadeIn > 0) {
1658             if (processed * 2 < fadeIn) {
1659                 fadeIn = processed * 2;
1660             }
1661         }
1662 
1663         if (fadeOut > 0) {
1664             if ((count - processed - chunkSize) * 2 < fadeOut) {
1665                 fadeOut = (count - processed - chunkSize) * 2;
1666             }
1667         }
1668 
1669         for (std::set<ModelId>::iterator mi = m_models.begin();
1670              mi != m_models.end(); ++mi) {
1671 
1672             (void) m_audioGenerator->mixModel(*mi, chunkStart,
1673                                               chunkSize, chunkBufferPtrs,
1674                                               fadeIn, fadeOut);
1675         }
1676 
1677         for (int c = 0; c < channels; ++c) {
1678             chunkBufferPtrs[c] += chunkSize;
1679         }
1680 
1681         processed += chunkSize;
1682         chunkStart = nextChunkStart;
1683     }
1684 
1685 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1686     cout << "mixModels returning " << processed << " frames to " << nextChunkStart << endl;
1687 #endif
1688 
1689     frame = nextChunkStart;
1690     return processed;
1691 }
1692 
1693 void
unifyRingBuffers()1694 AudioCallbackPlaySource::unifyRingBuffers()
1695 {
1696     if (m_readBuffers == m_writeBuffers) return;
1697 
1698     // only unify if there will be something to read
1699     for (int c = 0; c < getTargetChannelCount(); ++c) {
1700         RingBuffer<float> *wb = getWriteRingBuffer(c);
1701         if (wb) {
1702             if (wb->getReadSpace() < m_blockSize * 2) {
1703                 if ((m_writeBufferFill + m_blockSize * 2) <
1704                     m_lastModelEndFrame) {
1705                     // OK, we don't have enough and there's more to
1706                     // read -- don't unify until we can do better
1707 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1708                     cout << "AudioCallbackPlaySource::unifyRingBuffers: Not unifying: write buffer has less (" << wb->getReadSpace() << ") than " << m_blockSize*2 << " to read and write buffer fill (" << m_writeBufferFill << ") is not close to end frame (" << m_lastModelEndFrame << ")" << endl;
1709 #endif
1710                     return;
1711                 }
1712             }
1713             break;
1714         }
1715     }
1716 
1717     sv_frame_t rf = m_readBufferFill;
1718     RingBuffer<float> *rb = getReadRingBuffer(0);
1719     if (rb) {
1720         int rs = rb->getReadSpace();
1721         //!!! incorrect when in non-contiguous selection, see comments elsewhere
1722 //        cout << "rs = " << rs << endl;
1723         if (rs < rf) rf -= rs;
1724         else rf = 0;
1725     }
1726 
1727 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1728     cout << "AudioCallbackPlaySource::unifyRingBuffers: m_readBufferFill = " << m_readBufferFill << ", rf = " << rf << ", m_writeBufferFill = " << m_writeBufferFill << endl;
1729 #endif
1730 
1731     sv_frame_t wf = m_writeBufferFill;
1732     sv_frame_t skip = 0;
1733     for (int c = 0; c < getTargetChannelCount(); ++c) {
1734         RingBuffer<float> *wb = getWriteRingBuffer(c);
1735         if (wb) {
1736             if (c == 0) {
1737 
1738                 int wrs = wb->getReadSpace();
1739 //                cout << "wrs = " << wrs << endl;
1740 
1741                 if (wrs < wf) wf -= wrs;
1742                 else wf = 0;
1743 //                cout << "wf = " << wf << endl;
1744 
1745                 if (wf < rf) skip = rf - wf;
1746                 if (skip == 0) break;
1747             }
1748 
1749 //            cout << "skipping " << skip << endl;
1750             wb->skip(int(skip));
1751         }
1752     }
1753 
1754     m_bufferScavenger.claim(m_readBuffers);
1755     m_readBuffers = m_writeBuffers;
1756     m_readBufferFill = m_writeBufferFill;
1757 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
1758     cout << "unified" << endl;
1759 #endif
1760 }
1761 
1762 void
run()1763 AudioCallbackPlaySource::FillThread::run()
1764 {
1765     AudioCallbackPlaySource &s(m_source);
1766 
1767 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1768     cout << "AudioCallbackPlaySourceFillThread starting" << endl;
1769 #endif
1770 
1771     s.m_mutex.lock();
1772 
1773     bool previouslyPlaying = s.m_playing;
1774     bool work = false;
1775 
1776     while (!s.m_exiting) {
1777 
1778         s.unifyRingBuffers();
1779         s.m_bufferScavenger.scavenge();
1780         s.m_pluginScavenger.scavenge();
1781 
1782         if (work && s.m_playing && s.getSourceSampleRate()) {
1783 
1784 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1785             cout << "AudioCallbackPlaySourceFillThread: not waiting" << endl;
1786 #endif
1787 
1788             s.m_mutex.unlock();
1789             s.m_mutex.lock();
1790 
1791         } else {
1792 
1793             double ms = 100;
1794             if (s.getSourceSampleRate() > 0) {
1795                 ms = double(s.m_ringBufferSize) / s.getSourceSampleRate() * 1000.0;
1796             }
1797 
1798             if (s.m_playing) ms /= 10;
1799 
1800 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1801             if (!s.m_playing) cout << endl;
1802             cout << "AudioCallbackPlaySourceFillThread: waiting for " << ms << "ms..." << endl;
1803 #endif
1804 
1805             s.m_condition.wait(&s.m_mutex, int(ms));
1806         }
1807 
1808 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1809         cout << "AudioCallbackPlaySourceFillThread: awoken" << endl;
1810 #endif
1811 
1812         work = false;
1813 
1814         if (!s.getSourceSampleRate()) {
1815 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1816             cout << "AudioCallbackPlaySourceFillThread: source sample rate is zero" << endl;
1817 #endif
1818             continue;
1819         }
1820 
1821         bool playing = s.m_playing;
1822 
1823         if (playing && !previouslyPlaying) {
1824 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1825             cout << "AudioCallbackPlaySourceFillThread: playback state changed, resetting" << endl;
1826 #endif
1827             for (int c = 0; c < s.getTargetChannelCount(); ++c) {
1828                 RingBuffer<float> *rb = s.getReadRingBuffer(c);
1829                 if (rb) rb->reset();
1830             }
1831         }
1832         previouslyPlaying = playing;
1833 
1834         work = s.fillBuffers();
1835     }
1836 
1837     s.m_mutex.unlock();
1838 }
1839 
1840