Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ulab.numpy: implement sinc for creating audio filters #617

Merged
merged 3 commits into from
May 16, 2023

Conversation

jepler
Copy link
Collaborator

@jepler jepler commented May 15, 2023

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:

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)

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)
@@ -570,6 +570,27 @@ MATH_FUN_1(sin, sin);
MP_DEFINE_CONST_FUN_OBJ_1(vector_sin_obj, vector_sin);
#endif

#if ULAB_NUMPY_HAS_SINC
//| def sin(a: _ArrayLike) -> ulab.numpy.ndarray:
//| """Computes the sine function"""
Copy link
Owner

@v923z v923z May 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two typos here, I believe.

@v923z
Copy link
Owner

v923z commented May 16, 2023

@jepler If you think that this is useful, then we should definitely add it.

However, before merging, could you, please, add build to the requirements list, as you suggested in #616, so that the checks pass?

@jepler
Copy link
Collaborator Author

jepler commented May 16, 2023

This isn't critical, because it's quite possible to implement sinc in python (thanks @gamblor21):

def sinc(x):
    y = np.pi * np.where(x == 0, 1.0e-20, x)
    return np.sin(y)/y

@v923z
Copy link
Owner

v923z commented May 16, 2023

This isn't critical, because it's quite possible to implement sinc in python (thanks @gamblor21):

You should just merge it, if you are satisfied.

def sinc(x):
    y = np.pi * np.where(x == 0, 1.0e-20, x)
    return np.sin(y)/y

Indeed. In that case, it could've been implemented as a snippet.

@jepler jepler merged commit 6619c20 into v923z:master May 16, 2023
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants