jens328 commited on
Commit
2711c10
·
verified ·
1 Parent(s): 735eee4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -41
app.py CHANGED
@@ -4,7 +4,7 @@ import librosa
4
  import numpy as np
5
 
6
  # ---------------------------------------------------------
7
- # 1. AUDIO-MODELL LADEN
8
  # ---------------------------------------------------------
9
 
10
  classifier = pipeline(
@@ -32,6 +32,8 @@ ENERGY_HOP_MS = 10 # Schrittweite (ms)
32
  ENERGY_QUANTILE = 0.80 # Lautheitsschwelle (oberes 20%-Quantil)
33
  MIN_EVENT_DURATION = 0.25 # min. Dauer eines lauten Events (Sek.)
34
 
 
 
35
  # ---------------------------------------------------------
36
  # 3. FUNKTION: LAUTE EVENTS FINDEN
37
  # ---------------------------------------------------------
@@ -82,35 +84,64 @@ def find_loud_events(y, sr):
82
  return events
83
 
84
  # ---------------------------------------------------------
85
- # 4. FUNKTION: BELL-PROBABILITÄT FÜR EIN EVENT
 
 
86
  # ---------------------------------------------------------
87
 
88
- def bark_probability_for_event(y, sr, start_s, end_s):
89
- start_idx = int(start_s * sr)
90
- end_idx = int(end_s * sr)
 
 
 
 
 
 
91
 
92
- segment = y[start_idx:end_idx]
 
 
93
 
94
- if len(segment) < int(0.15 * sr):
95
- return 0.0
 
 
 
 
 
 
 
 
96
 
97
- results = classifier(
98
- segment,
 
 
 
 
99
  candidate_labels=CANDIDATE_LABELS,
100
  multi_label=True,
 
101
  )
102
 
103
- for r in results:
104
- if r["label"].lower() == "dog barking":
105
- return float(r["score"])
 
 
 
 
 
 
106
 
107
- return 0.0
108
 
109
  # ---------------------------------------------------------
110
- # 5. HAUPT-ANALYSEFUNKTION (mit UI-Parametern)
111
  # ---------------------------------------------------------
112
 
113
- def analyze_barking(audio_path, max_pause_sec, bark_prob_threshold):
114
  # 0. Upload prüfen
115
  if audio_path is None or audio_path == "":
116
  return "Es wurde keine Audiodatei hochgeladen."
@@ -130,26 +161,29 @@ def analyze_barking(audio_path, max_pause_sec, bark_prob_threshold):
130
  if not loud_events:
131
  return "Keine lauten Ereignisse gefunden – vermutlich kein Bellen."
132
 
133
- # 3. Nur laute Events mit Modell prüfen
134
- bark_windows = []
135
- for (s, e) in loud_events:
136
- try:
137
- score = bark_probability_for_event(y, sr, s, e)
138
- except Exception as ex:
139
- print(f"Fehler im Modellaufruf bei {s:.2f}-{e:.2f}s: {ex}")
140
- continue
141
-
142
- if score >= bark_prob_threshold:
143
- bark_windows.append((s, e, score))
144
 
145
  if not bark_windows:
146
- return (
147
- "Es wurde kein Hundebellen mit ausreichend hoher Sicherheit erkannt.\n\n"
148
- f"(Schwellwert für 'dog barking' = {bark_prob_threshold:.2f})"
149
- )
 
 
 
 
 
 
150
 
151
- # 4. Episoden aus Bell-Segmenten bilden
152
- bark_windows.sort(key=lambda x: x[0])
153
 
154
  episodes = []
155
  cur_start, cur_end, _ = bark_windows[0]
@@ -168,6 +202,8 @@ def analyze_barking(audio_path, max_pause_sec, bark_prob_threshold):
168
  total_seconds = sum(e2 - e1 for (e1, e2) in episodes)
169
 
170
  lines = []
 
 
171
  lines.append(f"**A: Anzahl der Bell-Ereignisse:** {count}")
172
  lines.append(f"**B: Gesamtdauer des Bellens:** {total_seconds:.1f} Sekunden\n")
173
  lines.append(
@@ -182,7 +218,7 @@ def analyze_barking(audio_path, max_pause_sec, bark_prob_threshold):
182
  return "\n".join(lines)
183
 
184
  # ---------------------------------------------------------
185
- # 6. GRADIO UI – MIT SLIDERN
186
  # ---------------------------------------------------------
187
 
188
  audio_input = gr.Audio(type="filepath", label="Audio hochladen (.wav, .mp3)")
@@ -196,23 +232,29 @@ pause_slider = gr.Slider(
196
  )
197
 
198
  threshold_slider = gr.Slider(
199
- minimum=0.1,
200
  maximum=0.9,
201
  value=0.35,
202
- step=0.05,
203
  label="Schwellwert für 'dog barking' (0–1)",
204
  )
205
 
 
 
 
 
 
206
  demo = gr.Interface(
207
  fn=analyze_barking,
208
- inputs=[audio_input, pause_slider, threshold_slider],
209
  outputs=gr.Markdown(),
210
- title="Barking Episode Analyzer (mit Parametern)",
211
  description=(
212
  "Erkennt Hundebellen in Aufnahmen.\n\n"
213
- "Stell unten ein:\n"
214
- "- wie lang die Pause sein darf, bevor ein neues Ereignis gezählt wird,\n"
215
- "- ab welchem Schwellwert das Modell 'dog barking' als Bellen zählt."
 
216
  ),
217
  )
218
 
 
4
  import numpy as np
5
 
6
  # ---------------------------------------------------------
7
+ # 1. AUDIO-MODELL LADEN (für genaue Erkennung)
8
  # ---------------------------------------------------------
9
 
10
  classifier = pipeline(
 
32
  ENERGY_QUANTILE = 0.80 # Lautheitsschwelle (oberes 20%-Quantil)
33
  MIN_EVENT_DURATION = 0.25 # min. Dauer eines lauten Events (Sek.)
34
 
35
+ MIN_SEGMENT_FOR_CLAP = 0.15 # minimale Segmentlänge, damit CLAP Sinn macht (Sek.)
36
+
37
  # ---------------------------------------------------------
38
  # 3. FUNKTION: LAUTE EVENTS FINDEN
39
  # ---------------------------------------------------------
 
84
  return events
85
 
86
  # ---------------------------------------------------------
87
+ # 4. BELL-SEGMENTE ERKENNEN
88
+ # - entweder „fast mode“ (nur Energie)
89
+ # - oder CLAP-basiert, aber gebatcht
90
  # ---------------------------------------------------------
91
 
92
+ def detect_bark_windows(y, sr, loud_events, bark_prob_threshold, use_clap):
93
+ """
94
+ Gibt eine Liste von (start_s, end_s) zurück, die als Bellen gewertet werden.
95
+ Wenn use_clap=False: jedes laute Event = Bellen (reine Lautstärke-Logik).
96
+ Wenn use_clap=True: CLAP bewertet die Events.
97
+ """
98
+ if not use_clap:
99
+ # Fast Mode: alles, was laut ist, wird als Bellen gezählt
100
+ return [(s, e, 1.0) for (s, e) in loud_events]
101
 
102
+ # CLAP-Mode: wir batchen die Events für die Pipeline
103
+ segments = []
104
+ meta = [] # (start_s, end_s) zu jedem Segment
105
 
106
+ for (s, e) in loud_events:
107
+ if e - s < MIN_SEGMENT_FOR_CLAP:
108
+ continue
109
+ start_idx = int(s * sr)
110
+ end_idx = int(e * sr)
111
+ seg = y[start_idx:end_idx]
112
+ if len(seg) == 0:
113
+ continue
114
+ segments.append(seg)
115
+ meta.append((s, e))
116
 
117
+ if not segments:
118
+ return []
119
+
120
+ # Batch-Aufruf der Pipeline (deutlich schneller als Einzel-Aufrufe)
121
+ results_list = classifier(
122
+ segments,
123
  candidate_labels=CANDIDATE_LABELS,
124
  multi_label=True,
125
+ batch_size=4,
126
  )
127
 
128
+ bark_windows = []
129
+ for (s, e), results in zip(meta, results_list):
130
+ bark_score = 0.0
131
+ for r in results:
132
+ if r["label"].lower() == "dog barking":
133
+ bark_score = float(r["score"])
134
+ break
135
+ if bark_score >= bark_prob_threshold:
136
+ bark_windows.append((s, e, bark_score))
137
 
138
+ return bark_windows
139
 
140
  # ---------------------------------------------------------
141
+ # 5. HAUPT-ANALYSEFUNKTION
142
  # ---------------------------------------------------------
143
 
144
+ def analyze_barking(audio_path, max_pause_sec, bark_prob_threshold, fast_mode):
145
  # 0. Upload prüfen
146
  if audio_path is None or audio_path == "":
147
  return "Es wurde keine Audiodatei hochgeladen."
 
161
  if not loud_events:
162
  return "Keine lauten Ereignisse gefunden – vermutlich kein Bellen."
163
 
164
+ # 3. Bellen-Segmente finden
165
+ bark_windows = detect_bark_windows(
166
+ y,
167
+ sr,
168
+ loud_events,
169
+ bark_prob_threshold,
170
+ use_clap=not fast_mode
171
+ )
 
 
 
172
 
173
  if not bark_windows:
174
+ if fast_mode:
175
+ return (
176
+ "Fast Mode (ohne KI): keine ausreichend lauten Ereignisse, "
177
+ "die als Bellen interpretiert wurden."
178
+ )
179
+ else:
180
+ return (
181
+ "Es wurde kein Hundebellen mit ausreichend hoher Sicherheit erkannt.\n\n"
182
+ f"(Schwellwert für 'dog barking' = {bark_prob_threshold:.2f})"
183
+ )
184
 
185
+ # 4. Bell-Segmente zu Episoden zusammenfassen
186
+ bark_windows.sort(key=lambda x: x[0]) # nach Startzeit
187
 
188
  episodes = []
189
  cur_start, cur_end, _ = bark_windows[0]
 
202
  total_seconds = sum(e2 - e1 for (e1, e2) in episodes)
203
 
204
  lines = []
205
+ mode_text = "Fast Mode (nur Energie)" if fast_mode else "CLAP-KI-Modus"
206
+ lines.append(f"**Modus:** {mode_text}")
207
  lines.append(f"**A: Anzahl der Bell-Ereignisse:** {count}")
208
  lines.append(f"**B: Gesamtdauer des Bellens:** {total_seconds:.1f} Sekunden\n")
209
  lines.append(
 
218
  return "\n".join(lines)
219
 
220
  # ---------------------------------------------------------
221
+ # 6. GRADIO UI – MIT SLIDERN & FAST-MODE
222
  # ---------------------------------------------------------
223
 
224
  audio_input = gr.Audio(type="filepath", label="Audio hochladen (.wav, .mp3)")
 
232
  )
233
 
234
  threshold_slider = gr.Slider(
235
+ minimum=0.01,
236
  maximum=0.9,
237
  value=0.35,
238
+ step=0.01,
239
  label="Schwellwert für 'dog barking' (0–1)",
240
  )
241
 
242
+ fast_checkbox = gr.Checkbox(
243
+ value=False,
244
+ label="Fast Mode (nur Lautstärke, ohne KI-Modell – sehr schnell, aber ungenauer)",
245
+ )
246
+
247
  demo = gr.Interface(
248
  fn=analyze_barking,
249
+ inputs=[audio_input, pause_slider, threshold_slider, fast_checkbox],
250
  outputs=gr.Markdown(),
251
+ title="Barking Episode Analyzer (mit Parametern & Fast Mode)",
252
  description=(
253
  "Erkennt Hundebellen in Aufnahmen.\n\n"
254
+ "Optionen:\n"
255
+ "- **Maximale Pause**: ab welcher Pause ein neues Bell-Ereignis gezählt wird.\n"
256
+ "- **Schwellwert**: ab welcher Wahrscheinlichkeit 'dog barking' gezählt wird.\n"
257
+ "- **Fast Mode**: nur Lautstärke-Analyse (schnell), ohne 'dog barking'-Modell."
258
  ),
259
  )
260