mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Add support for configuring the Q parameter of biquad based filters.
This is in preparation for improving ma_lpf, ma_hpf and ma_bpf to make them proper Butterworth filters.
This commit is contained in:
+52
-12
@@ -1851,10 +1851,11 @@ typedef struct
|
||||
ma_uint32 channels;
|
||||
ma_uint32 sampleRate;
|
||||
double cutoffFrequency;
|
||||
double q;
|
||||
} ma_lpf1_config, ma_lpf2_config;
|
||||
|
||||
ma_lpf1_config ma_lpf1_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency);
|
||||
ma_lpf2_config ma_lpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency);
|
||||
ma_lpf2_config ma_lpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -1918,10 +1919,11 @@ typedef struct
|
||||
ma_uint32 channels;
|
||||
ma_uint32 sampleRate;
|
||||
double cutoffFrequency;
|
||||
double q;
|
||||
} ma_hpf1_config, ma_hpf2_config;
|
||||
|
||||
ma_hpf1_config ma_hpf1_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency);
|
||||
ma_hpf2_config ma_hpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency);
|
||||
ma_hpf2_config ma_hpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -1985,9 +1987,10 @@ typedef struct
|
||||
ma_uint32 channels;
|
||||
ma_uint32 sampleRate;
|
||||
double cutoffFrequency;
|
||||
double q;
|
||||
} ma_bpf2_config;
|
||||
|
||||
ma_bpf2_config ma_bpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency);
|
||||
ma_bpf2_config ma_bpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -29925,11 +29928,12 @@ ma_lpf1_config ma_lpf1_config_init(ma_format format, ma_uint32 channels, ma_uint
|
||||
config.channels = channels;
|
||||
config.sampleRate = sampleRate;
|
||||
config.cutoffFrequency = cutoffFrequency;
|
||||
config.q = 0.5;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
ma_lpf2_config ma_lpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency)
|
||||
ma_lpf2_config ma_lpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q)
|
||||
{
|
||||
ma_lpf1_config config;
|
||||
|
||||
@@ -29938,6 +29942,12 @@ ma_lpf2_config ma_lpf2_config_init(ma_format format, ma_uint32 channels, ma_uint
|
||||
config.channels = channels;
|
||||
config.sampleRate = sampleRate;
|
||||
config.cutoffFrequency = cutoffFrequency;
|
||||
config.q = q;
|
||||
|
||||
/* Q cannot be 0 or else it'll result in a division by 0. In this case just default to 0.707107. */
|
||||
if (config.q == 0) {
|
||||
config.q = 0.707107;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
@@ -30087,7 +30097,7 @@ static MA_INLINE ma_biquad_config ma_lpf2__get_biquad_config(const ma_lpf2_confi
|
||||
|
||||
MA_ASSERT(pConfig != NULL);
|
||||
|
||||
q = 0.707107;
|
||||
q = pConfig->q;
|
||||
w = 2 * MA_PI_D * pConfig->cutoffFrequency / pConfig->sampleRate;
|
||||
s = ma_sin(w);
|
||||
c = ma_cos(w);
|
||||
@@ -30250,7 +30260,13 @@ static ma_result ma_lpf_reinit__internal(const ma_lpf_config* pConfig, ma_lpf* p
|
||||
}
|
||||
|
||||
for (ilpf2 = 0; ilpf2 < lpf2Count; ilpf2 += 1) {
|
||||
ma_lpf2_config lpf2Config = ma_lpf2_config_init(pConfig->format, pConfig->channels, pConfig->sampleRate, pConfig->cutoffFrequency);
|
||||
ma_lpf2_config lpf2Config;
|
||||
double q;
|
||||
|
||||
/* TODO: Calculate Q. */
|
||||
q = 0;
|
||||
|
||||
lpf2Config = ma_lpf2_config_init(pConfig->format, pConfig->channels, pConfig->sampleRate, pConfig->cutoffFrequency, q);
|
||||
|
||||
if (isNew) {
|
||||
result = ma_lpf2_init(&lpf2Config, &pLPF->lpf2[ilpf2]);
|
||||
@@ -30413,7 +30429,7 @@ ma_hpf1_config ma_hpf1_config_init(ma_format format, ma_uint32 channels, ma_uint
|
||||
return config;
|
||||
}
|
||||
|
||||
ma_hpf2_config ma_hpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency)
|
||||
ma_hpf2_config ma_hpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q)
|
||||
{
|
||||
ma_hpf2_config config;
|
||||
|
||||
@@ -30422,6 +30438,12 @@ ma_hpf2_config ma_hpf2_config_init(ma_format format, ma_uint32 channels, ma_uint
|
||||
config.channels = channels;
|
||||
config.sampleRate = sampleRate;
|
||||
config.cutoffFrequency = cutoffFrequency;
|
||||
config.q = q;
|
||||
|
||||
/* Q cannot be 0 or else it'll result in a division by 0. In this case just default to 0.707107. */
|
||||
if (config.q == 0) {
|
||||
config.q = 0.707107;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
@@ -30571,7 +30593,7 @@ static MA_INLINE ma_biquad_config ma_hpf2__get_biquad_config(const ma_hpf2_confi
|
||||
|
||||
MA_ASSERT(pConfig != NULL);
|
||||
|
||||
q = 0.707107;
|
||||
q = pConfig->q;
|
||||
w = 2 * MA_PI_D * pConfig->cutoffFrequency / pConfig->sampleRate;
|
||||
s = ma_sin(w);
|
||||
c = ma_cos(w);
|
||||
@@ -30734,7 +30756,13 @@ static ma_result ma_hpf_reinit__internal(const ma_hpf_config* pConfig, ma_hpf* p
|
||||
}
|
||||
|
||||
for (ihpf2 = 0; ihpf2 < hpf2Count; ihpf2 += 1) {
|
||||
ma_hpf2_config hpf2Config = ma_hpf2_config_init(pConfig->format, pConfig->channels, pConfig->sampleRate, pConfig->cutoffFrequency);
|
||||
ma_hpf2_config hpf2Config;
|
||||
double q;
|
||||
|
||||
/* TODO: Calculate Q. */
|
||||
q = 0;
|
||||
|
||||
hpf2Config = ma_hpf2_config_init(pConfig->format, pConfig->channels, pConfig->sampleRate, pConfig->cutoffFrequency, q);
|
||||
|
||||
if (isNew) {
|
||||
result = ma_hpf2_init(&hpf2Config, &pHPF->hpf2[ihpf2]);
|
||||
@@ -30866,7 +30894,7 @@ ma_uint32 ma_hpf_get_latency(ma_hpf* pHPF)
|
||||
Band-Pass Filtering
|
||||
|
||||
**************************************************************************************************************************************************************/
|
||||
ma_bpf2_config ma_bpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency)
|
||||
ma_bpf2_config ma_bpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q)
|
||||
{
|
||||
ma_bpf2_config config;
|
||||
|
||||
@@ -30875,6 +30903,12 @@ ma_bpf2_config ma_bpf2_config_init(ma_format format, ma_uint32 channels, ma_uint
|
||||
config.channels = channels;
|
||||
config.sampleRate = sampleRate;
|
||||
config.cutoffFrequency = cutoffFrequency;
|
||||
config.q = q;
|
||||
|
||||
/* Q cannot be 0 or else it'll result in a division by 0. In this case just default to 0.707107. */
|
||||
if (config.q == 0) {
|
||||
config.q = 0.707107;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
@@ -30891,7 +30925,7 @@ static MA_INLINE ma_biquad_config ma_bpf2__get_biquad_config(const ma_bpf2_confi
|
||||
|
||||
MA_ASSERT(pConfig != NULL);
|
||||
|
||||
q = 0.707107;
|
||||
q = pConfig->q;
|
||||
w = 2 * MA_PI_D * pConfig->cutoffFrequency / pConfig->sampleRate;
|
||||
s = ma_sin(w);
|
||||
c = ma_cos(w);
|
||||
@@ -31041,7 +31075,13 @@ static ma_result ma_bpf_reinit__internal(const ma_bpf_config* pConfig, ma_bpf* p
|
||||
}
|
||||
|
||||
for (ibpf2 = 0; ibpf2 < bpf2Count; ibpf2 += 1) {
|
||||
ma_bpf2_config bpf2Config = ma_bpf2_config_init(pConfig->format, pConfig->channels, pConfig->sampleRate, pConfig->cutoffFrequency);
|
||||
ma_bpf2_config bpf2Config;
|
||||
double q;
|
||||
|
||||
/* TODO: Calculate Q. */
|
||||
q = 0;
|
||||
|
||||
bpf2Config = ma_bpf2_config_init(pConfig->format, pConfig->channels, pConfig->sampleRate, pConfig->cutoffFrequency, q);
|
||||
|
||||
if (isNew) {
|
||||
result = ma_bpf2_init(&bpf2Config, &pBPF->bpf2[ibpf2]);
|
||||
|
||||
@@ -19,7 +19,7 @@ ma_result test_bpf2__by_format(const char* pInputFilePath, const char* pOutputFi
|
||||
return result;
|
||||
}
|
||||
|
||||
bpfConfig = ma_bpf2_config_init(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate, 2000);
|
||||
bpfConfig = ma_bpf2_config_init(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate, 2000, 0);
|
||||
result = ma_bpf2_init(&bpfConfig, &bpf);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_decoder_uninit(&decoder);
|
||||
|
||||
@@ -80,7 +80,7 @@ ma_result test_hpf2__by_format(const char* pInputFilePath, const char* pOutputFi
|
||||
return result;
|
||||
}
|
||||
|
||||
hpfConfig = ma_hpf2_config_init(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate, 2000);
|
||||
hpfConfig = ma_hpf2_config_init(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate, 2000, 0);
|
||||
result = ma_hpf2_init(&hpfConfig, &hpf);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_decoder_uninit(&decoder);
|
||||
|
||||
@@ -80,7 +80,7 @@ ma_result test_lpf2__by_format(const char* pInputFilePath, const char* pOutputFi
|
||||
return result;
|
||||
}
|
||||
|
||||
lpfConfig = ma_lpf2_config_init(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate, 2000);
|
||||
lpfConfig = ma_lpf2_config_init(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate, 2000, 0);
|
||||
result = ma_lpf2_init(&lpfConfig, &lpf);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_decoder_uninit(&decoder);
|
||||
|
||||
Reference in New Issue
Block a user