Search code examples
pythonnumpystructfftpyaudio

issue with music visualiser in python ( fft and generally )


So I'm trying to make a music visualizer, I'm very new to python ( let alone coding in general ) for a project I need to make a music visualiser however I'm struggling, I've managed to get an open audio stream.

Things i need help on :

Is this below code the correct way of getting the fft data and fftfreq data ( assuming thats amplitude and frequency data )? And do i need to do this calculation somewhere else? Or is doing it within that function the correct way?

How come when I try and print the fft_data at the end of the code, I get the error of ( fft_data is not defined ) even though I believe the function is called previously in the code and should have calculated something?

Am I correct that to get the resulting variables to be returned from the function i need to put return ( audio_data, fft_data, fft_freq) etc, and if so how come its still not printing fft_data at the bottom?

I will probably be following up with a later post when i am past these issues.

any help is honestly seriously appreciated <3

p.s since im new to python and coding in general please try not to explain in a complicated way, or if i ask, elaborate in simpler terms if possible ( doesnt have to be rediculously simple )

this is the method i want to go for, i dont want to use librosa or other modules i would like to stick with numpy struct and pyaudio as i know its possible

import pyaudio
import numpy as np
import time
import matplotlib.animation as animation
import matplotlib.pyplot as plt
from matplotlib import style

pa = pyaudio.PyAudio()

def callback(in_data, frame_count, time_info, flag):
audio_data = np.fromstring(in_data, dtype=np.float32)
print(audio_data)
fft_data = np.fft.fft(audio_data)
fft_freq = np.fft.fftfreq(len(fft_data))
return (audio_data, fft_data, fft_freq, pyaudio.paContinue)



stream = pa.open(format=pyaudio.paFloat32,
             channels=1,
             rate=44100,
             output=False,
             input=True,
             stream_callback=callback)

stream.start_stream()

stream.close()
pa.terminate()

print(fft_data)

If I do print(audio_data) inside the callback function, it prints the audio data but I'm not sure if its already plottable so I presume I have to use fft on it. However when I try and print fft_data at the bottom of the code it says "fft_data is not defined".


Solution

  • from the docs, stream_callback "must return a tuple: (out_data, flag)" and returns control back to the PortAudio rather than your code.

    for debugging, you might want to do something like:

    callback_output = []
    
    def callback(in_data, frame_count, time_info, flag):
        audio_data = np.fromstring(in_data, dtype=np.float32)
        callback_output.append(
            audio_data
        )
        return None, pyaudio.paContinue
    

    and then do the FFTs afterwards on the data that has been stored in callback_output