Dimsumcat commited on
Commit
51a7b0b
·
verified ·
1 Parent(s): 7d0b2db

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -97
app.py CHANGED
@@ -4,140 +4,78 @@ import librosa
4
  import librosa.display
5
  import numpy as np
6
  import matplotlib.pyplot as plt
7
- import time
8
 
9
- # Load the pre-trained model (optional for this logic, depending on use case)
10
  model = tf.keras.models.load_model("model.h5")
11
 
12
  # Function to process audio, predict, and generate results
13
- def process_audio(audio_file, inhale_duration, exhale_duration):
14
  try:
15
  # Load the audio file
16
  y, sr = librosa.load(audio_file, sr=16000)
17
 
18
- # Compute energy (absolute value of the signal)
19
- energy = np.abs(y)
 
 
 
20
 
21
- # Define a threshold for distinguishing inhalation from exhalation
22
- threshold = 0.02 # This threshold can be adjusted based on your data
23
-
24
- # Segment the audio based on energy
25
- segments = librosa.effects.split(y, top_db=20)
26
-
27
- all_segments = [] # To store all segments for table generation
28
- prev_end = 0 # To track the previous segment's end time
29
- prev_label = None # To track the last segment label (Inhale/Exhale)
30
- prev_start = 0 # To track the previous segment's start time
31
-
32
  plt.figure(figsize=(10, 4))
33
  librosa.display.waveshow(y, sr=sr, alpha=0.5)
34
-
35
- # Loop through all segments and classify them
36
- for i, (start, end) in enumerate(segments):
37
  segment = y[start:end]
38
  duration = (end - start) / sr
39
- mean_amplitude = np.mean(np.abs(segment))
40
-
41
- # Classify the segment as Inhale or Exhale based on amplitude
42
- label = "Exhale" if mean_amplitude > threshold else "Inhale"
43
-
44
- # Store the first segment
45
- if prev_end == 0:
46
- prev_end = end
47
- prev_start = start
48
- prev_label = label
49
- continue
50
-
51
- # Calculate the duration between this segment and the previous one
52
- segment_duration = (start - prev_end) / sr
53
-
54
- # Append previous segment (Inhale or Exhale) to the list
55
- all_segments.append({
56
- "Segment": len(all_segments) + 1,
57
- "Type": prev_label,
58
- "Duration (s)": round(segment_duration, 2),
59
- "Mean Amplitude": round(np.mean(np.abs(y[prev_start:prev_end])), 4),
60
- "Start (s)": round(prev_start / sr, 2),
61
- "End (s)": round(prev_end / sr, 2)
62
- })
63
-
64
- # Append current segment (Inhale or Exhale)
65
- all_segments.append({
66
- "Segment": len(all_segments) + 1,
67
  "Type": label,
68
- "Duration (s)": round(duration, 2),
69
- "Mean Amplitude": round(mean_amplitude, 4),
70
- "Start (s)": round(start / sr, 2),
71
- "End (s)": round(end / sr, 2)
72
  })
73
-
74
- # Highlight the exhale periods in red
75
- if label == "Exhale":
76
- plt.axvspan(start / sr, end / sr, color='red', alpha=0.3)
77
- # Highlight the inhale periods in blue
78
- elif label == "Inhale":
79
- plt.axvspan(prev_end / sr, start / sr, color='blue', alpha=0.3)
80
-
81
- prev_start = start # Update the start for the next iteration
82
- prev_end = end # Update the end for the next iteration
83
- prev_label = label # Update the label for the next iteration
84
-
85
  # Save the waveform with highlighted segments
86
  plt.title("Audio Waveform with Inhale/Exhale Segments")
87
  plt.xlabel("Time (s)")
88
  plt.ylabel("Amplitude")
89
  plt.savefig("waveform_highlighted.png")
90
  plt.close()
91
-
92
  # Format results as a table
93
- result_table = "Segment\tType\tDuration (s)\tMean Amplitude\tStart (s)\tEnd (s)\n" + "\n".join(
94
- f"{row['Segment']}\t{row['Type']}\t{row['Duration (s)']}\t{row['Mean Amplitude']}\t{row['Start (s)']}\t{row['End (s)']}" for row in all_segments
95
  )
96
-
97
- # Start countdown for recording
98
- total_duration = inhale_duration + exhale_duration
99
- countdown_message = f"Starting recording with total duration of {total_duration} seconds.\n"
100
- countdown_message += f"Starting Inhale for {inhale_duration} seconds...\n"
101
-
102
- for t in range(inhale_duration, 0, -1):
103
- time.sleep(1)
104
- countdown_message += f"Inhale: {t}s remaining...\n"
105
-
106
- countdown_message += f"Switching to Exhale for {exhale_duration} seconds...\n"
107
 
