Detect out-of-range samples on output and restart with lower gain
This commit is contained in:
@@ -121,6 +121,8 @@ int main(int argc, char **argv)
|
||||
SoftDetector
|
||||
} detector = CompoundDetector;
|
||||
|
||||
bool ignoreClipping = false;
|
||||
|
||||
while (1) {
|
||||
int optionIndex = 0;
|
||||
|
||||
@@ -155,6 +157,7 @@ int main(int argc, char **argv)
|
||||
{ "timemap", 1, 0, 'M' },
|
||||
{ "freqmap", 1, 0, 'Q' },
|
||||
{ "pitchmap", 1, 0, 'C' },
|
||||
{ "ignore-clipping", 0, 0, 'i' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -193,6 +196,7 @@ int main(int argc, char **argv)
|
||||
case 'M': timeMapFile = optarg; break;
|
||||
case 'Q': freqMapFile = optarg; freqOrPitchMapSpecified = true; break;
|
||||
case 'C': pitchMapFile = optarg; freqOrPitchMapSpecified = true; break;
|
||||
case 'i': ignoreClipping = true; break;
|
||||
default: help = true; break;
|
||||
}
|
||||
}
|
||||
@@ -283,6 +287,8 @@ int main(int argc, char **argv)
|
||||
cerr << " --pitch-hq In RT mode, use a slower, higher quality pitch shift" << endl;
|
||||
cerr << " --centre-focus Preserve focus of centre material in stereo" << endl;
|
||||
cerr << " (at a cost in width and individual channel quality)" << endl;
|
||||
cerr << " --ignore-clipping Ignore clipping at output; the default is to restart" << endl;
|
||||
cerr << " with reduced gain if clipping occurs" << endl;
|
||||
cerr << endl;
|
||||
cerr << " -d<N>, --debug <N> Select debug level (N = 0,1,2,3); default 0, full 3" << endl;
|
||||
cerr << " (N.B. debug level 3 includes audible ticks in output)" << endl;
|
||||
@@ -554,14 +560,24 @@ int main(int argc, char **argv)
|
||||
|
||||
RubberBandStretcher::setDefaultDebugLevel(debug);
|
||||
|
||||
size_t countIn = 0, countOut = 0;
|
||||
|
||||
float gain = 1.f;
|
||||
bool successful = false;
|
||||
|
||||
while (!successful) { // we may have to repeat with a modified
|
||||
// gain, if clipping occurs
|
||||
successful = true;
|
||||
|
||||
RubberBandStretcher ts(sfinfo.samplerate, channels, options,
|
||||
ratio, frequencyshift);
|
||||
|
||||
ts.setExpectedInputDuration(sfinfo.frames);
|
||||
|
||||
float *fbuf = new float[channels * ibs];
|
||||
float **ibuf = new float *[channels];
|
||||
for (size_t i = 0; i < channels; ++i) ibuf[i] = new float[ibs];
|
||||
for (size_t i = 0; i < channels; ++i) {
|
||||
ibuf[i] = new float[ibs];
|
||||
}
|
||||
|
||||
int frame = 0;
|
||||
int percent = 0;
|
||||
@@ -618,7 +634,9 @@ int main(int argc, char **argv)
|
||||
|
||||
std::map<size_t, double>::const_iterator freqMapItr = freqMap.begin();
|
||||
|
||||
size_t countIn = 0, countOut = 0;
|
||||
countIn = 0;
|
||||
countOut = 0;
|
||||
bool clipping = false;
|
||||
|
||||
while (frame < sfinfo.frames) {
|
||||
|
||||
@@ -645,7 +663,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if ((count = sf_readf_float(sndfile, fbuf, thisBlockSize)) < 0) break;
|
||||
if ((count = sf_readf_float(sndfile, fbuf, thisBlockSize)) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
countIn += count;
|
||||
|
||||
@@ -677,19 +697,19 @@ int main(int argc, char **argv)
|
||||
float *fobf = new float[channels * avail];
|
||||
for (size_t c = 0; c < channels; ++c) {
|
||||
for (int i = 0; i < avail; ++i) {
|
||||
float value = obf[c][i];
|
||||
float value = gain * obf[c][i];
|
||||
if (ignoreClipping) { // i.e. just clamp, don't bail out
|
||||
if (value > 1.f) value = 1.f;
|
||||
if (value < -1.f) value = -1.f;
|
||||
} else {
|
||||
if (value >= 1.f || value < -1.f) {
|
||||
clipping = true;
|
||||
gain = (0.999f / fabsf(obf[c][i]));
|
||||
}
|
||||
}
|
||||
fobf[i * channels + c] = value;
|
||||
}
|
||||
}
|
||||
// cout << "fobf mean: ";
|
||||
// double d = 0;
|
||||
// for (int i = 0; i < avail; ++i) {
|
||||
// d += fobf[i];
|
||||
// }
|
||||
// d /= avail;
|
||||
// cout << d << endl;
|
||||
sf_writef_float(sndfileOut, fobf, avail);
|
||||
delete[] fobf;
|
||||
for (size_t i = 0; i < channels; ++i) {
|
||||
@@ -698,6 +718,17 @@ int main(int argc, char **argv)
|
||||
delete[] obf;
|
||||
}
|
||||
|
||||
if (clipping) {
|
||||
if (!quiet) {
|
||||
cerr << "NOTE: Clipping detected at output sample "
|
||||
<< countOut << ", restarting with "
|
||||
<< "reduced gain of " << gain
|
||||
<< " (supply --ignore-clipping to avoid this)" << endl;
|
||||
}
|
||||
successful = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (frame == 0 && !realtime && !quiet) {
|
||||
cerr << "Pass 2: Processing..." << endl;
|
||||
}
|
||||
@@ -713,6 +744,12 @@ int main(int argc, char **argv)
|
||||
frame += thisBlockSize;
|
||||
}
|
||||
|
||||
if (!successful) {
|
||||
sf_seek(sndfile, 0, SEEK_SET);
|
||||
sf_seek(sndfileOut, 0, SEEK_SET);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
cerr << "\r " << endl;
|
||||
}
|
||||
@@ -734,7 +771,7 @@ int main(int argc, char **argv)
|
||||
float *fobf = new float[channels * avail];
|
||||
for (size_t c = 0; c < channels; ++c) {
|
||||
for (int i = 0; i < avail; ++i) {
|
||||
float value = obf[c][i];
|
||||
float value = gain * obf[c][i];
|
||||
if (value > 1.f) value = 1.f;
|
||||
if (value < -1.f) value = -1.f;
|
||||
fobf[i * channels + c] = value;
|
||||
@@ -751,6 +788,7 @@ int main(int argc, char **argv)
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sf_close(sndfile);
|
||||
sf_close(sndfileOut);
|
||||
|
||||
Reference in New Issue
Block a user