diff audioio/AudioCallbackPlaySource.cpp @ 26:d88d117e0c34

* Add mono timestretch toggle button; some more work on getting blocksize etc parameters through to plugins
author Chris Cannam
date Mon, 18 Sep 2006 16:43:17 +0000
parents e74f508db18c
children 37af203dbd15
line wrap: on
line diff
--- a/audioio/AudioCallbackPlaySource.cpp	Fri Sep 15 15:35:06 2006 +0000
+++ b/audioio/AudioCallbackPlaySource.cpp	Mon Sep 18 16:43:17 2006 +0000
@@ -588,34 +588,41 @@
 }
 
 void
-AudioCallbackPlaySource::setSlowdownFactor(float factor, bool sharpen)
+AudioCallbackPlaySource::setTimeStretch(float factor, bool sharpen, bool mono)
 {
     // Avoid locks -- create, assign, mark old one for scavenging
     // later (as a call to getSourceSamples may still be using it)
 
     PhaseVocoderTimeStretcher *existingStretcher = m_timeStretcher;
 
+    size_t channels = getTargetChannelCount();
+    if (mono) channels = 1;
+
     if (existingStretcher &&
         existingStretcher->getRatio() == factor &&
-        existingStretcher->getSharpening() == sharpen) {
+        existingStretcher->getSharpening() == sharpen &&
+        existingStretcher->getChannelCount() == channels) {
 	return;
     }
 
     if (factor != 1) {
 
         if (existingStretcher &&
-            existingStretcher->getSharpening() == sharpen) {
+            existingStretcher->getSharpening() == sharpen &&
+            existingStretcher->getChannelCount() == channels) {
             existingStretcher->setRatio(factor);
             return;
         }
 
 	PhaseVocoderTimeStretcher *newStretcher = new PhaseVocoderTimeStretcher
 	    (getTargetSampleRate(),
-             getTargetChannelCount(),
+             channels,
              factor,
              sharpen,
              lrintf(getTargetBlockSize() / factor));
+
 	m_timeStretcher = newStretcher;
+
     } else {
 	m_timeStretcher = 0;
     }
@@ -624,7 +631,7 @@
 	m_timeStretcherScavenger.claim(existingStretcher);
     }
 }
-	    
+
 size_t
 AudioCallbackPlaySource::getSourceSamples(size_t count, float **buffer)
 {
@@ -676,6 +683,9 @@
 
 //            std::cout << "ratio = " << ratio << std::endl;
 
+    size_t channels = getTargetChannelCount();
+    bool mix = (channels > 1 && ts->getChannelCount() == 1);
+
     size_t available;
 
     while ((available = ts->getAvailableOutputSamples()) < count) {
@@ -684,18 +694,30 @@
         reqd = std::max(reqd, ts->getRequiredInputSamples());
         if (reqd == 0) reqd = 1;
                 
-        size_t channels = getTargetChannelCount();
-
         float *ib[channels];
 
         size_t got = reqd;
 
-        for (size_t c = 0; c < channels; ++c) {
-            ib[c] = new float[reqd]; //!!! fix -- this is a rt function
-            RingBuffer<float> *rb = getReadRingBuffer(c);
-            if (rb) {
-                size_t gotHere = rb->read(ib[c], got);
-                if (gotHere < got) got = gotHere;
+        if (mix) {
+            for (size_t c = 0; c < channels; ++c) {
+                if (c == 0) ib[c] = new float[reqd]; //!!! fix -- this is a rt function
+                else ib[c] = 0;
+                RingBuffer<float> *rb = getReadRingBuffer(c);
+                if (rb) {
+                    size_t gotHere;
+                    if (c > 0) gotHere = rb->readAdding(ib[0], got);
+                    else gotHere = rb->read(ib[0], got);
+                    if (gotHere < got) got = gotHere;
+                }
+            }
+        } else {
+            for (size_t c = 0; c < channels; ++c) {
+                ib[c] = new float[reqd]; //!!! fix -- this is a rt function
+                RingBuffer<float> *rb = getReadRingBuffer(c);
+                if (rb) {
+                    size_t gotHere = rb->read(ib[c], got);
+                    if (gotHere < got) got = gotHere;
+                }
             }
         }
 
@@ -720,6 +742,17 @@
 
     ts->getOutput(buffer, count);
 
+    if (mix) {
+        for (size_t c = 1; c < channels; ++c) {
+            for (size_t i = 0; i < count; ++i) {
+                buffer[c][i] = buffer[0][i] / channels;
+            }
+        }
+        for (size_t i = 0; i < count; ++i) {
+            buffer[0][i] /= channels;
+        }
+    }
+
     m_condition.wakeAll();
 
     return count;