# HG changeset patch # User Chris Cannam # Date 1382095342 -3600 # Node ID 1b95c3a52b45819f09a088209228c201ad76391c # Parent 1879a2997ebf2e0a2be5959798cc1d1014ef5562 Write latency tail diff -r 1879a2997ebf -r 1b95c3a52b45 garage-resampler/resample.cpp --- 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 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 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);