diff audioio/AudioCallbackPlaySource.cpp @ 449:12d982e52190

Merge from branch tonioni
author Chris Cannam
date Mon, 20 Apr 2015 09:21:08 +0100
parents c48bc6ddfe17
children 3e2a2ca24d90
line wrap: on
line diff
--- a/audioio/AudioCallbackPlaySource.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/AudioCallbackPlaySource.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -149,7 +149,7 @@
 {
     if (m_models.find(model) != m_models.end()) return;
 
-    bool canPlay = m_audioGenerator->addModel(model);
+    bool willPlay = m_audioGenerator->addModel(model);
 
     m_mutex.lock();
 
@@ -225,7 +225,7 @@
 	clearRingBuffers(true, getTargetChannelCount());
 	buffersChanged = true;
     } else {
-	if (canPlay) clearRingBuffers(true);
+	if (willPlay) clearRingBuffers(true);
     }
 
     if (buffersChanged || srChanged) {
@@ -256,8 +256,8 @@
 	emit modelReplaced();
     }
 
-    connect(model, SIGNAL(modelChangedWithin(int, int)),
-            this, SLOT(modelChangedWithin(int, int)));
+    connect(model, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)),
+            this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t)));
 
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
     cout << "AudioCallbackPlaySource::addModel: awakening thread" << endl;
@@ -267,11 +267,11 @@
 }
 
 void
-AudioCallbackPlaySource::modelChangedWithin(int 
+AudioCallbackPlaySource::modelChangedWithin(sv_frame_t 
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
                                             startFrame
 #endif
-                                            , int endFrame)
+                                            , sv_frame_t endFrame)
 {
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
     SVDEBUG << "AudioCallbackPlaySource::modelChangedWithin(" << startFrame << "," << endFrame << ")" << endl;
@@ -291,8 +291,8 @@
     cout << "AudioCallbackPlaySource::removeModel(" << model << ")" << endl;
 #endif
 
-    disconnect(model, SIGNAL(modelChangedWithin(int, int)),
-               this, SLOT(modelChangedWithin(int, int)));
+    disconnect(model, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)),
+               this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t)));
 
     m_models.erase(model);
 
@@ -306,7 +306,7 @@
 	m_sourceSampleRate = 0;
     }
 
