comparison 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
comparison
equal deleted inserted replaced
12:1879a2997ebf 13:1b95c3a52b45
92 if (!sndfileOut) { 92 if (!sndfileOut) {
93 cerr << "ERROR: Failed to open output file \"" << fileNameOut << "\" for writing: " 93 cerr << "ERROR: Failed to open output file \"" << fileNameOut << "\" for writing: "
94 << sf_strerror(sndfileOut) << endl; 94 << sf_strerror(sndfileOut) << endl;
95 return 1; 95 return 1;
96 } 96 }
97
98 int channels = sfinfo.channels;
99 vector<Resampler *> resamplers; // one per channel
100
101 for (int c = 0; c < channels; ++c) {
102 resamplers.push_back(new Resampler(sourceRate, targetRate));
103 }
104
105 int outputLatency = resamplers[0]->getLatency();
106 int inputLatency = int(ceil((double(outputLatency) * sourceRate) /
107 targetRate));
97 108
98 int ibs = 1024; 109 int ibs = 1024;
110 if (ibs < inputLatency) {
111 ibs = inputLatency;
112 }
113
99 int obs = int(ceil((double(ibs) * targetRate) / sourceRate)); 114 int obs = int(ceil((double(ibs) * targetRate) / sourceRate));
100 115
101 int channels = sfinfo.channels;
102 float *ibuf = new float[channels * ibs]; 116 float *ibuf = new float[channels * ibs];
103 float *obuf = new float[channels * obs]; 117 float *obuf = new float[channels * obs];
104 118
105 double **prebuf = new double*[channels]; 119 double **prebuf = new double*[channels];
106 double **postbuf = new double*[channels]; 120 double **postbuf = new double*[channels];
107 vector<Resampler *> resamplers; // one per channel
108 121
109 for (int c = 0; c < channels; ++c) { 122 for (int c = 0; c < channels; ++c) {
110 prebuf[c] = new double[ibs]; 123 prebuf[c] = new double[ibs];
111 postbuf[c] = new double[obs]; 124 postbuf[c] = new double[obs];
112 resamplers.push_back(new Resampler(sourceRate, targetRate)); 125 }
113 } 126
114
115 int latency = resamplers[0]->getLatency();
116 int n = 0; 127 int n = 0;
128 int rcount = 0;
129 int ocount = 0;
117 130
118 while (true) { 131 while (true) {
119 132
120 int count = sf_readf_float(sndfile, ibuf, ibs); 133 int count = sf_readf_float(sndfile, ibuf, ibs);
121 if (count <= 0) break; 134 if (count <= 0) break;
122 135
123 int rcount = 0; 136 rcount = 0;
124 int ocount = 0; 137 ocount = 0;
125 138
126 for (int c = 0; c < channels; ++c) { 139 for (int c = 0; c < channels; ++c) {
127 140
128 for (int i = 0; i < count; ++i) { 141 for (int i = 0; i < count; ++i) {
129 prebuf[c][i] = ibuf[i * channels + c]; 142 prebuf[c][i] = ibuf[i * channels + c];
130 } 143 }
131 144
132 rcount = resamplers[c]->process(prebuf[c], postbuf[c], count); 145 rcount = resamplers[c]->process(prebuf[c], postbuf[c], count);
133 146
134 if (n + rcount > latency) { 147 if (n + rcount > outputLatency) {
135 int off = 0; 148 int off = 0;
136 if (latency > n) { 149 if (outputLatency > n) {
137 off = latency - n; 150 off = outputLatency - n;
138 } 151 }
139 for (int i = off; i < rcount; ++i) { 152 for (int i = off; i < rcount; ++i) {
140 obuf[(i - off) * channels + c] = postbuf[c][i]; 153 obuf[(i - off) * channels + c] = postbuf[c][i];
141 } 154 }
142 ocount = rcount - off; 155 ocount = rcount - off;
148 } 161 }
149 162
150 n += rcount; 163 n += rcount;
151 } 164 }
152 165
153 //!!! todo: tail (latency) 166 // latency tail
167 for (int c = 0; c < channels; ++c) {
168 for (int i = 0; i < inputLatency; ++i) {
169 prebuf[c][i] = 0.0;
170 }
171 rcount = resamplers[c]->process(prebuf[c], postbuf[c], inputLatency);
172 for (int i = 0; i < rcount; ++i) {
173 obuf[i * channels + c] = postbuf[c][i];
174 }
175 }
176 sf_writef_float(sndfileOut, obuf, rcount);
177 n += rcount;
154 178
155 sf_close(sndfile); 179 sf_close(sndfile);
156 sf_close(sndfileOut); 180 sf_close(sndfileOut);
157 181
158 for (int c = 0; c < channels; ++c) { 182 for (int c = 0; c < channels; ++c) {