diff options
Diffstat (limited to 'gst-libs/gst/resample/resample.c')
-rw-r--r-- | gst-libs/gst/resample/resample.c | 1371 |
1 files changed, 687 insertions, 684 deletions
diff --git a/gst-libs/gst/resample/resample.c b/gst-libs/gst/resample/resample.c index 8cac9de6..cd409d23 100644 --- a/gst-libs/gst/resample/resample.c +++ b/gst-libs/gst/resample/resample.c @@ -30,100 +30,107 @@ #include <gst/gstplugin.h> #include <gst/gstversion.h> -inline double sinc(double x) +inline double +sinc (double x) { - if(x==0)return 1; - return sin(x) / x; + if (x == 0) + return 1; + return sin (x) / x; } -inline double window_func(double x) +inline double +window_func (double x) { - x = 1 - x*x; - return x*x; + x = 1 - x * x; + return x * x; } -signed short double_to_s16(double x) +signed short +double_to_s16 (double x) { - if(x<-32768){ - printf("clipped\n"); - return -32768; - } - if(x>32767){ - printf("clipped\n"); - return -32767; - } - return rint(x); + if (x < -32768) { + printf ("clipped\n"); + return -32768; + } + if (x > 32767) { + printf ("clipped\n"); + return -32767; + } + return rint (x); } -signed short double_to_s16_ppcasm(double x) +signed short +double_to_s16_ppcasm (double x) { - if(x<-32768){ - return -32768; - } - if(x>32767){ - return -32767; - } - return rint(x); + if (x < -32768) { + return -32768; + } + if (x > 32767) { + return -32767; + } + return rint (x); } -void gst_resample_init(gst_resample_t * r) +void +gst_resample_init (gst_resample_t * r) { - r->i_start = 0; - if(r->filter_length&1){ - r->o_start = 0; - }else{ - r->o_start = r->o_inc * 0.5; - } + r->i_start = 0; + if (r->filter_length & 1) { + r->o_start = 0; + } else { + r->o_start = r->o_inc * 0.5; + } - memset(r->acc, 0, sizeof(r->acc)); + memset (r->acc, 0, sizeof (r->acc)); - gst_resample_reinit(r); + gst_resample_reinit (r); } -void gst_resample_reinit(gst_resample_t * r) +void +gst_resample_reinit (gst_resample_t * r) { - /* i_inc is the number of samples that the output increments for - * each input sample. o_inc is the opposite. */ - r->i_inc = (double) r->o_rate / r->i_rate; - r->o_inc = (double) r->i_rate / r->o_rate; - - r->halftaps = (r->filter_length - 1.0) * 0.5; - - if (r->format == GST_RESAMPLE_S16) { - switch (r->method) { - default: - case GST_RESAMPLE_NEAREST: - r->scale = gst_resample_nearest_s16; - break; - case GST_RESAMPLE_BILINEAR: - r->scale = gst_resample_bilinear_s16; - break; - case GST_RESAMPLE_SINC_SLOW: - r->scale = gst_resample_sinc_s16; - break; - case GST_RESAMPLE_SINC: - r->scale = gst_resample_sinc_ft_s16; - break; - } - } else if (r->format == GST_RESAMPLE_FLOAT) { - switch (r->method) { - default: - case GST_RESAMPLE_NEAREST: - r->scale = gst_resample_nearest_float; - break; - case GST_RESAMPLE_BILINEAR: - r->scale = gst_resample_bilinear_float; - break; - case GST_RESAMPLE_SINC_SLOW: - r->scale = gst_resample_sinc_float; - break; - case GST_RESAMPLE_SINC: - r->scale = gst_resample_sinc_ft_float; - break; - } - } else { - fprintf (stderr, "gst_resample: Unexpected format \"%d\"\n", r->format); - } + /* i_inc is the number of samples that the output increments for + * each input sample. o_inc is the opposite. */ + r->i_inc = (double) r->o_rate / r->i_rate; + r->o_inc = (double) r->i_rate / r->o_rate; + + r->halftaps = (r->filter_length - 1.0) * 0.5; + + if (r->format == GST_RESAMPLE_S16) { + switch (r->method) { + default: + case GST_RESAMPLE_NEAREST: + r->scale = gst_resample_nearest_s16; + break; + case GST_RESAMPLE_BILINEAR: + r->scale = gst_resample_bilinear_s16; + break; + case GST_RESAMPLE_SINC_SLOW: + r->scale = gst_resample_sinc_s16; + break; + case GST_RESAMPLE_SINC: + r->scale = gst_resample_sinc_ft_s16; + break; + } + } else if (r->format == GST_RESAMPLE_FLOAT) { + switch (r->method) { + default: + case GST_RESAMPLE_NEAREST: + r->scale = gst_resample_nearest_float; + break; + case GST_RESAMPLE_BILINEAR: + r->scale = gst_resample_bilinear_float; + break; + case GST_RESAMPLE_SINC_SLOW: + r->scale = gst_resample_sinc_float; + break; + case GST_RESAMPLE_SINC: + r->scale = gst_resample_sinc_ft_float; + break; + } + } else { + fprintf (stderr, "gst_resample: Unexpected format \"%d\"\n", r->format); + } } /* @@ -140,94 +147,94 @@ void gst_resample_reinit(gst_resample_t * r) * i_start_buf is the time of the first sample in the temporary * buffer. */ -void gst_resample_scale(gst_resample_t * r, void *i_buf, unsigned int i_size) +void +gst_resample_scale (gst_resample_t * r, void *i_buf, unsigned int i_size) { - int o_size; - - r->i_buf = i_buf; - - r->i_samples = i_size / 2 / r->channels; - - r->i_start_buf = r->i_start - r->filter_length * r->i_inc; - - /* i_start is the offset (in a given output sample) that is the - * beginning of the current input buffer */ - r->i_end = r->i_start + r->i_inc * r->i_samples; - - r->o_samples = floor(r->i_end - r->halftaps * r->i_inc); - - o_size = r->o_samples * r->channels * 2; - r->o_buf = r->get_buffer(r->priv, o_size); - - if(r->verbose){ - printf("gst_resample_scale: i_buf=%p i_size=%d\n", - i_buf,i_size); - printf("gst_resample_scale: i_samples=%d o_samples=%d i_inc=%g o_buf=%p\n", - r->i_samples, r->o_samples, r->i_inc, r->o_buf); - printf("gst_resample_scale: i_start=%g i_end=%g o_start=%g\n", - r->i_start, r->i_end, r->o_start); - } - - if ((r->filter_length + r->i_samples)*sizeof(double)*2 > r->buffer_len) { - int size = (r->filter_length + r->i_samples) * sizeof(double) * 2; - - if(r->verbose){ - printf("gst_resample temp buffer size=%d\n",size); - } - if(r->buffer)free(r->buffer); - r->buffer_len = size; - r->buffer = malloc(size); - memset(r->buffer, 0, size); - } - - if (r->format==GST_RESAMPLE_S16) { - if(r->channels==2){ - conv_double_short( - r->buffer + r->filter_length * sizeof(double) * 2, - r->i_buf, r->i_samples * 2); - } else { - conv_double_short_dstr( - r->buffer + r->filter_length * sizeof(double) * 2, - r->i_buf, r->i_samples, sizeof(double) * 2); - } - } else if (r->format==GST_RESAMPLE_FLOAT) { - if(r->channels==2){ - conv_double_float( - r->buffer + r->filter_length * sizeof(double) * 2, - r->i_buf, r->i_samples * 2); - } else { - conv_double_float_dstr( - r->buffer + r->filter_length * sizeof(double) * 2, - r->i_buf, r->i_samples, sizeof(double) * 2); - } - } - - r->scale(r); - - memcpy(r->buffer, - r->buffer + r->i_samples * sizeof(double) * 2, - r->filter_length * sizeof(double) * 2); - - /* updating times */ - r->i_start += r->i_samples * r->i_inc; - r->o_start += r->o_samples * r->o_inc - r->i_samples; - - /* adjusting timebase zero */ - r->i_start -= r->o_samples; + int o_size; + + r->i_buf = i_buf; + + r->i_samples = i_size / 2 / r->channels; + + r->i_start_buf = r->i_start - r->filter_length * r->i_inc; + + /* i_start is the offset (in a given output sample) that is the + * beginning of the current input buffer */ + r->i_end = r->i_start + r->i_inc * r->i_samples; + + r->o_samples = floor (r->i_end - r->halftaps * r->i_inc); + + o_size = r->o_samples * r->channels * 2; + r->o_buf = r->get_buffer (r->priv, o_size); + + if (r->verbose) { + printf ("gst_resample_scale: i_buf=%p i_size=%d\n", i_buf, i_size); + printf ("gst_resample_scale: i_samples=%d o_samples=%d i_inc=%g o_buf=%p\n", + r->i_samples, r->o_samples, r->i_inc, r->o_buf); + printf ("gst_resample_scale: i_start=%g i_end=%g o_start=%g\n", + r->i_start, r->i_end, r->o_start); + } + + if ((r->filter_length + r->i_samples) * sizeof (double) * 2 > r->buffer_len) { + int size = (r->filter_length + r->i_samples) * sizeof (double) * 2; + + if (r->verbose) { + printf ("gst_resample temp buffer size=%d\n", size); + } + if (r->buffer) + free (r->buffer); + r->buffer_len = size; + r->buffer = malloc (size); + memset (r->buffer, 0, size); + } + + if (r->format == GST_RESAMPLE_S16) { + if (r->channels == 2) { + conv_double_short (r->buffer + r->filter_length * sizeof (double) * 2, + r->i_buf, r->i_samples * 2); + } else { + conv_double_short_dstr (r->buffer + + r->filter_length * sizeof (double) * 2, r->i_buf, r->i_samples, + sizeof (double) * 2); + } + } else if (r->format == GST_RESAMPLE_FLOAT) { + if (r->channels == 2) { + conv_double_float (r->buffer + r->filter_length * sizeof (double) * 2, + r->i_buf, r->i_samples * 2); + } else { + conv_double_float_dstr (r->buffer + + r->filter_length * sizeof (double) * 2, r->i_buf, r->i_samples, + sizeof (double) * 2); + } + } + + r->scale (r); + + memcpy (r->buffer, + r->buffer + r->i_samples * sizeof (double) * 2, + r->filter_length * sizeof (double) * 2); + + /* updating times */ + r->i_start += r->i_samples * r->i_inc; + r->o_start += r->o_samples * r->o_inc - r->i_samples; + + /* adjusting timebase zero */ + r->i_start -= r->o_samples; } -void gst_resample_nearest_s16(gst_resample_t * r) +void +gst_resample_nearest_s16 (gst_resample_t * r) { - signed short *i_ptr, *o_ptr; - int i_count = 0; - double a; - int i; + signed short *i_ptr, *o_ptr; + int i_count = 0; + double a; + int i; - i_ptr = (signed short *) r->i_buf; - o_ptr = (signed short *) r->o_buf; + i_ptr = (signed short *) r->i_buf; + o_ptr = (signed short *) r->o_buf; - a = r->o_start; - i_count = 0; + a = r->o_start; + i_count = 0; #define SCALE_LOOP(COPY,INC) \ for (i = 0; i < r->o_samples; i++) { \ COPY; \ @@ -240,191 +247,190 @@ void gst_resample_nearest_s16(gst_resample_t * r) o_ptr+=INC; \ } - switch (r->channels) { - case 1: - SCALE_LOOP(o_ptr[0] = i_ptr[0], 1); - break; - case 2: - SCALE_LOOP(o_ptr[0] = i_ptr[0]; - o_ptr[1] = i_ptr[1], 2); - break; - default: - { - int n, n_chan = r->channels; - - SCALE_LOOP(for (n = 0; n < n_chan; n++) o_ptr[n] = - i_ptr[n], n_chan); - } - } - if (i_count != r->i_samples) { - printf("handled %d in samples (expected %d)\n", i_count, - r->i_samples); - } + switch (r->channels) { + case 1: + SCALE_LOOP (o_ptr[0] = i_ptr[0], 1); + break; + case 2: + SCALE_LOOP (o_ptr[0] = i_ptr[0]; o_ptr[1] = i_ptr[1], 2); + break; + default: + { + int n, n_chan = r->channels; + + SCALE_LOOP (for (n = 0; n < n_chan; n++) o_ptr[n] = i_ptr[n], n_chan); + } + } + if (i_count != r->i_samples) { + printf ("handled %d in samples (expected %d)\n", i_count, r->i_samples); + } } -void gst_resample_bilinear_s16(gst_resample_t * r) +void +gst_resample_bilinear_s16 (gst_resample_t * r) { - signed short *i_ptr, *o_ptr; - int o_count = 0; - double b; - int i; - double acc0, acc1; - - i_ptr = (signed short *) r->i_buf; - o_ptr = (signed short *) r->o_buf; - - acc0 = r->acc[0]; - acc1 = r->acc[1]; - b = r->i_start; - for (i = 0; i < r->i_samples; i++) { - b += r->i_inc; - /*printf("in %d\n",i_ptr[0]); */ - if(b>=2){ - printf("not expecting b>=2\n"); - } - if (b >= 1) { - acc0 += (1.0 - (b-r->i_inc)) * i_ptr[0]; - acc1 += (1.0 - (b-r->i_inc)) * i_ptr[1]; - - o_ptr[0] = rint(acc0); - /*printf("out %d\n",o_ptr[0]); */ - o_ptr[1] = rint(acc1); - o_ptr += 2; - o_count++; - - b -= 1.0; - - acc0 = b * i_ptr[0]; - acc1 = b * i_ptr[1]; - } else { - acc0 += i_ptr[0] * r->i_inc; - acc1 += i_ptr[1] * r->i_inc; - } - i_ptr += 2; - } - r->acc[0] = acc0; - r->acc[1] = acc1; - - if (o_count != r->o_samples) { - printf("handled %d out samples (expected %d)\n", o_count, - r->o_samples); - } + signed short *i_ptr, *o_ptr; + int o_count = 0; + double b; + int i; + double acc0, acc1; + + i_ptr = (signed short *) r->i_buf; + o_ptr = (signed short *) r->o_buf; + + acc0 = r->acc[0]; + acc1 = r->acc[1]; + b = r->i_start; + for (i = 0; i < r->i_samples; i++) { + b += r->i_inc; + /*printf("in %d\n",i_ptr[0]); */ + if (b >= 2) { + printf ("not expecting b>=2\n"); + } + if (b >= 1) { + acc0 += (1.0 - (b - r->i_inc)) * i_ptr[0]; + acc1 += (1.0 - (b - r->i_inc)) * i_ptr[1]; + + o_ptr[0] = rint (acc0); + /*printf("out %d\n",o_ptr[0]); */ + o_ptr[1] = rint (acc1); + o_ptr += 2; + o_count++; + + b -= 1.0; + + acc0 = b * i_ptr[0]; + acc1 = b * i_ptr[1]; + } else { + acc0 += i_ptr[0] * r->i_inc; + acc1 += i_ptr[1] * r->i_inc; + } + i_ptr += 2; + } + r->acc[0] = acc0; + r->acc[1] = acc1; + + if (o_count != r->o_samples) { + printf ("handled %d out samples (expected %d)\n", o_count, r->o_samples); + } } -void gst_resample_sinc_slow_s16(gst_resample_t * r) +void +gst_resample_sinc_slow_s16 (gst_resample_t * r) { - signed short *i_ptr, *o_ptr; - int i, j; - double c0, c1; - double a; - int start; - double center; - double weight; - - if (!r->buffer) { - int size = r->filter_length * 2 * r->channels; - - printf("gst_resample temp buffer\n"); - r->buffer = malloc(size); - memset(r->buffer, 0, size); - } - - i_ptr = (signed short *) r->i_buf; - o_ptr = (signed short *) r->o_buf; - - a = r->i_start; + signed short *i_ptr, *o_ptr; + int i, j; + double c0, c1; + double a; + int start; + double center; + double weight; + + if (!r->buffer) { + int size = r->filter_length * 2 * r->channels; + + printf ("gst_resample temp buffer\n"); + r->buffer = malloc (size); + memset (r->buffer, 0, size); + } + + i_ptr = (signed short *) r->i_buf; + o_ptr = (signed short *) r->o_buf; + + a = r->i_start; #define GETBUF(index,chan) (((index)<0) \ ? ((short *)(r->buffer))[((index)+r->filter_length)*2+(chan)] \ : i_ptr[(index)*2+(chan)]) - { - double sinx, cosx, sind, cosd; - double x, d; - double t; - - for (i = 0; i < r->o_samples; i++) { - start = floor(a) - r->filter_length; - center = a - r->halftaps; - x = M_PI * (start - center) * r->o_inc; - sinx = sin(M_PI * (start - center) * r->o_inc); - cosx = cos(M_PI * (start - center) * r->o_inc); - d = M_PI * r->o_inc; - sind = sin(M_PI * r->o_inc); - cosd = cos(M_PI * r->o_inc); - c0 = 0; - c1 = 0; - for (j = 0; j < r->filter_length; j++) { - weight = (x==0)?1:(sinx/x); + { + double sinx, cosx, sind, cosd; + double x, d; + double t; + + for (i = 0; i < r->o_samples; i++) { + start = floor (a) - r->filter_length; + center = a - r->halftaps; + x = M_PI * (start - center) * r->o_inc; + sinx = sin (M_PI * (start - center) * r->o_inc); + cosx = cos (M_PI * (start - center) * r->o_inc); + d = M_PI * r->o_inc; + sind = sin (M_PI * r->o_inc); + cosd = cos (M_PI * r->o_inc); + c0 = 0; + c1 = 0; + for (j = 0; j < r->filter_length; j++) { + weight = (x == 0) ? 1 : (sinx / x); /*printf("j %d sin %g cos %g\n",j,sinx,cosx); */ /*printf("j %d sin %g x %g sinc %g\n",j,sinx,x,weight); */ - c0 += weight * GETBUF((start + j), 0); - c1 += weight * GETBUF((start + j), 1); - t = cosx * cosd - sinx * sind; - sinx = cosx * sind + sinx * cosd; - cosx = t; - x += d; - } - o_ptr[0] = rint(c0); - o_ptr[1] = rint(c1); - o_ptr += 2; - a += r->o_inc; - } - } + c0 += weight * GETBUF ((start + j), 0); + c1 += weight * GETBUF ((start + j), 1); + t = cosx * cosd - sinx * sind; + sinx = cosx * sind + sinx * cosd; + cosx = t; + x += d; + } + o_ptr[0] = rint (c0); + o_ptr[1] = rint (c1); + o_ptr += 2; + a += r->o_inc; + } + } #undef GETBUF - memcpy(r->buffer, - i_ptr + (r->i_samples - r->filter_length) * r->channels, - r->filter_length * 2 * r->channels); + memcpy (r->buffer, + i_ptr + (r->i_samples - r->filter_length) * r->channels, + r->filter_length * 2 * r->channels); } /* only works for channels == 2 ???? */ -void gst_resample_sinc_s16(gst_resample_t * r) +void +gst_resample_sinc_s16 (gst_resample_t * r) { - double *ptr; - signed short *o_ptr; - int i, j; - double c0, c1; - double a; - int start; - double center; - double weight; - double x0, x, d; - double scale; - - ptr = (double *) r->buffer; - o_ptr = (signed short *) r->o_buf; - - /* scale provides a cutoff frequency for the low - * pass filter aspects of sinc(). scale=M_PI - * will cut off at the input frequency, which is - * good for up-sampling, but will cause aliasing - * for downsampling. Downsampling needs to be - * cut off at o_rate, thus scale=M_PI*r->i_inc. */ - /* actually, it needs to be M_PI*r->i_inc*r->i_inc. - * Need to research why. */ - scale = M_PI*r->i_inc; - for (i = 0; i < r->o_samples; i++) { - a = r->o_start + i * r->o_inc; - start = floor(a - r->halftaps); + double *ptr; + signed short *o_ptr; + int i, j; + double c0, c1; + double a; + int start; + double center; + double weight; + double x0, x, d; + double scale; + + ptr = (double *) r->buffer; + o_ptr = (signed short *) r->o_buf; + + /* scale provides a cutoff frequency for the low + * pass filter aspects of sinc(). scale=M_PI + * will cut off at the input frequency, which is + * good for up-sampling, but will cause aliasing + * for downsampling. Downsampling needs to be + * cut off at o_rate, thus scale=M_PI*r->i_inc. */ + /* actually, it needs to be M_PI*r->i_inc*r->i_inc. + * Need to research why. */ + scale = M_PI * r->i_inc; + for (i = 0; i < r->o_samples; i++) { + a = r->o_start + i * r->o_inc; + start = floor (a - r->halftaps); /*printf("%d: a=%g start=%d end=%d\n",i,a,start,start+r->filter_length-1); */ - center = a; - /*x = M_PI * (start - center) * r->o_inc; */ - /*d = M_PI * r->o_inc; */ - /*x = (start - center) * r->o_inc; */ - x0 = (start - center) * r->o_inc; - d = r->o_inc; - c0 = 0; - c1 = 0; - for (j = 0; j < r->filter_length; j++) { - x = x0 + d * j; - weight = sinc(x*scale*r->i_inc)*scale/M_PI; - weight *= window_func(x/r->halftaps*r->i_inc); - c0 += weight * ptr[(start + j + r->filter_length)*2 + 0]; - c1 += weight * ptr[(start + j + r->filter_length)*2 + 1]; - } - o_ptr[0] = double_to_s16(c0); - o_ptr[1] = double_to_s16(c1); - o_ptr += 2; - } + center = a; + /*x = M_PI * (start - center) * r->o_inc; */ + /*d = M_PI * r->o_inc; */ + /*x = (start - center) * r->o_inc; */ + x0 = (start - center) * r->o_inc; + d = r->o_inc; + c0 = 0; + c1 = 0; + for (j = 0; j < r->filter_length; j++) { + x = x0 + d * j; + weight = sinc (x * scale * r->i_inc) * scale / M_PI; + weight *= window_func (x / r->halftaps * r->i_inc); + c0 += weight * ptr[(start + j + r->filter_length) * 2 + 0]; + c1 += weight * ptr[(start + j + r->filter_length) * 2 + 1]; + } + o_ptr[0] = double_to_s16 (c0); + o_ptr[1] = double_to_s16 (c1); + o_ptr += 2; + } } /* @@ -468,98 +474,100 @@ static functable_t *ft; double out_tmp[10000]; -void gst_resample_sinc_ft_s16(gst_resample_t * r) +void +gst_resample_sinc_ft_s16 (gst_resample_t * r) { - double *ptr; - signed short *o_ptr; - int i; - /*int j; */ - double c0, c1; - /*double a; */ - double start_f, start_x; - int start; - double center; - /*double weight; */ - double x, d; - double scale; - int n = 4; - - scale = r->i_inc; /* cutoff at 22050 */ - /*scale = 1.0; // cutoff at 24000 */ - /*scale = r->i_inc * 0.5; // cutoff at 11025 */ - - if(!ft){ - ft = malloc(sizeof(*ft)); - memset(ft,0,sizeof(*ft)); - - ft->len = (r->filter_length + 2) * n; - ft->offset = 1.0 / n; - ft->start = - ft->len * 0.5 * ft->offset; - - ft->func_x = functable_sinc; - ft->func_dx = functable_dsinc; - ft->scale = M_PI * scale; - - ft->func2_x = functable_window_std; - ft->func2_dx = functable_window_dstd; - ft->scale2 = 1.0 / r->halftaps; - - functable_init(ft); - - /*printf("len=%d offset=%g start=%g\n",ft->len,ft->offset,ft->start); */ - } - - ptr = r->buffer; - o_ptr = (signed short *) r->o_buf; - - center = r->o_start; - start_x = center - r->halftaps; - start_f = floor(start_x); - start_x -= start_f; - start = start_f; - for (i = 0; i < r->o_samples; i++) { - /*start_f = floor(center - r->halftaps); */ + double *ptr; + signed short *o_ptr; + int i; + + /*int j; */ + double c0, c1; + + /*double a; */ + double start_f, start_x; + int start; + double center; + + /*double weight; */ + double x, d; + double scale; + int n = 4; + + scale = r->i_inc; /* cutoff at 22050 */ + /*scale = 1.0; // cutoff at 24000 */ + /*scale = r->i_inc * 0.5; // cutoff at 11025 */ + + if (!ft) { + ft = malloc (sizeof (*ft)); + memset (ft, 0, sizeof (*ft)); + + ft->len = (r->filter_length + 2) * n; + ft->offset = 1.0 / n; + ft->start = -ft->len * 0.5 * ft->offset; + + ft->func_x = functable_sinc; + ft->func_dx = functable_dsinc; + ft->scale = M_PI * scale; + + ft->func2_x = functable_window_std; + ft->func2_dx = functable_window_dstd; + ft->scale2 = 1.0 / r->halftaps; + + functable_init (ft); + + /*printf("len=%d offset=%g start=%g\n",ft->len,ft->offset,ft->start); */ + } + + ptr = r->buffer; + o_ptr = (signed short *) r->o_buf; + + center = r->o_start; + start_x = center - r->halftaps; + start_f = floor (start_x); + start_x -= start_f; + start = start_f; + for (i = 0; i < r->o_samples; i++) { + /*start_f = floor(center - r->halftaps); */ /*printf("%d: a=%g start=%d end=%d\n",i,a,start,start+r->filter_length-1); */ - x = start_f - center; - d = 1; - c0 = 0; - c1 = 0; + x = start_f - center; + d = 1; + c0 = 0; + c1 = 0; /*#define slow */ #ifdef slow - for (j = 0; j < r->filter_length; j++) { - weight = functable_eval(ft,x)*scale; - /*weight = sinc(M_PI * scale * x)*scale*r->i_inc; */ - /*weight *= window_func(x / r->halftaps); */ - c0 += weight * ptr[(start + j + r->filter_length)*2 + 0]; - c1 += weight * ptr[(start + j + r->filter_length)*2 + 1]; - x += d; - } + for (j = 0; j < r->filter_length; j++) { + weight = functable_eval (ft, x) * scale; + /*weight = sinc(M_PI * scale * x)*scale*r->i_inc; */ + /*weight *= window_func(x / r->halftaps); */ + c0 += weight * ptr[(start + j + r->filter_length) * 2 + 0]; + c1 += weight * ptr[(start + j + r->filter_length) * 2 + 1]; + x += d; + } #else - functable_fir2(ft, - &c0,&c1, - x, n, - ptr+(start + r->filter_length)*2, - r->filter_length); - c0 *= scale; - c1 *= scale; + functable_fir2 (ft, + &c0, &c1, x, n, ptr + (start + r->filter_length) * 2, r->filter_length); + c0 *= scale; + c1 *= scale; #endif - out_tmp[2 * i + 0] = c0; - out_tmp[2 * i + 1] = c1; - center += r->o_inc; - start_x += r->o_inc; - while(start_x>=1.0){ - start_f++; - start_x -= 1.0; - start++; - } - } - - if(r->channels==2){ - conv_short_double(r->o_buf,out_tmp,2 * r->o_samples); - }else{ - conv_short_double_sstr(r->o_buf,out_tmp,r->o_samples,2 * sizeof(double)); - } + out_tmp[2 * i + 0] = c0; + out_tmp[2 * i + 1] = c1; + center += r->o_inc; + start_x += r->o_inc; + while (start_x >= 1.0) { + start_f++; + start_x -= 1.0; + start++; + } + } + + if (r->channels == 2) { + conv_short_double (r->o_buf, out_tmp, 2 * r->o_samples); + } else { + conv_short_double_sstr (r->o_buf, out_tmp, r->o_samples, + 2 * sizeof (double)); + } } /******** @@ -567,18 +575,19 @@ void gst_resample_sinc_ft_s16(gst_resample_t * r) ********/ -void gst_resample_nearest_float(gst_resample_t * r) +void +gst_resample_nearest_float (gst_resample_t * r) { - float *i_ptr, *o_ptr; - int i_count = 0; - double a; - int i; + float *i_ptr, *o_ptr; + int i_count = 0; + double a; + int i; - i_ptr = (float *) r->i_buf; - o_ptr = (float *) r->o_buf; + i_ptr = (float *) r->i_buf; + o_ptr = (float *) r->o_buf; - a = r->o_start; - i_count = 0; + a = r->o_start; + i_count = 0; #define SCALE_LOOP(COPY,INC) \ for (i = 0; i < r->o_samples; i++) { \ COPY; \ @@ -591,302 +600,296 @@ void gst_resample_nearest_float(gst_resample_t * r) o_ptr+=INC; \ } - switch (r->channels) { - case 1: - SCALE_LOOP(o_ptr[0] = i_ptr[0], 1); - break; - case 2: - SCALE_LOOP(o_ptr[0] = i_ptr[0]; - o_ptr[1] = i_ptr[1], 2); - break; - default: - { - int n, n_chan = r->channels; - - SCALE_LOOP(for (n = 0; n < n_chan; n++) o_ptr[n] = - i_ptr[n], n_chan); - } - } - if (i_count != r->i_samples) { - printf("handled %d in samples (expected %d)\n", i_count, - r->i_samples); - } + switch (r->channels) { + case 1: + SCALE_LOOP (o_ptr[0] = i_ptr[0], 1); + break; + case 2: + SCALE_LOOP (o_ptr[0] = i_ptr[0]; o_ptr[1] = i_ptr[1], 2); + break; + default: + { + int n, n_chan = r->channels; + + SCALE_LOOP (for (n = 0; n < n_chan; n++) o_ptr[n] = i_ptr[n], n_chan); + } + } + if (i_count != r->i_samples) { + printf ("handled %d in samples (expected %d)\n", i_count, r->i_samples); + } } -void gst_resample_bilinear_float(gst_resample_t * r) +void +gst_resample_bilinear_float (gst_resample_t * r) { - float *i_ptr, *o_ptr; - int o_count = 0; - double b; - int i; - double acc0, acc1; - - i_ptr = (float *) r->i_buf; - o_ptr = (float *) r->o_buf; - - acc0 = r->acc[0]; - acc1 = r->acc[1]; - b = r->i_start; - for (i = 0; i < r->i_samples; i++) { - b += r->i_inc; - /*printf("in %d\n",i_ptr[0]); */ - if(b>=2){ - printf("not expecting b>=2\n"); - } - if (b >= 1) { - acc0 += (1.0 - (b-r->i_inc)) * i_ptr[0]; - acc1 += (1.0 - (b-r->i_inc)) * i_ptr[1]; - - o_ptr[0] = acc0; - /*printf("out %d\n",o_ptr[0]); */ - o_ptr[1] = acc1; - o_ptr += 2; - o_count++; - - b -= 1.0; - - acc0 = b * i_ptr[0]; - acc1 = b * i_ptr[1]; - } else { - acc0 += i_ptr[0] * r->i_inc; - acc1 += i_ptr[1] * r->i_inc; - } - i_ptr += 2; - } - r->acc[0] = acc0; - r->acc[1] = acc1; - - if (o_count != r->o_samples) { - printf("handled %d out samples (expected %d)\n", o_count, - r->o_samples); - } + float *i_ptr, *o_ptr; + int o_count = 0; + double b; + int i; + double acc0, acc1; + + i_ptr = (float *) r->i_buf; + o_ptr = (float *) r->o_buf; + + acc0 = r->acc[0]; + acc1 = r->acc[1]; + b = r->i_start; + for (i = 0; i < r->i_samples; i++) { + b += r->i_inc; + /*printf("in %d\n",i_ptr[0]); */ + if (b >= 2) { + printf ("not expecting b>=2\n"); + } + if (b >= 1) { + acc0 += (1.0 - (b - r->i_inc)) * i_ptr[0]; + acc1 += (1.0 - (b - r->i_inc)) * i_ptr[1]; + + o_ptr[0] = acc0; + /*printf("out %d\n",o_ptr[0]); */ + o_ptr[1] = acc1; + o_ptr += 2; + o_count++; + + b -= 1.0; + + acc0 = b * i_ptr[0]; + acc1 = b * i_ptr[1]; + } else { + acc0 += i_ptr[0] * r->i_inc; + acc1 += i_ptr[1] * r->i_inc; + } + i_ptr += 2; + } + r->acc[0] = acc0; + r->acc[1] = acc1; + + if (o_count != r->o_samples) { + printf ("handled %d out samples (expected %d)\n", o_count, r->o_samples); + } } -void gst_resample_sinc_slow_float(gst_resample_t * r) +void +gst_resample_sinc_slow_float (gst_resample_t * r) { - float *i_ptr, *o_ptr; - int i, j; - double c0, c1; - double a; - int start; - double center; - double weight; - - if (!r->buffer) { - int size = r->filter_length * sizeof(float) * r->channels; - - printf("gst_resample temp buffer\n"); - r->buffer = malloc(size); - memset(r->buffer, 0, size); - } - - i_ptr = (float *) r->i_buf; - o_ptr = (float *) r->o_buf; - - a = r->i_start; + float *i_ptr, *o_ptr; + int i, j; + double c0, c1; + double a; + int start; + double center; + double weight; + + if (!r->buffer) { + int size = r->filter_length * sizeof (float) * r->channels; + + printf ("gst_resample temp buffer\n"); + r->buffer = malloc (size); + memset (r->buffer, 0, size); + } + + i_ptr = (float *) r->i_buf; + o_ptr = (float *) r->o_buf; + + a = r->i_start; #define GETBUF(index,chan) (((index)<0) \ ? ((float *)(r->buffer))[((index)+r->filter_length)*2+(chan)] \ : i_ptr[(index)*2+(chan)]) - { - double sinx, cosx, sind, cosd; - double x, d; - double t; - - for (i = 0; i < r->o_samples; i++) { - start = floor(a) - r->filter_length; - center = a - r->halftaps; - x = M_PI * (start - center) * r->o_inc; - sinx = sin(M_PI * (start - center) * r->o_inc); - cosx = cos(M_PI * (start - center) * r->o_inc); - d = M_PI * r->o_inc; - sind = sin(M_PI * r->o_inc); - cosd = cos(M_PI * r->o_inc); - c0 = 0; - c1 = 0; - for (j = 0; j < r->filter_length; j++) { - weight = (x==0)?1:(sinx/x); + { + double sinx, cosx, sind, cosd; + double x, d; + double t; + + for (i = 0; i < r->o_samples; i++) { + start = floor (a) - r->filter_length; + center = a - r->halftaps; + x = M_PI * (start - center) * r->o_inc; + sinx = sin (M_PI * (start - center) * r->o_inc); + cosx = cos (M_PI * (start - center) * r->o_inc); + d = M_PI * r->o_inc; + sind = sin (M_PI * r->o_inc); + cosd = cos (M_PI * r->o_inc); + c0 = 0; + c1 = 0; + for (j = 0; j < r->filter_length; j++) { + weight = (x == 0) ? 1 : (sinx / x); /*printf("j %d sin %g cos %g\n",j,sinx,cosx); */ /*printf("j %d sin %g x %g sinc %g\n",j,sinx,x,weight); */ - c0 += weight * GETBUF((start + j), 0); - c1 += weight * GETBUF((start + j), 1); - t = cosx * cosd - sinx * sind; - sinx = cosx * sind + sinx * cosd; - cosx = t; - x += d; - } - o_ptr[0] = c0; - o_ptr[1] = c1; - o_ptr += 2; - a += r->o_inc; - } - } + c0 += weight * GETBUF ((start + j), 0); + c1 += weight * GETBUF ((start + j), 1); + t = cosx * cosd - sinx * sind; + sinx = cosx * sind + sinx * cosd; + cosx = t; + x += d; + } + o_ptr[0] = c0; + o_ptr[1] = c1; + o_ptr += 2; + a += r->o_inc; + } + } #undef GETBUF - memcpy(r->buffer, - i_ptr + (r->i_samples - r->filter_length) * r->channels, - r->filter_length * sizeof(float) * r->channels); + memcpy (r->buffer, + i_ptr + (r->i_samples - r->filter_length) * r->channels, + r->filter_length * sizeof (float) * r->channels); } /* only works for channels == 2 ???? */ -void gst_resample_sinc_float(gst_resample_t * r) +void +gst_resample_sinc_float (gst_resample_t * r) { - double *ptr; - float *o_ptr; - int i, j; - double c0, c1; - double a; - int start; - double center; - double weight; - double x0, x, d; - double scale; - - ptr = (double *) r->buffer; - o_ptr = (float *) r->o_buf; - - /* scale provides a cutoff frequency for the low - * pass filter aspects of sinc(). scale=M_PI - * will cut off at the input frequency, which is - * good for up-sampling, but will cause aliasing - * for downsampling. Downsampling needs to be - * cut off at o_rate, thus scale=M_PI*r->i_inc. */ - /* actually, it needs to be M_PI*r->i_inc*r->i_inc. - * Need to research why. */ - scale = M_PI*r->i_inc; - for (i = 0; i < r->o_samples; i++) { - a = r->o_start + i * r->o_inc; - start = floor(a - r->halftaps); + double *ptr; + float *o_ptr; + int i, j; + double c0, c1; + double a; + int start; + double center; + double weight; + double x0, x, d; + double scale; + + ptr = (double *) r->buffer; + o_ptr = (float *) r->o_buf; + + /* scale provides a cutoff frequency for the low + * pass filter aspects of sinc(). scale=M_PI + * will cut off at the input frequency, which is + * good for up-sampling, but will cause aliasing + * for downsampling. Downsampling needs to be + * cut off at o_rate, thus scale=M_PI*r->i_inc. */ + /* actually, it needs to be M_PI*r->i_inc*r->i_inc. + * Need to research why. */ + scale = M_PI * r->i_inc; + for (i = 0; i < r->o_samples; i++) { + a = r->o_start + i * r->o_inc; + start = floor (a - r->halftaps); /*printf("%d: a=%g start=%d end=%d\n",i,a,start,start+r->filter_length-1); */ - center = a; - /*x = M_PI * (start - center) * r->o_inc; */ - /*d = M_PI * r->o_inc; */ - /*x = (start - center) * r->o_inc; */ - x0 = (start - center) * r->o_inc; - d = r->o_inc; - c0 = 0; - c1 = 0; - for (j = 0; j < r->filter_length; j++) { - x = x0 + d * j; - weight = sinc(x*scale*r->i_inc)*scale/M_PI; - weight *= window_func(x/r->halftaps*r->i_inc); - c0 += weight * ptr[(start + j + r->filter_length)*2 + 0]; - c1 += weight * ptr[(start + j + r->filter_length)*2 + 1]; - } - o_ptr[0] = c0; - o_ptr[1] = c1; - o_ptr += 2; - } + center = a; + /*x = M_PI * (start - center) * r->o_inc; */ + /*d = M_PI * r->o_inc; */ + /*x = (start - center) * r->o_inc; */ + x0 = (start - center) * r->o_inc; + d = r->o_inc; + c0 = 0; + c1 = 0; + for (j = 0; j < r->filter_length; j++) { + x = x0 + d * j; + weight = sinc (x * scale * r->i_inc) * scale / M_PI; + weight *= window_func (x / r->halftaps * r->i_inc); + c0 += weight * ptr[(start + j + r->filter_length) * 2 + 0]; + c1 += weight * ptr[(start + j + r->filter_length) * 2 + 1]; + } + o_ptr[0] = c0; + o_ptr[1] = c1; + o_ptr += 2; + } } -void gst_resample_sinc_ft_float(gst_resample_t * r) +void +gst_resample_sinc_ft_float (gst_resample_t * r) { - double *ptr; - float *o_ptr; - int i; - /*int j; */ - double c0, c1; - /*double a; */ - double start_f, start_x; - int start; - double center; - /*double weight; */ - double x, d; - double scale; - int n = 4; - - scale = r->i_inc; /* cutoff at 22050 */ - /*scale = 1.0; // cutoff at 24000 */ - /*scale = r->i_inc * 0.5; // cutoff at 11025 */ - - if(!ft){ - ft = malloc(sizeof(*ft)); - memset(ft,0,sizeof(*ft)); - - ft->len = (r->filter_length + 2) * n; - ft->offset = 1.0 / n; - ft->start = - ft->len * 0.5 * ft->offset; - - ft->func_x = functable_sinc; - ft->func_dx = functable_dsinc; - ft->scale = M_PI * scale; - - ft->func2_x = functable_window_std; - ft->func2_dx = functable_window_dstd; - ft->scale2 = 1.0 / r->halftaps; - - functable_init(ft); - - /*printf("len=%d offset=%g start=%g\n",ft->len,ft->offset,ft->start); */ - } - - ptr = r->buffer; - o_ptr = (float *) r->o_buf; - - center = r->o_start; - start_x = center - r->halftaps; - start_f = floor(start_x); - start_x -= start_f; - start = start_f; - for (i = 0; i < r->o_samples; i++) { - /*start_f = floor(center - r->halftaps); */ + double *ptr; + float *o_ptr; + int i; + + /*int j; */ + double c0, c1; + + /*double a; */ + double start_f, start_x; + int start; + double center; + + /*double weight; */ + double x, d; + double scale; + int n = 4; + + scale = r->i_inc; /* cutoff at 22050 */ + /*scale = 1.0; // cutoff at 24000 */ + /*scale = r->i_inc * 0.5; // cutoff at 11025 */ + + if (!ft) { + ft = malloc (sizeof (*ft)); + memset (ft, 0, sizeof (*ft)); + + ft->len = (r->filter_length + 2) * n; + ft->offset = 1.0 / n; + ft->start = -ft->len * 0.5 * ft->offset; + + ft->func_x = functable_sinc; + ft->func_dx = functable_dsinc; + ft->scale = M_PI * scale; + + ft->func2_x = functable_window_std; + ft->func2_dx = functable_window_dstd; + ft->scale2 = 1.0 / r->halftaps; + + functable_init (ft); + + /*printf("len=%d offset=%g start=%g\n",ft->len,ft->offset,ft->start); */ + } + + ptr = r->buffer; + o_ptr = (float *) r->o_buf; + + center = r->o_start; + start_x = center - r->halftaps; + start_f = floor (start_x); + start_x -= start_f; + start = start_f; + for (i = 0; i < r->o_samples; i++) { + /*start_f = floor(center - r->halftaps); */ /*printf("%d: a=%g start=%d end=%d\n",i,a,start,start+r->filter_length-1); */ - x = start_f - center; - d = 1; - c0 = 0; - c1 = 0; + x = start_f - center; + d = 1; + c0 = 0; + c1 = 0; /*#define slow */ #ifdef slow - for (j = 0; j < r->filter_length; j++) { - weight = functable_eval(ft,x)*scale; - /*weight = sinc(M_PI * scale * x)*scale*r->i_inc; */ - /*weight *= window_func(x / r->halftaps); */ - c0 += weight * ptr[(start + j + r->filter_length)*2 + 0]; - c1 += weight * ptr[(start + j + r->filter_length)*2 + 1]; - x += d; - } + for (j = 0; j < r->filter_length; j++) { + weight = functable_eval (ft, x) * scale; + /*weight = sinc(M_PI * scale * x)*scale*r->i_inc; */ + /*weight *= window_func(x / r->halftaps); */ + c0 += weight * ptr[(start + j + r->filter_length) * 2 + 0]; + c1 += weight * ptr[(start + j + r->filter_length) * 2 + 1]; + x += d; + } #else - functable_fir2(ft, - &c0,&c1, - x, n, - ptr+(start + r->filter_length)*2, - r->filter_length); - c0 *= scale; - c1 *= scale; + functable_fir2 (ft, + &c0, &c1, x, n, ptr + (start + r->filter_length) * 2, r->filter_length); + c0 *= scale; + c1 *= scale; #endif - out_tmp[2 * i + 0] = c0; - out_tmp[2 * i + 1] = c1; - center += r->o_inc; - start_x += r->o_inc; - while(start_x>=1.0){ - start_f++; - start_x -= 1.0; - start++; - } - } - - if(r->channels==2){ - conv_float_double(r->o_buf,out_tmp,2 * r->o_samples); - }else{ - conv_float_double_sstr(r->o_buf,out_tmp,r->o_samples,2 * sizeof(double)); - } + out_tmp[2 * i + 0] = c0; + out_tmp[2 * i + 1] = c1; + center += r->o_inc; + start_x += r->o_inc; + while (start_x >= 1.0) { + start_f++; + start_x -= 1.0; + start++; + } + } + + if (r->channels == 2) { + conv_float_double (r->o_buf, out_tmp, 2 * r->o_samples); + } else { + conv_float_double_sstr (r->o_buf, out_tmp, r->o_samples, + 2 * sizeof (double)); + } } static gboolean -plugin_init (GstPlugin *plugin) +plugin_init (GstPlugin * plugin) { return TRUE; } -GST_PLUGIN_DEFINE ( - GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "gstresample", - "Resampling routines for use in audio plugins", - plugin_init, - VERSION, - GST_LICENSE, - GST_PACKAGE, - GST_ORIGIN -); - +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "gstresample", + "Resampling routines for use in audio plugins", + plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN); |