-    int lastEnd = 0;
+    sv_frame_t lastEnd = 0;
     for (std::set<Model *>::const_iterator i = m_models.begin();
 	 i != m_models.end(); ++i) {
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
@@ -362,21 +362,27 @@
 {
     if (!haveLock) m_mutex.lock();
 
+#ifdef DEBUG_AUDIO_PLAY_SOURCE
     cerr << "clearRingBuffers" << endl;
+#endif
 
     rebuildRangeLists();
 
     if (count == 0) {
-	if (m_writeBuffers) count = m_writeBuffers->size();
+	if (m_writeBuffers) count = int(m_writeBuffers->size());
     }
 
+#ifdef DEBUG_AUDIO_PLAY_SOURCE
     cerr << "current playing frame = " << getCurrentPlayingFrame() << endl;
 
     cerr << "write buffer fill (before) = " << m_writeBufferFill << endl;
-
+#endif
+    
     m_writeBufferFill = getCurrentBufferedFrame();
 
+#ifdef DEBUG_AUDIO_PLAY_SOURCE
     cerr << "current buffered frame = " << m_writeBufferFill << endl;
+#endif
 
     if (m_readBuffers != m_writeBuffers) {
 	delete m_writeBuffers;
@@ -388,6 +394,8 @@
 	m_writeBuffers->push_back(new RingBuffer<float>(m_ringBufferSize));
     }
 
+    m_audioGenerator->reset();
+    
 //    cout << "AudioCallbackPlaySource::clearRingBuffers: Created "
 //	      << count << " write buffers" << endl;
 
@@ -397,7 +405,7 @@
 }
 
 void
-AudioCallbackPlaySource::play(int startFrame)
+AudioCallbackPlaySource::play(sv_frame_t startFrame)
 {
     if (!m_sourceSampleRate) {
         cerr << "AudioCallbackPlaySource::play: No source sample rate available, not playing" << endl;
@@ -593,29 +601,29 @@
 AudioCallbackPlaySource::getTargetBlockSize() const
 {
 //    cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << endl;
-    return m_blockSize;
+    return int(m_blockSize);
 }
 
 void
-AudioCallbackPlaySource::setTargetPlayLatency(int latency)
+AudioCallbackPlaySource::setTargetPlayLatency(sv_frame_t latency)
 {
     m_playLatency = latency;
 }
 
-int
+sv_frame_t
 AudioCallbackPlaySource::getTargetPlayLatency() const
 {
     return m_playLatency;
 }
 
-int
+sv_frame_t
 AudioCallbackPlaySource::getCurrentPlayingFrame()
 {
     // This method attempts to estimate which audio sample frame is
     // "currently coming through the speakers".
 
-    int targetRate = getTargetSampleRate();
-    int latency = m_playLatency; // at target rate
+    sv_samplerate_t targetRate = getTargetSampleRate();
+    sv_frame_t latency = m_playLatency; // at target rate
     RealTime latency_t = RealTime::zeroTime;
 
     if (targetRate != 0) {
@@ -625,13 +633,13 @@
     return getCurrentFrame(latency_t);
 }
 
-int
+sv_frame_t
 AudioCallbackPlaySource::getCurrentBufferedFrame()
 {
     return getCurrentFrame(RealTime::zeroTime);
 }
 
-int
+sv_frame_t
 AudioCallbackPlaySource::getCurrentFrame(RealTime latency_t)
 {
     // We resample when filling the ring buffer, and time-stretch when
@@ -640,8 +648,8 @@
     // Because of the multiple rates involved, we do the actual
     // calculation using RealTime instead.
 
-    int sourceRate = getSourceSampleRate();
-    int targetRate = getTargetSampleRate();
+    sv_samplerate_t sourceRate = getSourceSampleRate();
+    sv_samplerate_t targetRate = getTargetSampleRate();
 
     if (sourceRate == 0 || targetRate == 0) return 0;
 
@@ -655,8 +663,8 @@
 	}
     }
 
-    int readBufferFill = m_readBufferFill;
-    int lastRetrievedBlockSize = m_lastRetrievedBlockSize;
+    sv_frame_t readBufferFill = m_readBufferFill;
+    sv_frame_t lastRetrievedBlockSize = m_lastRetrievedBlockSize;
     double lastRetrievalTimestamp = m_lastRetrievalTimestamp;
     double currentTime = 0.0;
     if (m_target) currentTime = m_target->getCurrentTime();
@@ -665,7 +673,7 @@
 
     RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, targetRate);
 
-    int stretchlat = 0;
+    sv_frame_t stretchlat = 0;
     double timeRatio = 1.0;
 
     if (m_timeStretcher) {
@@ -739,7 +747,7 @@
             - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t
             + sincerequest_t;
         if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime;
-        int frame = RealTime::realTime2Frame(playing_t, sourceRate);
+        sv_frame_t frame = RealTime::realTime2Frame(playing_t, sourceRate);
         return m_viewManager->alignPlaybackFrameToReference(frame);
     }
 
@@ -755,7 +763,9 @@
         ++index;
     }
 
-    if (inRange >= (int)m_rangeStarts.size()) inRange = m_rangeStarts.size()-1;
+    if (inRange >= int(m_rangeStarts.size())) {
+        inRange = int(m_rangeStarts.size())-1;
+    }
 
     RealTime playing_t = bufferedto_t;
 
@@ -806,7 +816,7 @@
 
         if (inRange == 0) {
             if (looping) {
-                inRange = m_rangeStarts.size() - 1;
+                inRange = int(m_rangeStarts.size()) - 1;
             } else {
                 break;
             }
@@ -833,7 +843,7 @@
 
     if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime;
 
-    int frame = RealTime::realTime2Frame(playing_t, sourceRate);
+    sv_frame_t frame = RealTime::realTime2Frame(playing_t, sourceRate);
 
     if (m_lastCurrentFrame > 0 && !looping) {
         if (frame < m_lastCurrentFrame) {
@@ -854,7 +864,7 @@
     m_rangeStarts.clear();
     m_rangeDurations.clear();
 
-    int sourceRate = getSourceSampleRate();
+    sv_samplerate_t sourceRate = getSourceSampleRate();
     if (sourceRate == 0) return;
 
     RealTime end = RealTime::frame2RealTime(m_lastModelEndFrame, sourceRate);
@@ -916,7 +926,7 @@
 }
 
 void
-AudioCallbackPlaySource::setTargetSampleRate(int sr)
+AudioCallbackPlaySource::setTargetSampleRate(sv_samplerate_t sr)
 {
     bool first = (m_targetSampleRate == 0);
 
@@ -1033,7 +1043,7 @@
     clearRingBuffers();
 }
 
-int
+sv_samplerate_t
 AudioCallbackPlaySource::getTargetSampleRate() const
 {
     if (m_targetSampleRate) return m_targetSampleRate;
@@ -1053,35 +1063,35 @@
     return m_sourceChannelCount;
 }
 
-int
+sv_samplerate_t
 AudioCallbackPlaySource::getSourceSampleRate() const
 {
     return m_sourceSampleRate;
 }
 
 void
-AudioCallbackPlaySource::setTimeStretch(float factor)
+AudioCallbackPlaySource::setTimeStretch(double factor)
 {
     m_stretchRatio = factor;
 
     if (!getTargetSampleRate()) return; // have to make our stretcher later
 
-    if (m_timeStretcher || (factor == 1.f)) {
+    if (m_timeStretcher || (factor == 1.0)) {
         // stretch ratio will be set in next process call if appropriate
     } else {
         m_stretcherInputCount = getTargetChannelCount();
         RubberBandStretcher *stretcher = new RubberBandStretcher
-            (getTargetSampleRate(),
+            (int(getTargetSampleRate()),
              m_stretcherInputCount,
              RubberBandStretcher::OptionProcessRealTime,
              factor);
         RubberBandStretcher *monoStretcher = new RubberBandStretcher
-            (getTargetSampleRate(),
+            (int(getTargetSampleRate()),
              1,
              RubberBandStretcher::OptionProcessRealTime,
              factor);
         m_stretcherInputs = new float *[m_stretcherInputCount];
-        m_stretcherInputSizes = new int[m_stretcherInputCount];
+        m_stretcherInputSizes = new sv_frame_t[m_stretcherInputCount];
         for (int c = 0; c < m_stretcherInputCount; ++c) {
             m_stretcherInputSizes[c] = 16384;
             m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]];
@@ -1093,11 +1103,9 @@
     emit activity(tr("Change time-stretch factor to %1").arg(factor));
 }
 
-int
-AudioCallbackPlaySource::getSourceSamples(int ucount, float **buffer)
+sv_frame_t
+AudioCallbackPlaySource::getSourceSamples(sv_frame_t count, float **buffer)
 {
-    int count = ucount;
-
     if (!m_playing) {
 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
         SVDEBUG << "AudioCallbackPlaySource::getSourceSamples: Not playing" << endl;
@@ -1148,12 +1156,12 @@
     RubberBandStretcher *ts = m_timeStretcher;
     RubberBandStretcher *ms = m_monoStretcher;
 
-    float ratio = ts ? ts->getTimeRatio() : 1.f;
+    double ratio = ts ? ts->getTimeRatio() : 1.0;
 
     if (ratio != m_stretchRatio) {
         if (!ts) {
             cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: Time ratio change to " << m_stretchRatio << " is pending, but no stretcher is set" << endl;
-            m_stretchRatio = 1.f;
+            m_stretchRatio = 1.0;
         } else {
             ts->setTimeRatio(m_stretchRatio);
             if (ms) ms->setTimeRatio(m_stretchRatio);
@@ -1188,10 +1196,10 @@
 
 		// this is marginally more likely to leave our channels in
 		// sync after a processing failure than just passing "count":
-		int request = count;
+		sv_frame_t request = count;
 		if (ch > 0) request = got;
 
-		got = rb->read(buffer[ch], request);
+		got = rb->read(buffer[ch], int(request));
 	    
 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
 		cout << "AudioCallbackPlaySource::getSamples: got " << got << " (of " << count << ") samples on channel " << ch << ", signalling for more (possibly)" << endl;
@@ -1217,20 +1225,20 @@
     }
 
     int channels = getTargetChannelCount();
-    int available;
+    sv_frame_t available;
+    sv_frame_t fedToStretcher = 0;
     int warned = 0;
-    int fedToStretcher = 0;
 
     // The input block for a given output is approx output / ratio,
     // but we can't predict it exactly, for an adaptive timestretcher.
 
     while ((available = ts->available()) < count) {
 
-        int reqd = lrintf((count - available) / ratio);
-        reqd = std::max(reqd, (int)ts->getSamplesRequired());
+        sv_frame_t reqd = lrint(double(count - available) / ratio);
+        reqd = std::max(reqd, sv_frame_t(ts->getSamplesRequired()));
         if (reqd == 0) reqd = 1;
                 
-        int got = reqd;
+        sv_frame_t got = reqd;
 
 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
         cerr << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << endl;
@@ -1252,11 +1260,11 @@
             if (c >= m_stretcherInputCount) continue;
             RingBuffer<float> *rb = getReadRingBuffer(c);
             if (rb) {
-                int gotHere;
+                sv_frame_t gotHere;
                 if (stretchChannels == 1 && c > 0) {
-                    gotHere = rb->readAdding(m_stretcherInputs[0], got);
+                    gotHere = rb->readAdding(m_stretcherInputs[0], int(got));
                 } else {
-                    gotHere = rb->read(m_stretcherInputs[c], got);
+                    gotHere = rb->read(m_stretcherInputs[c], int(got));
                 }
                 if (gotHere < got) got = gotHere;
                 
@@ -1309,7 +1317,7 @@
 }
 
 void
-AudioCallbackPlaySource::applyAuditioningEffect(int count, float **buffers)
+AudioCallbackPlaySource::applyAuditioningEffect(sv_frame_t count, float **buffers)
 {
     if (m_auditioningPluginBypassed) return;
     RealTimePluginInstance *plugin = m_auditioningPlugin;
@@ -1343,7 +1351,7 @@
         }
     }
 
-    plugin->run(Vamp::RealTime::zeroTime, count);
+    plugin->run(Vamp::RealTime::zeroTime, int(count));
     
     for (int c = 0; c < getTargetChannelCount(); ++c) {
         for (int i = 0; i < count; ++i) {
@@ -1357,13 +1365,13 @@
 AudioCallbackPlaySource::fillBuffers()
 {
     static float *tmp = 0;
-    static int tmpSize = 0;
+    static sv_frame_t tmpSize = 0;
 
-    int space = 0;
+    sv_frame_t space = 0;
     for (int c = 0; c < getTargetChannelCount(); ++c) {
 	RingBuffer<float> *wb = getWriteRingBuffer(c);
 	if (wb) {
-	    int spaceHere = wb->getWriteSpace();
+	    sv_frame_t spaceHere = wb->getWriteSpace();
 	    if (c == 0 || spaceHere < space) space = spaceHere;
 	}
     }
@@ -1375,7 +1383,7 @@
         return false;
     }
 
-    int f = m_writeBufferFill;
+    sv_frame_t f = m_writeBufferFill;
 	
     bool readWriteEqual = (m_readBuffers == m_writeBuffers);
 
@@ -1398,8 +1406,8 @@
 
     int channels = getTargetChannelCount();
 
-    int orig = space;
-    int got = 0;
+    sv_frame_t orig = space;
+    sv_frame_t got = 0;
 
     static float **bufferPtrs = 0;
     static int bufferPtrCount = 0;
@@ -1410,7 +1418,7 @@
 	bufferPtrCount = channels;
     }
 
-    int generatorBlockSize = m_audioGenerator->getBlockSize();
+    sv_frame_t generatorBlockSize = m_audioGenerator->getBlockSize();
 
     if (resample && !m_converter) {
 	static bool warned = false;
@@ -1424,13 +1432,13 @@
 
 	double ratio =
 	    double(getTargetSampleRate()) / double(getSourceSampleRate());
-	orig = int(orig / ratio + 0.1);
+	orig = sv_frame_t(double(orig) / ratio + 0.1);
 
 	// orig must be a multiple of generatorBlockSize
 	orig = (orig / generatorBlockSize) * generatorBlockSize;
 	if (orig == 0) return false;
 
-	int work = std::max(orig, space);
+	sv_frame_t work = std::max(orig, space);
 
 	// We only allocate one buffer, but we use it in two halves.
 	// We place the non-interleaved values in the second half of
@@ -1492,7 +1500,7 @@
             err = src_process(m_converter, &data);
         }
 
-	int toCopy = int(got * ratio + 0.1);
+	sv_frame_t toCopy = sv_frame_t(double(got) * ratio + 0.1);
 
 	if (err) {
 	    cerr
@@ -1512,7 +1520,7 @@
 		tmp[i] = srcout[channels * i + c];
 	    }
 	    RingBuffer<float> *wb = getWriteRingBuffer(c);
-	    if (wb) wb->write(tmp, toCopy);
+	    if (wb) wb->write(tmp, int(toCopy));
 	}
 
 	m_writeBufferFill = f;
@@ -1521,7 +1529,7 @@
     } else {
 
 	// space must be a multiple of generatorBlockSize
-        int reqSpace = space;
+        sv_frame_t reqSpace = space;
 	space = (reqSpace / generatorBlockSize) * generatorBlockSize;
 	if (space == 0) {
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
@@ -1547,13 +1555,13 @@
 	    }
 	}
 
-	int got = mixModels(f, space, bufferPtrs); // also modifies f
+	sv_frame_t got = mixModels(f, space, bufferPtrs); // also modifies f
 
 	for (int c = 0; c < channels; ++c) {
 
 	    RingBuffer<float> *wb = getWriteRingBuffer(c);
 	    if (wb) {
-                int actual = wb->write(bufferPtrs[c], got);
+                int actual = wb->write(bufferPtrs[c], int(got));
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
 		cout << "Wrote " << actual << " samples for ch " << c << ", now "
 			  << wb->getReadSpace() << " to read" 
@@ -1580,14 +1588,14 @@
     return true;
 }    
 
-int
-AudioCallbackPlaySource::mixModels(int &frame, int count, float **buffers)
+sv_frame_t
+AudioCallbackPlaySource::mixModels(sv_frame_t &frame, sv_frame_t count, float **buffers)
 {
-    int processed = 0;
-    int chunkStart = frame;
-    int chunkSize = count;
-    int selectionSize = 0;
-    int nextChunkStart = chunkStart + chunkSize;
+    sv_frame_t processed = 0;
+    sv_frame_t chunkStart = frame;
+    sv_frame_t chunkSize = count;
+    sv_frame_t selectionSize = 0;
+    sv_frame_t nextChunkStart = chunkStart + chunkSize;
     
     bool looping = m_viewManager->getPlayLoopMode();
     bool constrained = (m_viewManager->getPlaySelectionMode() &&
@@ -1617,11 +1625,11 @@
 	nextChunkStart = chunkStart + chunkSize;
 	selectionSize = 0;
 
-	int fadeIn = 0, fadeOut = 0;
+	sv_frame_t fadeIn = 0, fadeOut = 0;
 
 	if (constrained) {
 
-            int rChunkStart =
+            sv_frame_t rChunkStart =
                 m_viewManager->alignPlaybackFrameToReference(chunkStart);
 	    
 	    Selection selection =
@@ -1643,9 +1651,9 @@
 
 	    } else {
 
-                int sf = m_viewManager->alignReferenceToPlaybackFrame
+                sv_frame_t sf = m_viewManager->alignReferenceToPlaybackFrame
                     (selection.getStartFrame());
-                int ef = m_viewManager->alignReferenceToPlaybackFrame
+                sv_frame_t ef = m_viewManager->alignReferenceToPlaybackFrame
                     (selection.getEndFrame());
 
 		selectionSize = ef - sf;
@@ -1761,7 +1769,7 @@
 	}
     }
 
-    int rf = m_readBufferFill;
+    sv_frame_t rf = m_readBufferFill;
     RingBuffer<float> *rb = getReadRingBuffer(0);
     if (rb) {
 	int rs = rb->getReadSpace();
@@ -1775,8 +1783,8 @@
     SVDEBUG << "AudioCallbackPlaySource::unifyRingBuffers: m_readBufferFill = " << m_readBufferFill << ", rf = " << rf << ", m_writeBufferFill = " << m_writeBufferFill << endl;
 #endif
 
-    int wf = m_writeBufferFill;
-    int skip = 0;
+    sv_frame_t wf = m_writeBufferFill;
+    sv_frame_t skip = 0;
     for (int c = 0; c < getTargetChannelCount(); ++c) {
 	RingBuffer<float> *wb = getWriteRingBuffer(c);
 	if (wb) {
@@ -1794,7 +1802,7 @@
 	    }
 
 //	    cout << "skipping " << skip << endl;
-	    wb->skip(skip);
+	    wb->skip(int(skip));
 	}
     }
 		    
@@ -1837,10 +1845,9 @@
 
 	} else {
 	    
-	    float ms = 100;
+	    double ms = 100;
 	    if (s.getSourceSampleRate() > 0) {
-		ms = float(s.m_ringBufferSize) /
-                    float(s.getSourceSampleRate()) * 1000.0;
+		ms = double(s.m_ringBufferSize) / s.getSourceSampleRate() * 1000.0;
 	    }
 	    
 	    if (s.m_playing) ms /= 10;