static unsafe void cubic_spline(stage_t p, fifo_t output_fifo) { int i, num_in = p.occupancy; int max_num_out = 1 + (int)(num_in * p.out_in_ratio); int output_offs = output_fifo.reserve(max_num_out); fixed(byte *pinput = &p.fifo.data[p.offset], poutput = &output_fifo.data[output_offs]) { double *input = (double *)pinput; double *output = (double *)poutput; for (i = 0; (p.at >> 32) < num_in; ++i, p.at += p.step) { double *s = input + (p.at >> 32); double x = (p.at & 0xffffffff) * (1 / MULT32); double b = 0.5 * (s[1] + s[-1]) - *s, a = (1 / 6.0) * (s[2] - s[1] + s[-1] - *s - 4 * b); double c = s[1] - *s - a - b; output[i] = ((a * x + b) * x + c) * x + *s; } } //assert(max_num_out - i >= 0); output_fifo.trim_by(max_num_out - i); p.fifo.read((int)(p.at >> 32), null); p.at &= 0xffffffff; }
static unsafe void double_sample(stage_t p, fifo_t output_fifo) { int num_in = Math.Max(0, p.fifo.occupancy); dft_filter_t f = p.shared.half_band[1]; int overlap = f.num_taps - 1; while (num_in > f.dft_length >> 1) { int input_offs = p.fifo.offset; p.fifo.read((f.dft_length - overlap) >> 1, null); num_in -= (f.dft_length - overlap) >> 1; int output_offs = output_fifo.reserve(f.dft_length); output_fifo.trim_by(overlap); fixed(byte *pinput = &p.fifo.data[input_offs]) fixed(byte *poutput = &output_fifo.data[output_offs]) fixed(double *lsx_fft_sc = p.shared.info.lsx_fft_sc) fixed(int *lsx_fft_br = p.shared.info.lsx_fft_br) { double *input = (double *)pinput; double *output = (double *)poutput; for (int j = 0, i = 0; i < f.dft_length; ++j, i += 2) { output[i] = input[j]; output[i + 1] = 0; } SOXFft.rdft(f.dft_length, 1, output, lsx_fft_br, lsx_fft_sc); output[0] *= f.coefs[0]; output[1] *= f.coefs[1]; for (int i = 2; i < f.dft_length; i += 2) { double tmp = output[i]; output[i] = f.coefs[i] * tmp - f.coefs[i + 1] * output[i + 1]; output[i + 1] = f.coefs[i + 1] * tmp + f.coefs[i] * output[i + 1]; } SOXFft.rdft(f.dft_length, -1, output, lsx_fft_br, lsx_fft_sc); } } }
static unsafe void half_sample(stage_t p, fifo_t output_fifo) { int num_in = Math.Max(0, p.fifo.occupancy); dft_filter_t f = p.shared.half_band[p.which]; int overlap = f.num_taps - 1; while (num_in >= f.dft_length) { int input_offs = p.fifo.offset; p.fifo.read(f.dft_length - overlap, null); num_in -= f.dft_length - overlap; int output_offs = output_fifo.reserve(f.dft_length); output_fifo.trim_by((f.dft_length + overlap) >> 1); Buffer.BlockCopy(p.fifo.data, input_offs, output_fifo.data, output_offs, f.dft_length * sizeof(double)); fixed(byte *poutput = &output_fifo.data[output_offs]) fixed(double *lsx_fft_sc = p.shared.info.lsx_fft_sc) fixed(int *lsx_fft_br = p.shared.info.lsx_fft_br) { double *output = (double *)poutput; SOXFft.rdft(f.dft_length, 1, output, lsx_fft_br, lsx_fft_sc); output[0] *= f.coefs[0]; output[1] *= f.coefs[1]; for (int i = 2; i < f.dft_length; i += 2) { double tmp = output[i]; output[i] = f.coefs[i] * tmp - f.coefs[i + 1] * output[i + 1]; output[i + 1] = f.coefs[i + 1] * tmp + f.coefs[i] * output[i + 1]; } SOXFft.rdft(f.dft_length, -1, output, lsx_fft_br, lsx_fft_sc); for (int j = 1, i = 2; i < f.dft_length - overlap; ++j, i += 2) { output[j] = output[i]; } } } }
static unsafe void cubic_spline(stage_t p, fifo_t output_fifo) { int i, num_in = p.occupancy; int max_num_out = 1 + (int)(num_in * p.out_in_ratio); int output_offs = output_fifo.reserve(max_num_out); fixed (byte* pinput = &p.fifo.data[p.offset], poutput = &output_fifo.data[output_offs]) { double* input = (double*)pinput; double* output = (double*)poutput; for (i = 0; (p.at >> 32) < num_in; ++i, p.at += p.step) { double* s = input + (p.at >> 32); double x = (p.at & 0xffffffff) * (1 / MULT32); double b = 0.5 * (s[1] + s[-1]) - *s, a = (1 / 6.0) * (s[2] - s[1] + s[-1] - *s - 4 * b); double c = s[1] - *s - a - b; output[i] = ((a * x + b) * x + c) * x + *s; } } //assert(max_num_out - i >= 0); output_fifo.trim_by(max_num_out - i); p.fifo.read((int)(p.at >> 32), null); p.at &= 0xffffffff; }
static unsafe void double_sample(stage_t p, fifo_t output_fifo) { int num_in = Math.Max(0, p.fifo.occupancy); dft_filter_t f = p.shared.half_band[1]; int overlap = f.num_taps - 1; while (num_in > f.dft_length >> 1) { int input_offs = p.fifo.offset; p.fifo.read((f.dft_length - overlap) >> 1, null); num_in -= (f.dft_length - overlap) >> 1; int output_offs = output_fifo.reserve(f.dft_length); output_fifo.trim_by(overlap); fixed (byte* pinput = &p.fifo.data[input_offs]) fixed (byte* poutput = &output_fifo.data[output_offs]) fixed (double* lsx_fft_sc = p.shared.info.lsx_fft_sc) fixed (int* lsx_fft_br = p.shared.info.lsx_fft_br) { double* input = (double*)pinput; double* output = (double*)poutput; for (int j = 0, i = 0; i < f.dft_length; ++j, i += 2) { output[i] = input[j]; output[i + 1] = 0; } SOXFft.rdft(f.dft_length, 1, output, lsx_fft_br, lsx_fft_sc); output[0] *= f.coefs[0]; output[1] *= f.coefs[1]; for (int i = 2; i < f.dft_length; i += 2) { double tmp = output[i]; output[i] = f.coefs[i] * tmp - f.coefs[i + 1] * output[i + 1]; output[i + 1] = f.coefs[i + 1] * tmp + f.coefs[i] * output[i + 1]; } SOXFft.rdft(f.dft_length, -1, output, lsx_fft_br, lsx_fft_sc); } } }
static unsafe void half_sample(stage_t p, fifo_t output_fifo) { int num_in = Math.Max(0, p.fifo.occupancy); dft_filter_t f = p.shared.half_band[p.which]; int overlap = f.num_taps - 1; while (num_in >= f.dft_length) { int input_offs = p.fifo.offset; p.fifo.read(f.dft_length - overlap, null); num_in -= f.dft_length - overlap; int output_offs = output_fifo.reserve(f.dft_length); output_fifo.trim_by((f.dft_length + overlap) >> 1); Buffer.BlockCopy(p.fifo.data, input_offs, output_fifo.data, output_offs, f.dft_length * sizeof(double)); fixed (byte* poutput = &output_fifo.data[output_offs]) fixed (double* lsx_fft_sc = p.shared.info.lsx_fft_sc) fixed (int* lsx_fft_br = p.shared.info.lsx_fft_br) { double* output = (double*)poutput; SOXFft.rdft(f.dft_length, 1, output, lsx_fft_br, lsx_fft_sc); output[0] *= f.coefs[0]; output[1] *= f.coefs[1]; for (int i = 2; i < f.dft_length; i += 2) { double tmp = output[i]; output[i] = f.coefs[i] * tmp - f.coefs[i + 1] * output[i + 1]; output[i + 1] = f.coefs[i + 1] * tmp + f.coefs[i] * output[i + 1]; } SOXFft.rdft(f.dft_length, -1, output, lsx_fft_br, lsx_fft_sc); for (int j = 1, i = 2; i < f.dft_length - overlap; ++j, i += 2) output[j] = output[i]; } } }