I'm playing around with audio signal processing for the first time and just to start somewhere, I decided to use the Python library pyo. My goal is to analyze an audio input signal from the microphone to detect different types of strikes on a drum and to emit an event (or call a callback, whatever) in that case. My first step is to define some frequency ranges, I want to observe and then to have a function called periodically and pass in the peak amplitudes within those defined frequency ranges.
I found that there is something like FFT/DFT and my naive idea is, that I can setup an FFT
object with my input signal and create an instance of the Pattern
class, that calls a function periodically. In that function I can then call the FFT
object in a way, so that it will return me a list with 1024 items. The "whole" frequency spectrum is sliced into 1024 slices and each item in the list contains an amplitude value for that specific frequency range slice at the given time.
I tried the following code and now I don't know how to interpretate the values provided by the FFT.get()
method. My question is: Are my expectations wrong or how do I use the FFT
class to get my list?
from pyo import *
server = Server(nchnls=1, buffersize=128, duplex=1, winhost="asio").boot().start()
class FrequencyRangeAmplitudeProvider:
__frequency_ranges = ()
__listener = lambda x: x
__fft = None
__pattern = None
def __init__(self, input, frequency_ranges, listener):
self.__frequency_ranges = frequency_ranges
self.__listener = listener
self.__fft = FFT(input, size=1024, overlaps=4, wintype=0)
self.__pattern = Pattern(function=self.__extract_and_emit, time=0.06).play()
def __extract_and_emit(self):
#print(self.__fft.get('real', True))
#print(self.__fft.get('imag', True))
#print(self.__fft.get('bin', True))
my_list = [] # <-- How to get the data, I'd need?
peak_amplitudes = self.__extract_peak_amplitude_in_frequency_ranges(my_list, self.__frequency_ranges)
self.__listener(peak_amplitudes)
@staticmethod
def __extract_peak_amplitude_in_frequency_ranges(amplitudes, frequency_ranges):
return (('A', -2.34), ('B', -.65))
frequency_ranges_to_observe = (('A', 430, 450), ('B', 870, 890))
def do_something_with_peak_amlitudes_in_frequency_ranges(amplitudes):
print(amplitudes)
provider = FrequencyRangeAmplitudeProvider(
Input(),
frequency_ranges_to_observe,
do_something_with_peak_amlitudes_in_frequency_ranges)
server.gui(locals())
```