108
- for t in range(exhale_duration, 0, -1):
109
- time.sleep(1)
110
- countdown_message += f"Exhale: {t}s remaining...\n"
111
-
112
- countdown_message += "Recording Finished!"
113
-
114
- return result_table, "waveform_highlighted.png", countdown_message
115
 
116
  except Exception as e:
117
- return f"Error: {str(e)}", None, None
118
-
119
 
120
  # Define Gradio interface
121
  with gr.Blocks() as demo:
122
  gr.Markdown("### Breathe Training Application")
123
-
124
- # Input fields for setting inhale and exhale duration
125
- with gr.Row():
126
- inhale_duration = gr.Number(label="Inhale Duration (s)", value=4, min_value=1)
127
- exhale_duration = gr.Number(label="Exhale Duration (s)", value=4, min_value=1)
128
-
129
  with gr.Row():
130
  audio_input = gr.Audio(type="filepath", label="Upload or Record Audio")
131
  result_output = gr.Textbox(label="Prediction Results (Table)")
132
  waveform_output = gr.Image(label="Waveform with Highlighted Segments")
133
- countdown_output = gr.Textbox(label="Countdown Timer")
134
-
135
- submit_button = gr.Button("Start Record")
136
 
137
  submit_button.click(
138
  fn=process_audio,
139
- inputs=[audio_input, inhale_duration, exhale_duration],
140
- outputs=[result_output, waveform_output, countdown_output]
141
  )
142
 
143
  # Run the Gradio app
 
4
  import librosa.display
5
  import numpy as np
6
  import matplotlib.pyplot as plt
 
7
 
8
+ # Load the pre-trained model
9
  model = tf.keras.models.load_model("model.h5")
10
 
11
  # Function to process audio, predict, and generate results
12
+ def process_audio(audio_file):
13
  try:
14
  # Load the audio file
15
  y, sr = librosa.load(audio_file, sr=16000)
16
 
17
+ # Detect segments (e.g., using energy or silence)
18
+ intervals = librosa.effects.split(y, top_db=20)
19
+
20
+ results = []
21
+ highlighted_waveform = []
22
 
 
 
 
 
 
 
 
 
 
 
 
23
  plt.figure(figsize=(10, 4))
24
  librosa.display.waveshow(y, sr=sr, alpha=0.5)
25
+
26
+ # Process each segment
27
+ for i, (start, end) in enumerate(intervals):
28
  segment = y[start:end]
29
  duration = (end - start) / sr
30
+
31
+ # Extract MFCC features
32
+ mfcc = librosa.feature.mfcc(y=segment, sr=sr, n_mfcc=13)
33
+ mfcc = np.mean(mfcc, axis=1).reshape(1, -1)
34
+
35
+ # Predict inhale or exhale
36
+ prediction = model.predict(mfcc)
37
+ label = "Inhale" if np.argmax(prediction) == 0 else "Exhale"
38
+
39
+ # Append results
40
+ results.append({
41
+ "Segment": i + 1,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  "Type": label,
43
+ "Duration (s)": round(duration, 2)
 
 
 
44
  })
45
+
46
+ # Highlight segment on waveform
47
+ plt.axvspan(start / sr, end / sr, color='blue' if label == "Inhale" else 'red', alpha=0.3)
48
+
 
 
 
 
 
 
 
 
49
  # Save the waveform with highlighted segments
50
  plt.title("Audio Waveform with Inhale/Exhale Segments")
51
  plt.xlabel("Time (s)")
52
  plt.ylabel("Amplitude")
53
  plt.savefig("waveform_highlighted.png")
54
  plt.close()
55
+
56
  # Format results as a table
57
+ result_table = "Segment\tType\tDuration (s)\n" + "\n".join(
58
+ f"{row['Segment']}\t{row['Type']}\t{row['Duration (s)']}" for row in results
59
  )
 
 
 
 
 
 
 
 
 
 
 
60
 
61
+ return result_table, "waveform_highlighted.png"
 
 
 
 
 
 
62
 
63
  except Exception as e:
64
+ return f"Error: {str(e)}", None
 
65
 
66
  # Define Gradio interface
67
  with gr.Blocks() as demo:
68
  gr.Markdown("### Breathe Training Application")
 
 
 
 
 
 
69
  with gr.Row():
70
  audio_input = gr.Audio(type="filepath", label="Upload or Record Audio")
71
  result_output = gr.Textbox(label="Prediction Results (Table)")
72
  waveform_output = gr.Image(label="Waveform with Highlighted Segments")
73
+ submit_button = gr.Button("Analyze")
 
 
74
 
75
  submit_button.click(
76
  fn=process_audio,
77
+ inputs=[audio_input],
78
+ outputs=[result_output, waveform_output]
79
  )
80
 
81
  # Run the Gradio app