"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/libsyn123/resample.c" between
mpg123-1.26.4.tar.bz2 and mpg123-1.26.5.tar.bz2

About: mpg123 is a fast console MPEG Audio Player and decoder library (MPEG 1.0/2.0/2.5, Layer 1,2 and 3 support).

resample.c  (mpg123-1.26.4.tar.bz2):resample.c  (mpg123-1.26.5.tar.bz2)
/* /*
resample: low-latency usable and quick resampler resample: low-latency usable and quick resampler
copyright 2018-2019 by the mpg123 project copyright 2018-2020 by the mpg123 project
licensed under the terms of the LGPL 2.1 licensed under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis initially written by Thomas Orgis
The resampler consists of these steps: The resampler consists of these steps:
1. If output rate < 1/4 input rate: 1. If output rate < 1/4 input rate:
1.1 Repeat until output >= 1/4 input rate: 1.1 Repeat until output >= 1/4 input rate:
1.1.1 Low pass with transition band from 1/4 to 1/2 input bandwidth. 1.1.1 Low pass with transition band from 1/4 to 1/2 input bandwidth.
skipping to change at line 425 skipping to change at line 425
}; };
// TODO: switch the decimation filter to Direct Form II // TODO: switch the decimation filter to Direct Form II
struct lpf4_hist struct lpf4_hist
{ {
// Filter history (to be switched to Direct Form 2). // Filter history (to be switched to Direct Form 2).
float x[LPF_4_ORDER]; float x[LPF_4_ORDER];
float y[LPF_4_ORDER]; float y[LPF_4_ORDER];
}; };
#ifndef NO_DE_DENORM
// Battling denormals. They naturally occur in IIR filters and
// need to be avoided since they hurt performance on many CPUs.
// Usually, gcc -ffast-math would also avoid them, but we cannot
// count on that and debugging performance issues becomes confusing.
// The idea is to add an alternatingly positive/negative small number
// that is orders of magnitude above denormals to freshly computed
// samples.
// Downside: You never see a true zero if ther is true zero on input.
// Upside would be that you'd convert to 24 or 32 bit integer anyway,
// where you'd get your zero back (1 in 32 bit is around 5e-10.
static const float denorm_base = 1e-15;
#define DE_DENORM(val, base) (val) += (base);
#define DE_DENORM_FLIP(base) (base) = -(base);
#define DE_DENORM_INIT(base, sign) (base) = (sign)*denorm_base;
#else
#define DE_DENORM(val, base)
#define DE_DENORM_FLIP(base)
#define DE_DENORM_INIT(base, sign)
#endif
struct decimator_state struct decimator_state
{ {
unsigned int sflags; // also stores decimation position (0 or 1) unsigned int sflags; // also stores decimation position (0 or 1)
unsigned int n1; unsigned int n1;
struct lpf4_hist *ch; // one for each channel, pointer into common array struct lpf4_hist *ch; // one for each channel, pointer into common array
float *out_hist; // channels*STAGE_HISTORY, pointer to common block float *out_hist; // channels*STAGE_HISTORY, pointer to common block
#ifndef NO_DE_DENORM
float dede; // current de-denormalization offset
#endif
}; };
#ifdef SYN123_HIGH_PREC #ifdef SYN123_HIGH_PREC
typedef double lpf_sum_type; typedef double lpf_sum_type;
#else #else
typedef float lpf_sum_type; typedef float lpf_sum_type;
#endif #endif
// The amount of lowpass runs determines much of the quality. // The amount of lowpass runs determines much of the quality.
// Each run gives lpf_db reduction. The lowpass also includes the // Each run gives lpf_db reduction. The lowpass also includes the
skipping to change at line 527 skipping to change at line 551
struct lpf4_hist *decim_hist; struct lpf4_hist *decim_hist;
struct channel_history *ch; struct channel_history *ch;
// Blocks of STAGE_HISTORY*channels samples. // Blocks of STAGE_HISTORY*channels samples.
// 0: plain input for first decimation, oversampling or direct interpolat ion // 0: plain input for first decimation, oversampling or direct interpolat ion
// 1: output of first decimation // 1: output of first decimation
// 2: output of second decimation, etc. // 2: output of second decimation, etc.
float *stage_history; // storage for past input of final (2x) lowpass float *stage_history; // storage for past input of final (2x) lowpass
float *frame; // One PCM frame to work on (one sample for each channel). float *frame; // One PCM frame to work on (one sample for each channel).
float *prebuf; // [channels*BATCH] float *prebuf; // [channels*BATCH]
float *upbuf; // [channels*2*BATCH] float *upbuf; // [channels*2*BATCH]
#ifndef NO_DE_DENORM
float dede; // de-denormalization offset, alternatingly used both in pree
mp and lpf
#endif
// Final lowpass filter setup. // Final lowpass filter setup.
float lpf_cutoff; float lpf_cutoff;
float lpf_w_c; float lpf_w_c;
unsigned char lpf_bw; // Bandwidth in percent, rounded to integer. unsigned char lpf_bw; // Bandwidth in percent, rounded to integer.
// Pre-emphasis filter coefficients and history. // Pre-emphasis filter coefficients and history.
float pre_b0; float pre_b0;
unsigned char pre_n1; unsigned char pre_n1;
float pre_b[PREEMP_ORDER][PREEMP_ORDER]; float pre_b[PREEMP_ORDER][PREEMP_ORDER];
float pre_a[PREEMP_ORDER][PREEMP_ORDER]; float pre_a[PREEMP_ORDER][PREEMP_ORDER];
// Same for the low pass. // Same for the low pass.
skipping to change at line 809 skipping to change at line 836
if(!ins) if(!ins)
return 0; return 0;
mdebug("decimating %zu samples", ins); mdebug("decimating %zu samples", ins);
if(!(rd->sflags & lowpass_flow)) if(!(rd->sflags & lowpass_flow))
{ {
for(unsigned int c=0; c<rrd->channels; ++c) for(unsigned int c=0; c<rrd->channels; ++c)
for(unsigned int j=0; j<LPF_4_ORDER; ++j) for(unsigned int j=0; j<LPF_4_ORDER; ++j)
rd->ch[c].x[j] = rd->ch[c].y[j] = in[c]; rd->ch[c].x[j] = rd->ch[c].y[j] = in[c];
rd->n1 = 0; rd->n1 = 0;
rd->sflags |= lowpass_flow|decimate_store; rd->sflags |= lowpass_flow|decimate_store;
DE_DENORM_INIT(rd->dede, dstage % 2 ? -1 : +1)
stage_history_init(rrd, dstage+1, in); stage_history_init(rrd, dstage+1, in);
} }
float *out = in; // output worker float *out = in; // output worker
float *oout = in; // for history storage float *oout = in; // for history storage
size_t outs = 0; size_t outs = 0;
#ifndef SYN123_NO_CASES #ifndef SYN123_NO_CASES
switch(rrd->channels) switch(rrd->channels)
{ {
case 1: for(size_t i=0; i<ins; ++i) case 1: for(size_t i=0; i<ins; ++i)
{ {
skipping to change at line 833 skipping to change at line 861
// y0 = b0x0 + b1x1 + ... + bxyn - a1y1 - ... - anyn // y0 = b0x0 + b1x1 + ... + bxyn - a1y1 - ... - anyn
// Switching y to double pushes roundoff hf noise down (? ). // Switching y to double pushes roundoff hf noise down (? ).
lpf_sum_type ny = lpf_4_coeff[0][0] * in[i]; // a0 == 1 i mplicit here lpf_sum_type ny = lpf_4_coeff[0][0] * in[i]; // a0 == 1 i mplicit here
for(int j=0; j<LPF_4_ORDER; ++j) for(int j=0; j<LPF_4_ORDER; ++j)
{ {
// This direct summing without intermediate asum and bsum // This direct summing without intermediate asum and bsum
// pushs roundoff hf noise down. // pushs roundoff hf noise down.
ny += rd->ch[0].x[ni[j]]*lpf_4_coeff[0][j+1]; ny += rd->ch[0].x[ni[j]]*lpf_4_coeff[0][j+1];
ny -= rd->ch[0].y[ni[j]]*lpf_4_coeff[1][j+1]; ny -= rd->ch[0].y[ni[j]]*lpf_4_coeff[1][j+1];
} }
DE_DENORM(ny, rd->dede)
rd->ch[0].x[rd->n1] = in[i]; rd->ch[0].x[rd->n1] = in[i];
rd->ch[0].y[rd->n1] = ny; rd->ch[0].y[rd->n1] = ny;
// Drop every second sample. // Drop every second sample.
// Maybe its faster doing this in a separate step after a ll? // Maybe its faster doing this in a separate step after a ll?
if(rd->sflags & decimate_store) if(rd->sflags & decimate_store)
{ {
DE_DENORM_FLIP(rd->dede)
*(out++) = ny; *(out++) = ny;
rd->sflags &= ~decimate_store; rd->sflags &= ~decimate_store;
++outs; ++outs;
} else } else
rd->sflags |= decimate_store; rd->sflags |= decimate_store;
} }
break; break;
case 2: for(size_t i=0; i<ins; ++i) case 2: for(size_t i=0; i<ins; ++i)
{ {
int ni[LPF_4_ORDER]; int ni[LPF_4_ORDER];
skipping to change at line 865 skipping to change at line 895
// y0 = b0x0 + b1x1 + ... + bxyn - a1y1 - ... - a nyn // y0 = b0x0 + b1x1 + ... + bxyn - a1y1 - ... - a nyn
// Switching y to double pushes roundoff hf noise down (?). // Switching y to double pushes roundoff hf noise down (?).
lpf_sum_type ny = lpf_4_coeff[0][0] * in[c]; // a 0 == 1 implicit here lpf_sum_type ny = lpf_4_coeff[0][0] * in[c]; // a 0 == 1 implicit here
for(int j=0; j<LPF_4_ORDER; ++j) for(int j=0; j<LPF_4_ORDER; ++j)
{ {
// This direct summing without intermedia te asum and bsum // This direct summing without intermedia te asum and bsum
// pushs roundoff hf noise down. // pushs roundoff hf noise down.
ny += rd->ch[c].x[ni[j]]*lpf_4_coeff[0][j +1]; ny += rd->ch[c].x[ni[j]]*lpf_4_coeff[0][j +1];
ny -= rd->ch[c].y[ni[j]]*lpf_4_coeff[1][j +1]; ny -= rd->ch[c].y[ni[j]]*lpf_4_coeff[1][j +1];
} }
DE_DENORM(ny, rd->dede)
rd->ch[c].x[rd->n1] = in[c]; rd->ch[c].x[rd->n1] = in[c];
rd->ch[c].y[rd->n1] = ny; rd->ch[c].y[rd->n1] = ny;
frame[c] = ny; frame[c] = ny;
} }
in += 2; in += 2;
// Drop every second sample. // Drop every second sample.
// Maybe its faster doing this in a separate step after a ll? // Maybe its faster doing this in a separate step after a ll?
if(rd->sflags & decimate_store) if(rd->sflags & decimate_store)
{ {
DE_DENORM_FLIP(rd->dede)
*(out++) = frame[0]; *(out++) = frame[0];
*(out++) = frame[1]; *(out++) = frame[1];
rd->sflags &= ~decimate_store; rd->sflags &= ~decimate_store;
++outs; ++outs;
} else } else
rd->sflags |= decimate_store; rd->sflags |= decimate_store;
} }
break; break;
default: default:
#endif #endif
skipping to change at line 902 skipping to change at line 934
// y0 = b0x0 + b1x1 + ... + bxyn - a1y1 - ... - a nyn // y0 = b0x0 + b1x1 + ... + bxyn - a1y1 - ... - a nyn
// Switching y to double pushes roundoff hf noise down (?). // Switching y to double pushes roundoff hf noise down (?).
lpf_sum_type ny = lpf_4_coeff[0][0] * in[c]; // a 0 == 1 implicit here lpf_sum_type ny = lpf_4_coeff[0][0] * in[c]; // a 0 == 1 implicit here
for(int j=0; j<LPF_4_ORDER; ++j) for(int j=0; j<LPF_4_ORDER; ++j)
{ {
// This direct summing without intermedia te asum and bsum // This direct summing without intermedia te asum and bsum
// pushs roundoff hf noise down. // pushs roundoff hf noise down.
ny += rd->ch[c].x[ni[j]]*lpf_4_coeff[0][j +1]; ny += rd->ch[c].x[ni[j]]*lpf_4_coeff[0][j +1];
ny -= rd->ch[c].y[ni[j]]*lpf_4_coeff[1][j +1]; ny -= rd->ch[c].y[ni[j]]*lpf_4_coeff[1][j +1];
} }
DE_DENORM(ny, rd->dede)
rd->ch[c].x[rd->n1] = in[c]; rd->ch[c].x[rd->n1] = in[c];
rd->ch[c].y[rd->n1] = ny; rd->ch[c].y[rd->n1] = ny;
rrd->frame[c] = ny; rrd->frame[c] = ny;
} }
in += rrd->channels; in += rrd->channels;
// Drop every second sample. // Drop every second sample.
// Maybe its faster doing this in a separate step after a ll? // Maybe its faster doing this in a separate step after a ll?
if(rd->sflags & decimate_store) if(rd->sflags & decimate_store)
{ {
DE_DENORM_FLIP(rd->dede)
for(unsigned int c=0; c<rrd->channels; ++c) for(unsigned int c=0; c<rrd->channels; ++c)
*(out++) = rrd->frame[c]; *(out++) = rrd->frame[c];
rd->sflags &= ~decimate_store; rd->sflags &= ~decimate_store;
++outs; ++outs;
} else } else
rd->sflags |= decimate_store; rd->sflags |= decimate_store;
} }
#ifndef SYN123_NO_CASES #ifndef SYN123_NO_CASES
} }
#endif #endif
skipping to change at line 976 skipping to change at line 1010
for(unsigned int c=0; c<channels; ++c) \ for(unsigned int c=0; c<channels; ++c) \
{ \ { \
lpf_sum_type ny = 0; \ lpf_sum_type ny = 0; \
lpf_sum_type nw = 0; \ lpf_sum_type nw = 0; \
for(unsigned char i=0; i<PREEMP_ORDER; ++i) \ for(unsigned char i=0; i<PREEMP_ORDER; ++i) \
{ \ { \
ny += rd->ch[c].pre_w[i]*rd->pre_b[n1][i]; \ ny += rd->ch[c].pre_w[i]*rd->pre_b[n1][i]; \
nw -= rd->ch[c].pre_w[i]*rd->pre_a[n1][i]; \ nw -= rd->ch[c].pre_w[i]*rd->pre_a[n1][i]; \
} \ } \
nw += in[c]; \ nw += in[c]; \
DE_DENORM(nw, rd->dede) \
ny += rd->pre_b0 * nw; \ ny += rd->pre_b0 * nw; \
rd->ch[c].pre_w[rd->pre_n1] = nw; \ rd->ch[c].pre_w[rd->pre_n1] = nw; \
out[c] = ny; \ out[c] = ny; \
} \ } \
} }
// Beginning of a low pass function with on-the-fly initialization // Beginning of a low pass function with on-the-fly initialization
// of filter history. // of filter history.
// For oversampling lowpass with zero-stuffing, initialize to half of first // For oversampling lowpass with zero-stuffing, initialize to half of first
// input sample. // input sample.
skipping to change at line 1021 skipping to change at line 1056
float old_y = in[c]; \ float old_y = in[c]; \
for(int j=0; j<times; ++j) \ for(int j=0; j<times; ++j) \
{ \ { \
lpf_sum_type w = old_y; \ lpf_sum_type w = old_y; \
lpf_sum_type y = 0; \ lpf_sum_type y = 0; \
for(int k=0; k<LPF_ORDER; ++k) \ for(int k=0; k<LPF_ORDER; ++k) \
{ \ { \
y += rd->ch[c].lpf_w[j][k]*rd->lpf_b[n1][k]; \ y += rd->ch[c].lpf_w[j][k]*rd->lpf_b[n1][k]; \
w -= rd->ch[c].lpf_w[j][k]*rd->lpf_a[n1][k]; \ w -= rd->ch[c].lpf_w[j][k]*rd->lpf_a[n1][k]; \
} \ } \
DE_DENORM(w, rd->dede) \
rd->ch[c].lpf_w[j][n1n] = w; \ rd->ch[c].lpf_w[j][n1n] = w; \
y += rd->lpf_b0*w; \ y += rd->lpf_b0*w; \
old_y = y; \ old_y = y; \
} \ } \
out[c] = old_y; \ out[c] = old_y; \
} \ } \
n1 = n1n; n1 = n1n;
#define LPF_DF2_END \ #define LPF_DF2_END \
rd->lpf_n1 = n1; rd->lpf_n1 = n1;
skipping to change at line 1057 skipping to change at line 1093
case 1: for(size_t i=0; i<ins; ++i) \ case 1: for(size_t i=0; i<ins; ++i) \
{ \ { \
float sample; \ float sample; \
PREEMP_DF2_SAMPLE(in, (&sample), 1) \ PREEMP_DF2_SAMPLE(in, (&sample), 1) \
/* Zero-stuffing! Insert zero after making up for energy loss. */ \ /* Zero-stuffing! Insert zero after making up for energy loss. */ \
sample *= 2; \ sample *= 2; \
LPF_DF2_SAMPLE(times, (&sample), out, 1) \ LPF_DF2_SAMPLE(times, (&sample), out, 1) \
out++; \ out++; \
sample = 0; \ sample = 0; \
LPF_DF2_SAMPLE(times, (&sample), out, 1) \ LPF_DF2_SAMPLE(times, (&sample), out, 1) \
DE_DENORM_FLIP(rd->dede) \
out++; \ out++; \
in++; \ in++; \
} \ } \
break; \ break; \
case 2: for(size_t i=0; i<ins; ++i) \ case 2: for(size_t i=0; i<ins; ++i) \
{ \ { \
float frame[2]; \ float frame[2]; \
PREEMP_DF2_SAMPLE(in, frame, 2) \ PREEMP_DF2_SAMPLE(in, frame, 2) \
/* Zero-stuffing! Insert zero after making up for energy loss. */ \ /* Zero-stuffing! Insert zero after making up for energy loss. */ \
frame[0] *= 2; \ frame[0] *= 2; \
frame[1] *= 2; \ frame[1] *= 2; \
LPF_DF2_SAMPLE(times, frame, out, 2) \ LPF_DF2_SAMPLE(times, frame, out, 2) \
out += 2; \ out += 2; \
frame[1] = frame[0] = 0; \ frame[1] = frame[0] = 0; \
LPF_DF2_SAMPLE(times, frame, out, 2) \ LPF_DF2_SAMPLE(times, frame, out, 2) \
DE_DENORM_FLIP(rd->dede) \
out += 2; \ out += 2; \
in += 2; \ in += 2; \
} \ } \
break; \ break; \
default: for(size_t i=0; i<ins; ++i) \ default: for(size_t i=0; i<ins; ++i) \
{ \ { \
PREEMP_DF2_SAMPLE(in, rd->frame, rd->channels) \ PREEMP_DF2_SAMPLE(in, rd->frame, rd->channels) \
/* Zero-stuffing! Insert zero after making up for energy loss. */ \ /* Zero-stuffing! Insert zero after making up for energy loss. */ \
for(unsigned int c=0; c<rd->channels; ++c) \ for(unsigned int c=0; c<rd->channels; ++c) \
rd->frame[c] *= 2; \ rd->frame[c] *= 2; \
LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \ LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \
out += rd->channels; \ out += rd->channels; \
for(unsigned int c=0; c<rd->channels; ++c) \ for(unsigned int c=0; c<rd->channels; ++c) \
rd->frame[c] = 0; \ rd->frame[c] = 0; \
LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \ LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \
DE_DENORM_FLIP(rd->dede) \
out += rd->channels; \ out += rd->channels; \
in += rd->channels; \ in += rd->channels; \
} \ } \
} \ } \
LPF_DF2_END \ LPF_DF2_END \
} \ } \
\ \
static void lowpass##times##_df2_preemp(struct resample_data *rd, float *in, siz e_t ins) \ static void lowpass##times##_df2_preemp(struct resample_data *rd, float *in, siz e_t ins) \
{ \ { \
if(!ins) \ if(!ins) \
skipping to change at line 1108 skipping to change at line 1147
float *out = in; \ float *out = in; \
LPF_DF2_BEGIN(times, in, rd->channels,) \ LPF_DF2_BEGIN(times, in, rd->channels,) \
PREEMP_DF2_BEGIN(in, rd->channels,); \ PREEMP_DF2_BEGIN(in, rd->channels,); \
switch(rd->channels) \ switch(rd->channels) \
{ \ { \
case 1: for(size_t i=0; i<ins; ++i) \ case 1: for(size_t i=0; i<ins; ++i) \
{ \ { \
float sample; \ float sample; \
PREEMP_DF2_SAMPLE(in, (&sample), 1) \ PREEMP_DF2_SAMPLE(in, (&sample), 1) \
LPF_DF2_SAMPLE(times, (&sample), out, 1) \ LPF_DF2_SAMPLE(times, (&sample), out, 1) \
DE_DENORM_FLIP(rd->dede) \
in++; \ in++; \
out++; \ out++; \
} \ } \
break; \ break; \
case 2: for(size_t i=0; i<ins; ++i) \ case 2: for(size_t i=0; i<ins; ++i) \
{ \ { \
float frame[2]; \ float frame[2]; \
PREEMP_DF2_SAMPLE(in, frame, 2) \ PREEMP_DF2_SAMPLE(in, frame, 2) \
LPF_DF2_SAMPLE(times, frame, out, 2) \ LPF_DF2_SAMPLE(times, frame, out, 2) \
DE_DENORM_FLIP(rd->dede) \
in += 2; \ in += 2; \
out += 2; \ out += 2; \
} \ } \
break; \ break; \
default: for(size_t i=0; i<ins; ++i) \ default: for(size_t i=0; i<ins; ++i) \
{ \ { \
PREEMP_DF2_SAMPLE(in, rd->frame, rd->channels) \ PREEMP_DF2_SAMPLE(in, rd->frame, rd->channels) \
LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \ LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \
DE_DENORM_FLIP(rd->dede) \
in += rd->channels; \ in += rd->channels; \
out += rd->channels; \ out += rd->channels; \
} \ } \
} \ } \
LPF_DF2_END \ LPF_DF2_END \
} }
#else #else
#define LOWPASS_DF2_FUNCSX(times) \ #define LOWPASS_DF2_FUNCSX(times) \
\ \
static void lowpass##times##_df2_preemp_2x(struct resample_data *rd, float *in, size_t ins, float *out) \ static void lowpass##times##_df2_preemp_2x(struct resample_data *rd, float *in, size_t ins, float *out) \
skipping to change at line 1151 skipping to change at line 1193
{ \ { \
PREEMP_DF2_SAMPLE(in, rd->frame, rd->channels) \ PREEMP_DF2_SAMPLE(in, rd->frame, rd->channels) \
/* Zero-stuffing! Insert zero after making up for energy loss. */ \ /* Zero-stuffing! Insert zero after making up for energy loss. */ \
for(unsigned int c=0; c<rd->channels; ++c) \ for(unsigned int c=0; c<rd->channels; ++c) \
rd->frame[c] *= 2; \ rd->frame[c] *= 2; \
LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \ LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \
out += rd->channels; \ out += rd->channels; \
for(unsigned int c=0; c<rd->channels; ++c) \ for(unsigned int c=0; c<rd->channels; ++c) \
rd->frame[c] = 0; \ rd->frame[c] = 0; \
LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \ LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \
DE_DENORM_FLIP(rd->dede) \
out += rd->channels; \ out += rd->channels; \
in += rd->channels; \ in += rd->channels; \
} \ } \
LPF_DF2_END \ LPF_DF2_END \
} \ } \
\ \
static void lowpass##times##_df2_preemp(struct resample_data *rd, float *in, siz e_t ins) \ static void lowpass##times##_df2_preemp(struct resample_data *rd, float *in, siz e_t ins) \
{ \ { \
if(!ins) \ if(!ins) \
return; \ return; \
float *out = in; \ float *out = in; \
LPF_DF2_BEGIN(times, in, rd->channels,) \ LPF_DF2_BEGIN(times, in, rd->channels,) \
PREEMP_DF2_BEGIN(in, rd->channels,); \ PREEMP_DF2_BEGIN(in, rd->channels,); \
for(size_t i=0; i<ins; ++i) \ for(size_t i=0; i<ins; ++i) \
{ \ { \
PREEMP_DF2_SAMPLE(in, rd->frame, rd->channels) \ PREEMP_DF2_SAMPLE(in, rd->frame, rd->channels) \
LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \ LPF_DF2_SAMPLE(times, rd->frame, out, rd->channels) \
DE_DENORM_FLIP(rd->dede) \
in += rd->channels; \ in += rd->channels; \
out += rd->channels; \ out += rd->channels; \
} \ } \
LPF_DF2_END \ LPF_DF2_END \
} }
#endif #endif
// Need that indirection so that times is expanded properly for concatenation. // Need that indirection so that times is expanded properly for concatenation.
#define LOWPASS_DF2_FUNCS(times) \ #define LOWPASS_DF2_FUNCS(times) \
LOWPASS_DF2_FUNCSX(times) LOWPASS_DF2_FUNCSX(times)
skipping to change at line 2258 skipping to change at line 2302
memset(sh->rd, 0, sizeof(*(sh->rd))); memset(sh->rd, 0, sizeof(*(sh->rd)));
rd = sh->rd; rd = sh->rd;
rd->inrate = rd->vinrate = rd->voutrate = rd->outrate = -1; rd->inrate = rd->vinrate = rd->voutrate = rd->outrate = -1;
rd->resample_func = NULL; rd->resample_func = NULL;
rd->lowpass_func = dirty ? DIRTY_LOWPASS_PREEMP : LOWPASS_P REEMP; rd->lowpass_func = dirty ? DIRTY_LOWPASS_PREEMP : LOWPASS_P REEMP;
rd->lowpass_2x_func = dirty ? DIRTY_LOWPASS_PREEMP_2X : LOWPASS_P REEMP_2X; rd->lowpass_2x_func = dirty ? DIRTY_LOWPASS_PREEMP_2X : LOWPASS_P REEMP_2X;
rd->decim = NULL; rd->decim = NULL;
rd->decim_hist = NULL; rd->decim_hist = NULL;
rd->channels = channels; rd->channels = channels;
rd->stage_history = NULL; rd->stage_history = NULL;
DE_DENORM_INIT(rd->dede, +1)
rd->frame = NULL; rd->frame = NULL;
#ifndef SYN123_NO_CASES #ifndef SYN123_NO_CASES
if(channels > 2) if(channels > 2)
#endif #endif
{ {
rd->frame = malloc(sizeof(float)*channels); rd->frame = malloc(sizeof(float)*channels);
if(!rd->frame) if(!rd->frame)
{ {
free(rd); free(rd);
return SYN123_DOOM; return SYN123_DOOM;
 End of changes. 22 change blocks. 
1 lines changed or deleted 47 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)