From dd46869ca7d3594ddff8c5b625e1f6d27cda7a29 Mon Sep 17 00:00:00 2001 From: shivam navadiya Date: Tue, 21 May 2024 20:52:30 +0530 Subject: [PATCH 1/3] Updated Spectogram.py --- Spectogram.py | 139 +++++++++++++++++++++++--------------------------- 1 file changed, 65 insertions(+), 74 deletions(-) diff --git a/Spectogram.py b/Spectogram.py index df0161f..dc7e9be 100644 --- a/Spectogram.py +++ b/Spectogram.py @@ -4,13 +4,15 @@ import scipy.signal import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg +import threading +import queue -""" RealTime Audio Spectrogram plot """ +# Global variables +_VARS = {"window": None, "stream": None, "audioData": np.array([])} +audio_buffer = queue.Queue(maxsize=10) # Buffer for audio data +stop_event = threading.Event() # Event to signal stopping of the audio stream -# VARS CONSTS: -_VARS = {"window": False, "stream": False, "audioData": np.array([])} - -# pysimpleGUI INIT: +# PySimpleGUI initialization AppFont = "Any 16" sg.theme("DarkBlue3") layout = [ @@ -30,54 +32,35 @@ sg.Button("Exit", font=AppFont), ], ] -_VARS["window"] = sg.Window( - "Mic to spectrogram plot + Max Level", layout, finalize=True -) - -graph = _VARS["window"]["graph"] +_VARS["window"] = sg.Window("Mic to spectrogram plot + Max Level", layout, finalize=True) -# INIT vars: -CHUNK = 1024 # Samples: 1024, 512, 256, 128 -RATE = 44100 # Equivalent to Human Hearing at 40 kHz -INTERVAL = 1 # Sampling Interval in Seconds -> Interval to listen -TIMEOUT = 10 # In ms for the event loop +# PyAudio initialization pAud = pyaudio.PyAudio() +CHUNK = 1024 +RATE = 44100 +INTERVAL = 1 +TIMEOUT = 100 # Adjusted timeout value -try: - pAud.get_device_info_by_index(0) -except pyaudio.CoreError as e: - print(f"Error initializing PyAudio: {e}") - pAud = None -# FUNCTIONS: - - -# PySimpleGUI plots: -def draw_figure(canvas, figure): - figure_canvas_agg = FigureCanvasTkAgg(figure, canvas) - figure_canvas_agg.draw() - figure_canvas_agg.get_tk_widget().pack(side="top", fill="both", expand=1) - return figure_canvas_agg - - -# pyaudio stream: def stop(): - if _VARS["stream"]: + if _VARS["stream"] is not None and _VARS["stream"].is_active(): + stop_event.set() # Signal the audio processing thread to stop _VARS["stream"].stop_stream() _VARS["stream"].close() + _VARS["stream"] = None _VARS["window"]["-PROG-"].update(0) - _VARS["window"]["Stop"].Update(disabled=True) - _VARS["window"]["Listen"].Update(disabled=False) + _VARS["window"]["Stop"].update(disabled=True) + _VARS["window"]["Listen"].update(disabled=False) + stop_event.clear() # Reset the event for the next use - -# callback: def callback(in_data, frame_count, time_info, status): - _VARS["audioData"] = np.frombuffer(in_data, dtype=np.int16) + if stop_event.is_set(): + return (in_data, pyaudio.paComplete) + audio_buffer.put(np.frombuffer(in_data, dtype=np.int16)) return (in_data, pyaudio.paContinue) - def listen(): - _VARS["window"]["Stop"].Update(disabled=False) - _VARS["window"]["Listen"].Update(disabled=True) + _VARS["window"]["Stop"].update(disabled=False) + _VARS["window"]["Listen"].update(disabled=True) _VARS["stream"] = pAud.open( format=pyaudio.paInt16, channels=1, @@ -88,36 +71,44 @@ def listen(): ) _VARS["stream"].start_stream() - -# INIT: -fig, ax = plt.subplots() # create a figure and an axis object -fig_agg = draw_figure(graph.TKCanvas, fig) # draw the figure on the graph - -# MAIN LOOP -while True: - event, values = _VARS["window"].read(timeout=TIMEOUT) - if event == sg.WIN_CLOSED or event == "Exit": - stop() - pAud.terminate() - break - if event == "Listen": - listen() - if event == "Stop": - stop() - - # Along with the global audioData variable, this - # bit updates the spectrogram plot - - elif _VARS["audioData"].size != 0: - # Update volume meter - _VARS["window"]["-PROG-"].update(np.amax(_VARS["audioData"])) - # Compute spectrogram - f, t, Sxx = scipy.signal.spectrogram(_VARS["audioData"], fs=RATE) - # Plot spectrogram - ax.clear() # clear the previous plot - ax.pcolormesh( - t, f, Sxx, shading="gouraud" - ) # plot the spectrogram as a colored mesh - ax.set_ylabel("Frequency [Hz]") # set the y-axis label - ax.set_xlabel("Time [sec]") # set the x-axis label - fig_agg.draw() # redraw the figure +def audio_processing(ax, fig_agg): + while not stop_event.is_set(): + try: + audio_data = audio_buffer.get(timeout=1) + if audio_data.size != 0: + _VARS["window"]["-PROG-"].update(np.amax(audio_data)) + f, t, Sxx = scipy.signal.spectrogram(audio_data, fs=RATE) + ax.clear() + ax.pcolormesh(t, f, Sxx, shading="gouraud") + ax.set_ylabel("Frequency [Hz]") + ax.set_xlabel("Time [sec]") + fig_agg.draw() + except queue.Empty: + continue + +def main(): + # Initialization + fig, ax = plt.subplots() + fig_agg = FigureCanvasTkAgg(fig, _VARS["window"]["graph"].TKCanvas) + fig_agg.draw() + fig_agg.get_tk_widget().pack(side="top", fill="both", expand=1) + + # Multithreading for audio processing + audio_thread = threading.Thread(target=audio_processing, args=(ax, fig_agg)) + audio_thread.daemon = True + audio_thread.start() + + # Event loop + while True: + event, values = _VARS["window"].read(timeout=TIMEOUT) + if event == sg.WINDOW_CLOSED or event == "Exit": + stop() + pAud.terminate() + break + elif event == "Listen": + listen() + elif event == "Stop": + stop() + +if __name__ == "__main__": + main() From 78647af077c8f8a5e8295091eb1d22bf698255a2 Mon Sep 17 00:00:00 2001 From: Shubhanshu Navadiya <115715087+Shubhanshu-356@users.noreply.github.com> Date: Sat, 15 Jun 2024 14:16:02 +0530 Subject: [PATCH 2/3] Update Spectogram.py --- Spectogram.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Spectogram.py b/Spectogram.py index 3a11b50..218817a 100644 --- a/Spectogram.py +++ b/Spectogram.py @@ -4,13 +4,13 @@ import scipy.signal import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg - gui-performance-enhancement +# gui-performance-enhancement import threading import queue import subprocess -main + # Global variables _VARS = {"window": None, "stream": None, "audioData": np.array([])} @@ -23,7 +23,6 @@ _VARS = {"window": False, "stream": False, "audioData": np.array([]), "current_visualizer_process": None} # pysimpleGUI INIT: - main AppFont = "Any 16" sg.theme("DarkBlue3") @@ -52,7 +51,6 @@ _VARS["window"] = sg.Window("Mic to spectrogram plot + Max Level", layout, finalize=True) gui-performance-enhancement graph = _VARS["window"]["graph"] - main # PyAudio initialization pAud = pyaudio.PyAudio() @@ -78,7 +76,7 @@ def stop(): _VARS["window"]["Listen"].Update(disabled=False) # callback: -main + def callback(in_data, frame_count, time_info, status): if stop_event.is_set(): return (in_data, pyaudio.paComplete) @@ -202,4 +200,4 @@ def close_current_visualizer(): ax.set_ylabel("Frequency [Hz]") # set the y-axis label ax.set_xlabel("Time [sec]") # set the x-axis label fig_agg.draw() # redraw the figure -main + From 5661e41231b03bf529592eb2d9ead2ae11a42196 Mon Sep 17 00:00:00 2001 From: Shubhanshu Navadiya <115715087+Shubhanshu-356@users.noreply.github.com> Date: Sun, 16 Jun 2024 13:01:29 +0530 Subject: [PATCH 3/3] Update Spectogram.py --- Spectogram.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Spectogram.py b/Spectogram.py index 218817a..2d6c276 100644 --- a/Spectogram.py +++ b/Spectogram.py @@ -3,8 +3,8 @@ import numpy as np import scipy.signal import matplotlib.pyplot as plt -from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -# gui-performance-enhancement +from matplotlib.backends.backend_tkagg +import FigureCanvasTkAgg import threading import queue import subprocess @@ -17,7 +17,7 @@ audio_buffer = queue.Queue(maxsize=10) # Buffer for audio data stop_event = threading.Event() # Event to signal stopping of the audio stream - gui-performance-enhancement + # PySimpleGUI initialization # VARS CONSTS: _VARS = {"window": False, "stream": False, "audioData": np.array([]), "current_visualizer_process": None} @@ -25,9 +25,7 @@ # pysimpleGUI INIT: AppFont = "Any 16" sg.theme("DarkBlue3") - -menu_layout = [ - ['Run Visualizers', ['Amplitude-Frequency-Visualizer', 'Waveform', 'Spectrogram', 'Intensity-vs-Frequency-and-time']], +Visualizers', ['Amplitude-Frequency-Visualizer', 'Waveform', 'Spectrogram', 'Intensity-vs-Frequency-and-time']], ] layout = [ @@ -49,7 +47,6 @@ ], ] _VARS["window"] = sg.Window("Mic to spectrogram plot + Max Level", layout, finalize=True) - gui-performance-enhancement graph = _VARS["window"]["graph"] # PyAudio initialization @@ -66,7 +63,6 @@ def stop(): _VARS["stream"].close() _VARS["stream"] = None _VARS["window"]["-PROG-"].update(0) - gui-performance-enhancement _VARS["window"]["Stop"].update(disabled=True) _VARS["window"]["Listen"].update(disabled=False) stop_event.clear() # Reset the event for the next use @@ -96,7 +92,7 @@ def listen(): ) _VARS["stream"].start_stream() - gui-performance-enhancement + def audio_processing(ax, fig_agg): while not stop_event.is_set(): try: