Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/alexmarsev/soxr.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Sykes <rob@rob-Ideapad-S205.(none)>2013-02-28 00:24:01 +0400
committerRob Sykes <rob@rob-Ideapad-S205.(none)>2013-02-28 00:24:01 +0400
commitfa75beaf0b8d5e594018471d778e98eb7f0a87dd (patch)
tree286aade8b3442d7ffe9617e73c4b624c9c71fe07
parent4d9db78903ab378efaf7fbf9e943695a0e8ac266 (diff)
Slight reworking of API params for phase-response and pass-/stop-band spec
-rw-r--r--src/rate.h24
-rw-r--r--src/soxr.c22
-rw-r--r--src/soxr.h12
3 files changed, 33 insertions, 25 deletions
diff --git a/src/rate.h b/src/rate.h
index fc2395c..81cabff 100644
--- a/src/rate.h
+++ b/src/rate.h
@@ -369,7 +369,7 @@ typedef struct {
#define have_post_stage (postM * postL != 1)
#define TO_3dB(a) ((1.6e-6*a-7.5e-4)*a+.646)
-#define LOW_Q_BW0_PC (67 + 5 / 8.)
+#define LOW_Q_BW0 (1385 / 2048.) /* 0.67625 rounded to be a FP exact. */
typedef enum {
rolloff_none, rolloff_small /* <= 0.01 dB */, rolloff_medium /* <= 0.35 dB */
@@ -385,9 +385,9 @@ static char const * rate_init(
double factor, /* Input rate divided by output rate. */
double bits, /* Required bit-accuracy (pass + stop) 16|20|28 */
double phase, /* Linear/minimum etc. filter phase. 50 */
- double bw_pc, /* Pass-band % (0dB pt.) to preserve. 91.3|98.4*/
- double anti_aliasing_pc, /* % bandwidth without aliasing 100 */
- rolloff_t rolloff, /* Pass-band roll-off small */
+ double passband_end, /* 0dB pt. bandwidth to preserve; nyquist=1 0.913*/
+ double stopband_begin, /* Aliasing/imaging control; > passband_end 1 */
+ rolloff_t rolloff, /* Pass-band roll-off small */
bool maintain_3dB_pt, /* true */
double multiplier, /* Linear gain to apply during conversion. 1 */
@@ -400,20 +400,20 @@ static char const * rate_init(
int log2_large_dft_size)
{
double att = (bits + 1) * linear_to_dB(2.), attArb = att; /* pass + stop */
- double tbw0 = 1 - bw_pc / 100, Fs_a = 2 - anti_aliasing_pc / 100;
+ double tbw0 = 1 - passband_end, Fs_a = stopband_begin;
double arbM = factor, tbw_tighten = 1;
int n = 0, i, preL = 1, preM = 1, shift = 0, arbL = 1, postL = 1, postM = 1;
bool upsample = false, rational = false, iOpt = !noSmallIntOpt;
- int mode = rolloff > rolloff_small? factor > 1 || bw_pc > LOW_Q_BW0_PC:
+ int mode = rolloff > rolloff_small? factor > 1 || passband_end > LOW_Q_BW0:
(int)ceil(2 + (bits - 17) / 4);
stage_t * s;
assert(factor > 0);
assert(!bits || (15 <= bits && bits <= 33));
assert(0 <= phase && phase <= 100);
- assert(53 <= bw_pc && bw_pc <= 100);
- assert(85 <= anti_aliasing_pc && anti_aliasing_pc <= 130);
- assert(bw_pc < 200 - anti_aliasing_pc);
+ assert(.53 <= passband_end);
+ assert(stopband_begin <= 1.2);
+ assert(passband_end + .005 < stopband_begin);
p->factor = factor;
if (bits) while (!n++) { /* Determine stages: */
@@ -690,9 +690,9 @@ static char const * rate_create(
channel, shared,
io_ratio,
q_spec->precision,
- q_spec->phase,
- q_spec->bw_pc,
- q_spec->anti_aliasing_pc,
+ q_spec->phase_response,
+ q_spec->passband_end,
+ q_spec->stopband_begin,
"\1\2\0"[q_spec->flags & 3],
!!(q_spec->flags & SOXR_MAINTAIN_3DB_PT),
scale,
diff --git a/src/soxr.c b/src/soxr.c
index 457144b..8a9eca6 100644
--- a/src/soxr.c
+++ b/src/soxr.c
@@ -69,7 +69,7 @@ struct soxr {
/* TODO: these should not be here. */
#define TO_3dB(a) ((1.6e-6*a-7.5e-4)*a+.646)
-#define LOW_Q_BW0_PC (67 + 5 / 8.)
+#define LOW_Q_BW0 (1385 / 2048.) /* 0.67625 rounded to be a FP exact. */
soxr_quality_spec_t soxr_quality_spec(unsigned long recipe, unsigned long flags)
{
@@ -85,24 +85,24 @@ soxr_quality_spec_t soxr_quality_spec(unsigned long recipe, unsigned long flags)
quality = 6;
else if (quality > 10)
quality = 0;
- p->phase = "\62\31\144"[(recipe & 0x30)>>8];
- p->anti_aliasing_pc = 100;
+ p->phase_response = "\62\31\144"[(recipe & 0x30)>>8];
+ p->stopband_begin = 1;
p->precision = !quality? 0: quality < 3? 16 : quality < 8? 4 + quality * 4 : 55 - quality * 4;
rej = p->precision * linear_to_dB(2.);
p->flags = flags;
if (quality < 8) {
- p->bw_pc = quality == 1? LOW_Q_BW0_PC : 100 - 5 / TO_3dB(rej);
+ p->passband_end = quality == 1? LOW_Q_BW0 : 1 - .05 / TO_3dB(rej);
if (quality <= 2)
p->flags &= ~SOXR_ROLLOFF_NONE, p->flags |= SOXR_ROLLOFF_MEDIUM;
}
else {
- static float const bw[] = {93.1f, 83.2f, 66.3f};
- p->bw_pc = bw[quality - 8];
+ static float const bw[] = {.931f, .832f, .663f};
+ p->passband_end = bw[quality - 8];
if (quality - 8 == 2)
p->flags &= ~SOXR_ROLLOFF_NONE, p->flags |= SOXR_ROLLOFF_MEDIUM;
}
if (recipe & SOXR_STEEP_FILTER)
- p->bw_pc = 100 - 1 / TO_3dB(rej);
+ p->passband_end = 1 - .01 / TO_3dB(rej);
return spec;
}
@@ -217,6 +217,14 @@ soxr_t soxr_create(
if (p) {
p->q_spec = q_spec? *q_spec : soxr_quality_spec(SOXR_HQ, 0);
+
+ if (q_spec) { /* Backwards compatibility with original API: */
+ if (p->q_spec.passband_end > 2)
+ p->q_spec.passband_end /= 100;
+ if (p->q_spec.stopband_begin > 2)
+ p->q_spec.stopband_begin = 2 - p->q_spec.stopband_begin / 100;
+ }
+
p->io_ratio = io_ratio;
p->num_channels = num_channels;
if (io_spec)
diff --git a/src/soxr.h b/src/soxr.h
index bcc7bff..aa7960d 100644
--- a/src/soxr.h
+++ b/src/soxr.h
@@ -221,12 +221,12 @@ struct soxr_io_spec { /* Typically */
struct soxr_quality_spec { /* Typically */
- double precision; /* Conversion precision (in bits). 20 */
- double phase; /* Linear/minimum etc. phase. [0,100] 50 */
- double bw_pc; /* Band-width % (0dB pt.) to preserve. 91.3 */
- double anti_aliasing_pc; /* % bandwidth without aliasing. 100 */
- void * e; /* Reserved for internal use. 0 */
- unsigned long flags; /* Per the following #defines. 0 */
+ double precision; /* Conversion precision (in bits). 20 */
+ double phase_response; /* 0=minimum, ... 50=linear, ... 100=maximum 50 */
+ double passband_end; /* 0dB pt. bandwidth to preserve; nyquist=1 0.913*/
+ double stopband_begin; /* Aliasing/imaging control; > passband_end 1 */
+ void * e; /* Reserved for internal use. 0 */
+ unsigned long flags; /* Per the following #defines. 0 */
};
#define SOXR_ROLLOFF_SMALL 0u /* <= 0.01 dB */