import gradio as gr import tensorflow as tf import librosa import librosa.display import numpy as np import matplotlib.pyplot as plt import sounddevice as sd import soundfile as sf import threading # Load the pre-trained model model = tf.keras.models.load_model("model.h5") # Function to process audio, predict, and generate results def process_audio(audio_file, breath_in_time, breath_out_time): try: # Calculate total recording duration total_time = breath_in_time + breath_out_time # Load the audio file y, sr = librosa.load(audio_file, sr=16000) # Detect segments (e.g., using energy or silence) intervals = librosa.effects.split(y, top_db=20) results = [] plt.figure(figsize=(10, 4)) librosa.display.waveshow(y, sr=sr, alpha=0.5) # Process each segment for i, (start, end) in enumerate(intervals): segment = y[start:end] duration = (end - start) / sr # Compute the amplitude (mean absolute value) amplitude = np.mean(np.abs(segment)) # Extract MFCC features mfcc = librosa.feature.mfcc(y=segment, sr=sr, n_mfcc=13) mfcc = np.mean(mfcc, axis=1).reshape(1, -1) # Predict inhale or exhale prediction = model.predict(mfcc) label_from_model = "Inhale" if np.argmax(prediction) == 0 else "Exhale" # Assign label based on amplitude label = "Inhale" if amplitude > 0.05 else "Exhale" # Threshold for exhale # Append results results.append({ "Segment": i + 1, "Type": label, "Duration (s)": round(duration, 2), "Amplitude": round(amplitude, 4) }) # Highlight segment on waveform with swapped colors plt.axvspan(start / sr, end / sr, color='red' if label == "Inhale" else 'blue', alpha=0.3) # Save the waveform with highlighted segments plt.title("Audio Waveform with Inhale/Exhale Segments") plt.xlabel("Time (s)") plt.ylabel("Amplitude") plt.savefig("waveform_highlighted.png") plt.close() # Format results as a table result_table = "Segment\tType\tDuration (s)\tAmplitude\n" + "\n".join( f"{row['Segment']}\t{row['Type']}\t{row['Duration (s)']}\t{row['Amplitude']}" for row in results ) return result_table, "waveform_highlighted.png" except Exception as e: return f"Error: {str(e)}", None # Function to record audio for a specified duration def record_audio(duration): try: # Define the file name audio_file = "recorded_audio.wav" # Record audio print(f"Recording for {duration} seconds...") recording = sd.rec(int(duration * 16000), samplerate=16000, channels=1, dtype='float32') sd.wait() # Wait until recording is finished sf.write(audio_file, recording, 16000) print("Recording complete!") return audio_file except Exception as e: return f"Error: {str(e)}" # Function to animate the scaling circle (during recording) def create_circle_animation(duration): # HTML and CSS to create the animated circle circle_animation = f""" <div id="circle-container" style="text-align:center; margin-top: 50px;"> <div id="circle" style="width: 50px; height: 50px; border-radius: 50%; background-color: #3498db; animation: scale-up-down {duration}s infinite;"></div> </div> <style> @keyframes scale-up-down {{ 0% {{ transform: scale(1); }} 50% {{ transform: scale(1.5); }} 100% {{ transform: scale(1); }} }} </style> """ return circle_animation # Define Gradio interface with gr.Blocks() as demo: gr.Markdown("### Breathe Training Application") with gr.Row(): breath_in_time = gr.Number(label="Breath In Time (seconds)", value=0, interactive=True) breath_out_time = gr.Number(label="Breath Out Time (seconds)", value=0, interactive=True) with gr.Row(): audio_input = gr.Audio(type="filepath", label="Upload Audio (optional)") result_output = gr.Textbox(label="Prediction Results (Table)") waveform_output = gr.Image(label="Waveform with Highlighted Segments") circle_output = gr.HTML(label="Breath Circle Animation") submit_button = gr.Button("Analyze") def handle_record_and_analyze(breath_in, breath_out): total_duration = breath_in + breath_out circle_animation = create_circle_animation(total_duration) audio_file = record_audio(total_duration) result_table, waveform_image = process_audio(audio_file, breath_in, breath_out) return circle_animation, result_table, waveform_image submit_button.click( fn=process_audio, inputs=[audio_input, breath_in_time, breath_out_time], outputs=[result_output, waveform_output], ) # Run the Gradio app demo.launch() # re load