File size: 5,066 Bytes
8e6cfd5
fbf28f4
f130dac
5f353bd
fbf28f4
8e6cfd5
dbff8ac
 
 
f130dac
51a7b0b
fbf28f4
 
a2e4e97
dbff8ac
fbf28f4
1a09d3b
 
 
fbf28f4
 
dbff8ac
a2e4e97
5735916
dbff8ac
5735916
a2e4e97
5735916
 
dbff8ac
5735916
 
 
 
a2e4e97
 
5735916
dbff8ac
5735916
 
 
dbff8ac
 
5735916
1a09d3b
 
a2e4e97
 
dbff8ac
a2e4e97
5735916
 
 
 
 
 
dbff8ac
a2e4e97
5735916
dbff8ac
a2e4e97
5735916
 
 
a2e4e97
5735916
dbff8ac
a2e4e97
5735916
 
 
dbff8ac
a2e4e97
dbff8ac
5735916
 
 
a2e4e97
dbff8ac
 
a2e4e97
dbff8ac
a2e4e97
 
 
dbff8ac
a2e4e97
dbff8ac
a2e4e97
 
dbff8ac
 
 
 
ec6e414
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a2e4e97
5735916
 
dbff8ac
 
f7500f7
 
dbff8ac
5735916
dbff8ac
5735916
 
ec6e414
dbff8ac
a2e4e97
 
 
1a09d3b
ec6e414
1a09d3b
ec6e414
 
1a09d3b
a2e4e97
 
 
 
 
 
 
dbff8ac
d2c0c43
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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