I have a function that computes the fourier transform of an incoming audio stream, and then identifies what musical notes are most dominant within the audio. Everything is working (though I'm sure my code may be janky in many ways). The main thing I'd like to fix is the speed of the function. I'm using a chunk size of 2^14, which makes the function quite accurate, but also way slower than I'd like. I was wondering if there is any way to implement a C fft function that could run faster, but still have it run within my Python code. I'm also open to any other suggestions on how to get this function to run faster.
Here is the current function:
def pitch_calculations(stream, CHUNK, RATE):
    # Read mic stream and then call struct.unpack to convert from binary data back to floats
    data = stream.read(CHUNK, exception_on_overflow=False)
    dataInt = np.array(struct.unpack(str(CHUNK) + 'h', data))
    
    # Apply a window function (Hamming) to the input data
    windowed_data = np.hamming(CHUNK) * dataInt
    # Using numpy fast Fourier transform to convert mic data into frequencies
    fft_result = np.abs(fft.fft(windowed_data, threads=6)) * 2 / (11000 * CHUNK)
    fft_result_copy = fft_result
    freqs = np.fft.fftfreq(len(windowed_data), d=1.0 / RATE)
    
    fft_result = fft_result[:int(len(fft_result)/2)]
    freqs = freqs[:int(len(freqs)/2)]
    
    # Find the indices of local maxima in the frequency spectrum using scipy.signal find_peaks
    localmax_indices = find_peaks(fft_result, height=0.04)[0]
    
    # Get the magnitudes of the local maxima
    strong_freqs = fft_result[localmax_indices]
    
    # Sort the magnitudes in descending order
    sorted_indices = np.argsort(strong_freqs)[::-1]
    
    # Calculate the pitches from the peaks, calculate how many cents sharp/flat
    pitches = []
    
    for index in sorted_indices:
        pitches.append(abs(freqs[localmax_indices[index]]))
        
    note_list = [calculate_tuning(pitch)[0] for pitch in pitches]
    cent_list = [calculate_tuning(pitch)[1] for pitch in pitches]
    note_list = order_pitches(note_list)
    note_list = remove_duplicates(note_list)
    
    
    return note_list, cent_list
 
    