Skip to content

Commit 1150554

Browse files
committed
ulab.numpy: implement sinc for creating audio filters
This is useful for generating FIR filters using code snippets generated at https://fiiir.com/ (at least those with a rectangular window type; other window types need additional functions but we can revisit it later if needed) I think this will come in handy for folks who are using the advanced features of our audio synthesizer module, synthio. e.g., the following block now gives highly similar results on ulab or numpy: ```py try: import numpy as np except: from ulab import numpy as np # Example code, computes the coefficients of a low-pass windowed-sinc filter. # Configuration. fS = 48000 # Sampling rate. fL = 4000 # Cutoff frequency. N = 23 # Filter length, must be odd. # Compute sinc filter. h = np.sinc(2 * fL / fS * (np.arange(N) - (N - 1) / 2)) # Normalize to get unity gain. h /= np.sum(h) # Applying the filter to a signal s can be as simple as writing # s = np.convolve(s, h)
1 parent ac2e995 commit 1150554

File tree

4 files changed

+29
-0
lines changed

4 files changed

+29
-0
lines changed

code/numpy/numpy.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,9 @@ static const mp_rom_map_elem_t ulab_numpy_globals_table[] = {
340340
#if ULAB_NUMPY_HAS_SIN
341341
{ MP_ROM_QSTR(MP_QSTR_sin), MP_ROM_PTR(&vector_sin_obj) },
342342
#endif
343+
#if ULAB_NUMPY_HAS_SINC
344+
{ MP_ROM_QSTR(MP_QSTR_sinc), MP_ROM_PTR(&vector_sinc_obj) },
345+
#endif
343346
#if ULAB_NUMPY_HAS_SINH
344347
{ MP_ROM_QSTR(MP_QSTR_sinh), MP_ROM_PTR(&vector_sinh_obj) },
345348
#endif

code/numpy/vector.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,27 @@ MATH_FUN_1(sin, sin);
570570
MP_DEFINE_CONST_FUN_OBJ_1(vector_sin_obj, vector_sin);
571571
#endif
572572

573+
#if ULAB_NUMPY_HAS_SINC
574+
//| def sin(a: _ArrayLike) -> ulab.numpy.ndarray:
575+
//| """Computes the sine function"""
576+
//| ...
577+
//|
578+
579+
static mp_float_t ulab_sinc1(mp_float_t x) {
580+
if (fpclassify(x) == FP_ZERO) {
581+
return MICROPY_FLOAT_CONST(1.);
582+
}
583+
x *= MP_PI;
584+
return MICROPY_FLOAT_C_FUN(sin)(x) / x;
585+
}
586+
587+
static mp_obj_t vector_sinc(mp_obj_t x_obj) {
588+
return vector_generic_vector(x_obj, ulab_sinc1);
589+
}
590+
591+
MP_DEFINE_CONST_FUN_OBJ_1(vector_sinc_obj, vector_sinc);
592+
#endif
593+
573594
#if ULAB_NUMPY_HAS_SINH
574595
//| def sinh(a: _ArrayLike) -> ulab.numpy.ndarray:
575596
//| """Computes the hyperbolic sine"""

code/numpy/vector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ MP_DECLARE_CONST_FUN_OBJ_1(vector_log10_obj);
3939
MP_DECLARE_CONST_FUN_OBJ_1(vector_log2_obj);
4040
MP_DECLARE_CONST_FUN_OBJ_1(vector_radians_obj);
4141
MP_DECLARE_CONST_FUN_OBJ_1(vector_sin_obj);
42+
MP_DECLARE_CONST_FUN_OBJ_1(vector_sinc_obj);
4243
MP_DECLARE_CONST_FUN_OBJ_1(vector_sinh_obj);
4344
#if ULAB_SUPPORTS_COMPLEX
4445
MP_DECLARE_CONST_FUN_OBJ_KW(vector_sqrt_obj);

code/ulab.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,10 @@
616616
#define ULAB_NUMPY_HAS_SIN (1)
617617
#endif
618618

619+
#ifndef ULAB_NUMPY_HAS_SINC
620+
#define ULAB_NUMPY_HAS_SINC (1)
621+
#endif
622+
619623
#ifndef ULAB_NUMPY_HAS_SINH
620624
#define ULAB_NUMPY_HAS_SINH (1)
621625
#endif

0 commit comments

Comments
 (0)