multichannel api in bw(pp)_src(_int)

This commit is contained in:
Stefano D'Angelo 2023-07-04 15:33:18 +02:00
parent af5dbc0a1c
commit b2cb3cad1e
4 changed files with 68 additions and 8 deletions

View File

@ -20,13 +20,18 @@
/*!
* module_type {{{ dsp }}}
* version {{{ 0.4.0 }}}
* version {{{ 0.5.0 }}}
* requires {{{ bw_common bw_config bw_math }}}
* description {{{
* Aribtrary-ratio IIR sample rate converter.
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.5.0</strong>:
* <ul>
* <li>Added <code>bw_src_process_multi()</code>.</li>
* </ul>
* </li>
* <li>Version <strong>0.4.0</strong>:
* <ul>
* <li>First release.</li>
@ -86,6 +91,20 @@ static inline void bw_src_process(const bw_src_coeffs *BW_RESTRICT coeffs, bw_sr
* After the call `n_in_samples` and `n_out_samples` will contain the actual
* number of consumed input samples and generated output samples,
* respectively.
*
* #### bw_src_process_multi()
* ```>>> */
static inline void bw_src_process_multi(const bw_src_coeffs *BW_RESTRICT coeffs, bw_src_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int **n_in_samples, int **n_out_samples);
/*! <<<```
* Processes at most the first `n_in_samples[i]` of each input buffer `x[i]`
* and fills the corresponding output buffer `y[i]` with at most
* `n_out_samples[i]` using `coeffs`, while using and updating each
* `state[i]`.
*
* After the call each element in `n_in_samples` and `n_out_samples` will
* contain the actual number of consumed input samples and generated output
* samples, respectively, for each of the `n_channels` input/output buffer
* couples.
* }}} */
/*** Implementation ***/
@ -221,6 +240,11 @@ static inline void bw_src_process(const bw_src_coeffs *BW_RESTRICT coeffs, bw_sr
*n_out_samples = j;
}
static inline void bw_src_process_multi(const bw_src_coeffs *BW_RESTRICT coeffs, bw_src_state **BW_RESTRICT state, const float **x, float **y, int n_channels, int **n_in_samples, int **n_out_samples) {
for (int i = 0; i < n_channels; i++)
bw_src_process(coeffs, state[i], x[i], y[i], n_in_samples[i], n_out_samples[i]);
}
#ifdef __cplusplus
}
#endif

View File

@ -20,7 +20,7 @@
/*!
* module_type {{{ dsp }}}
* version {{{ 0.4.0 }}}
* version {{{ 0.5.0 }}}
* requires {{{ bw_common bw_config bw_math }}}
* description {{{
* Integer-ratio IIR sample rate converter.
@ -33,6 +33,11 @@
* }}}
* changelog {{{
* <ul>
* <li>Version <strong>0.5.0</strong>:
* <ul>
* <li>Added <code>bw_src_int_process_multi()</code>.</li>
* </ul>
* </li>
* <li>Version <strong>0.4.0</strong>:
* <ul>
* <li>First release.</li>
@ -95,6 +100,22 @@ static inline int bw_src_int_process(const bw_src_int_coeffs *BW_RESTRICT coeffs
* divided by `-ratio` and then rounded towards positive infinity.
*
* Returns the number of generated output samples.
*
* #### bw_src_int_process_multi()
* ```>>> */
static inline void bw_src_int_process_multi(const bw_src_int_coeffs *BW_RESTRICT coeffs, bw_src_int_state **BW_RESTRICT state, const float **x, float **y, int *n, int n_channels, int n_in_samples);
/*! <<<```
* Processes the first `n_in_samples` of the `n_channels` input buffers `x`
* and fills the `n_channels` output buffers `y` using `coeffs`, while using
* and updating each of the `n_channels` `state`s.
*
* The number of generated output samples in each output buffer will be
* `ratio` times `n_in_samples` if `ratio` is positive, otherwise at most
* `n_in_samples` divided by `-ratio` and then rounded towards positive
* infinity.
*
* `n` is filled with the number of generated output samples for each output
* buffer, if not `NULL`.
* }}} */
/*** Implementation ***/
@ -192,6 +213,15 @@ static inline int bw_src_int_process(const bw_src_int_coeffs *BW_RESTRICT coeffs
return n;
}
static inline void bw_src_int_process_multi(const bw_src_int_coeffs *BW_RESTRICT coeffs, bw_src_int_state **BW_RESTRICT state, const float **x, float **y, int *n, int n_channels, int n_in_samples) {
if (n != NULL)
for (int i = 0; i < n_channels; i++)
n[i] = bw_src_int_process(coeffs, state[i], x[i], y[i], n_in_samples);
else
for (int i = 0; i < n_channels; i++)
bw_src_int_process(coeffs, state[i], x[i], y[i], n_in_samples);
}
#ifdef __cplusplus
}
#endif

View File

@ -40,11 +40,14 @@ namespace Brickworks {
private:
bw_src_coeffs coeffs;
bw_src_state states[N_CHANNELS];
bw_src_state *statesP[N_CHANNELS];
};
template<BW_SIZE_T N_CHANNELS>
inline SRC<N_CHANNELS>::SRC(float ratio) {
bw_src_init(&coeffs, ratio);
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
statesP[i] = states + i;
}
template<BW_SIZE_T N_CHANNELS>
@ -59,8 +62,7 @@ namespace Brickworks {
std::array<float *, N_CHANNELS> y,
std::array<int *, N_CHANNELS> nInSamples,
std::array<int *, N_CHANNELS> nOutSamples) {
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
bw_src_process(&coeffs, states + i, x.data()[i], y.data()[i], nInSamples.data()[i], nOutSamples.data()[i]);
bw_src_process_multi(coeffs, statesP, x.data(), y.data(), N_CHANNELS, nInSamples.data(), nOutSamples.data());
}
}

View File

@ -31,7 +31,7 @@ namespace Brickworks {
SRCInt(int ratio);
void reset(float x0 = 0.f);
void process(
std::array<int, N_CHANNELS> process(
std::array<const float *, N_CHANNELS> x,
std::array<float *, N_CHANNELS> y,
int nInSamples);
@ -39,11 +39,14 @@ namespace Brickworks {
private:
bw_src_int_coeffs coeffs;
bw_src_int_state states[N_CHANNELS];
bw_src_int_state *statesP[N_CHANNELS];
};
template<BW_SIZE_T N_CHANNELS>
inline SRCInt<N_CHANNELS>::SRCInt(int ratio) {
bw_src_int_init(&coeffs, ratio);
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
statesP[i] = states + i;
}
template<BW_SIZE_T N_CHANNELS>
@ -53,12 +56,13 @@ namespace Brickworks {
}
template<BW_SIZE_T N_CHANNELS>
inline void SRCInt<N_CHANNELS>::process(
inline std::array<int, N_CHANNELS> SRCInt<N_CHANNELS>::process(
std::array<const float *, N_CHANNELS> x,
std::array<float *, N_CHANNELS> y,
int nInSamples) {
for (BW_SIZE_T i = 0; i < N_CHANNELS; i++)
bw_src_int_process(&coeffs, states + i, x.data()[i], y.data()[i], nInSamples);
std::array<int, N_CHANNELS> ret;
bw_src_int_process_multi(&coeffs, statesP, x.data(), y.data(), ret.data(), N_CHANNELS, nInSamples);
return ret;
}
}