Out of curiosity I tried a long upconvert using:
SoX -V -S -r 192000 -b 24 -n -n synth 3:15:00 pinknoise sinc -a 40 -t 8k -24k
and sure enough, the same hang occurs in SoX. So, I searched through all of their code and found
two more instances in dft_filter.c and tempo.c where SoX will hang like it did for rate.c. I submitted
a bug report to them and patched my own SoX. Here is my updated patch file in case you want
to try and use the upsample method bandpass describes:
diff -cr sox-14.4.0/src/rate.c sox-14.4.0-update/src/rate.c
*** sox-14.4.0/src/rate.c Tue Dec 27 22:15:32 2011
--- sox-14.4.0-update/src/rate.c Tue Dec 4 11:04:47 2012
***************
*** 397,403 ****
size_t remaining = samples_out - p->samples_out;
sample_t * buff = calloc(1024, sizeof(*buff));
! if ((int)remaining > 0) {
while ((size_t)fifo_occupancy(fifo) < remaining) {
rate_input(p, buff, (size_t) 1024);
rate_process(p);
--- 397,403 ----
size_t remaining = samples_out - p->samples_out;
sample_t * buff = calloc(1024, sizeof(*buff));
! if (samples_out > p->samples_out) {
while ((size_t)fifo_occupancy(fifo) < remaining) {
rate_input(p, buff, (size_t) 1024);
rate_process(p);
diff -cr sox-14.4.0/src/dft_filter.c sox-14.4.0-update/src/dft_filter.c
*** sox-14.4.0/src/dft_filter.c Wed Mar 2 19:47:52 2011
--- sox-14.4.0-update/src/dft_filter.c Tue Dec 11 11:25:29 2012
***************
*** 108,114 ****
size_t remaining = samples_out - p->samples_out;
double * buff = lsx_calloc(1024, sizeof(*buff));
! if ((int)remaining > 0) {
while ((size_t)fifo_occupancy(&p->output_fifo) < remaining) {
fifo_write(&p->input_fifo, 1024, buff);
p->samples_in += 1024;
--- 108,114 ----
size_t remaining = samples_out - p->samples_out;
double * buff = lsx_calloc(1024, sizeof(*buff));
! if (samples_out > p->samples_out) {
while ((size_t)fifo_occupancy(&p->output_fifo) < remaining) {
fifo_write(&p->input_fifo, 1024, buff);
p->samples_in += 1024;
diff -cr sox-14.4.0/src/tempo.c sox-14.4.0-update/src/tempo.c
*** sox-14.4.0/src/tempo.c Sat Jan 21 16:33:13 2012
--- sox-14.4.0-update/src/tempo.c Tue Dec 11 11:34:31 2012
***************
*** 151,162 ****
size_t remaining = samples_out - t->samples_out;
float * buff = lsx_calloc(128 * t->channels, sizeof(*buff));
! if ((int)remaining > 0) {
! while (fifo_occupancy(&t->output_fifo) < remaining) {
tempo_input(t, buff, (size_t) 128);
tempo_process(t);
}
! fifo_trim_to(&t->output_fifo, remaining);
t->samples_in = 0;
}
free(buff);
--- 151,162 ----
size_t remaining = samples_out - t->samples_out;
float * buff = lsx_calloc(128 * t->channels, sizeof(*buff));
! if (samples_out > t->samples_out) {
! while ((size_t)fifo_occupancy(&t->output_fifo) < remaining) {
tempo_input(t, buff, (size_t) 128);
tempo_process(t);
}
! fifo_trim_to(&t->output_fifo, (int)remaining);
t->samples_in = 0;
}
free(buff);
Unlike the rate effect, beware that sinc automatically adds rate after itself to make the output rate the same as the input rate unless the output rate is specified with a -r switch. Also, the upsample+sinc is faster than the rate+rate currently being used in the effect chain.