diff garage-resampler/resample.cpp @ 13:1b95c3a52b45

Write latency tail
author Chris Cannam
date Fri, 18 Oct 2013 12:22:22 +0100
parents 1879a2997ebf
children 8c87484e6d79
line wrap: on
line diff
--- a/garage-resampler/resample.cpp	Fri Oct 18 12:18:10 2013 +0100
+++ b/garage-resampler/resample.cpp	Fri Oct 18 12:22:22 2013 +0100
@@ -94,34 +94,47 @@
 	     << sf_strerror(sndfileOut) << endl;
 	return 1;
     }
+
+    int channels = sfinfo.channels;
+    vector<Resampler *> resamplers; // one per channel
+
+    for (int c = 0; c < channels; ++c) {
+	resamplers.push_back(new Resampler(sourceRate, targetRate));
+    }
+
+    int outputLatency = resamplers[0]->getLatency();
+    int inputLatency = int(ceil((double(outputLatency) * sourceRate) / 
+				targetRate));
     
     int ibs = 1024;
+    if (ibs < inputLatency) {
+	ibs = inputLatency;
+    }
+
     int obs = int(ceil((double(ibs) * targetRate) / sourceRate));
 
-    int channels = sfinfo.channels;
     float *ibuf = new float[channels * ibs];
     float *obuf = new float[channels * obs];
     
     double **prebuf = new double*[channels];
     double **postbuf = new double*[channels];
-    vector<Resampler *> resamplers; // one per channel
 
     for (int c = 0; c < channels; ++c) {
 	prebuf[c] = new double[ibs];
 	postbuf[c] = new double[obs];
-	resamplers.push_back(new Resampler(sourceRate, targetRate));
     }
     
-    int latency = resamplers[0]->getLatency();
     int n = 0;
+    int rcount = 0;
+    int	ocount = 0;
     
     while (true) {
 
 	int count = sf_readf_float(sndfile, ibuf, ibs);
 	if (count <= 0) break;
 	
-	int rcount = 0;
-	int ocount = 0;
+	rcount = 0;
+	ocount = 0;
 
 	for (int c = 0; c < channels; ++c) {
 
@@ -131,10 +144,10 @@
 
 	    rcount = resamplers[c]->process(prebuf[c], postbuf[c], count);
 	    
-	    if (n + rcount > latency) {
+	    if (n + rcount > outputLatency) {
 		int off = 0;
-		if (latency > n) {
-		    off = latency - n;
+		if (outputLatency > n) {
+		    off = outputLatency - n;
 		}
 		for (int i = off; i < rcount; ++i) {
 		    obuf[(i - off) * channels + c] = postbuf[c][i];
@@ -150,7 +163,18 @@
 	n += rcount;
     }
 
-    //!!! todo: tail (latency)
+    // latency tail
+    for (int c = 0; c < channels; ++c) {
+	for (int i = 0; i < inputLatency; ++i) {
+	    prebuf[c][i] = 0.0;
+	}
+	rcount = resamplers[c]->process(prebuf[c], postbuf[c], inputLatency);
+	for (int i = 0; i < rcount; ++i) {
+	    obuf[i * channels + c] = postbuf[c][i];
+	}
+    }
+    sf_writef_float(sndfileOut, obuf, rcount);
+    n += rcount;
 
     sf_close(sndfile);
     sf_close(sndfileOut);