I'm working on an audio visualizer using Blender, and I'm wanting to separate input audio files into their respective frequencies to allow my models to react based on the amplitude at different frequencies. Is there a Python library out there that can (somewhat simply) separate an audio file into different frequencies? I'm going to be generating 12 different animations with audio files, and want to be able to decide which frequencies to separate out and whatnot.
-
$\begingroup$ Do you mean you want to take one audio data series and get back e.g 5 audio data series, each containing the frequency content in a specific frequency band? For example, the first will contain the signal with frequencies 20-200 Hz, the second 200-500Hz, etc? $\endgroup$– JdipAug 31 at 10:10
-
$\begingroup$ That's exactly what I'm going for, with hard cutoffs. $\endgroup$– Devin GardnerAug 31 at 10:46
2 Answers
What you need is a filter bank.
For audio, typically, fractional octave filter banks are used. This Python library can help you.
If you want to specify the bands yourself, here is another Python library than can help. You'll want to look into their Linkwitz-Riley crossover network implementation (
crossover
). These are particularly interesting because their magnitude responses sum to unity gain (if you decide to modify the band-passed signals and re-construct).
-
$\begingroup$ Oh awesome!! Thank you so much!! Now it's time to learn what any of those words mean lol $\endgroup$ Aug 31 at 15:48
-
$\begingroup$ Let me know if you need more help! Don't hesitate to ask in a separate question if you think it's worth it, otherwise you can edit your question with your progress. $\endgroup$– JdipAug 31 at 16:01
-
$\begingroup$ I edited the question, I'm now running into errors running pyfilterbank. $\endgroup$ Aug 31 at 16:55
-
$\begingroup$ That's not a signal processing question though. These types of questions can be asked at stack exchange $\endgroup$– JdipAug 31 at 17:05
-
$\begingroup$ That's a fair point. I've decided against the first suggested library in favor of
pyfar
as it seems to be more powerful, I'm just now struggling to comprehend all the terminology and math behind a lot of it. $\endgroup$ Aug 31 at 17:16
You want to extract signal components within a specific frequency range. For this you can use a band-pass filter. If you use several filter, then you can call it a filter-bank.
There are several option to build a band-pass filter. You can check:
- Scipy.signal https://docs.scipy.org/doc/scipy/reference/signal.html
- Librosa https://librosa.org/doc/latest/index.html
- Pyfar https://pyfar.readthedocs.io/en/latest/readme.html
I would go with scipy.signal because of the great set of tools (either for filtering but also for filter design and analysis). It is also quite fast and with a great community of developers.
A filter takes a signal as input and provides a signal as output. After the signal is filteres you must also decide how you will use it for your purposes. I suggest to extract segment of a predefined duration (1sec for example) and calculate the average power of the filtered signal.