jens328 commited on
Commit
1200cd9
·
verified ·
1 Parent(s): b90cffc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +105 -33
app.py CHANGED
@@ -1,46 +1,118 @@
1
  import gradio as gr
2
  from transformers import pipeline
 
 
3
 
4
- # Zero-shot Audio Classifier mit CLAP
5
  classifier = pipeline(
6
  task="zero-shot-audio-classification",
7
  model="laion/clap-htsat-unfused"
8
  )
9
 
10
- # Unsere interessanten Geräusch-Kategorien
11
- CANDIDATE_LABELS = [
12
- "dog barking",
13
- "dog growling",
14
- "people talking",
15
- "traffic noise",
16
- "car passing",
17
- "bird singing",
18
- "music",
19
- "wind",
20
- "rain",
21
- "silence"
22
- ]
23
-
24
- def classify(audio_file_path):
25
- """
26
- audio_file_path ist ein Dateipfad, weil wir Gradio mit type='filepath' benutzen.
27
- """
28
- results = classifier(
29
- audio_file_path,
30
- candidate_labels=CANDIDATE_LABELS,
31
- multi_label=True # mehrere Geräusche gleichzeitig möglich
32
- )
33
-
34
- # In ein Dictionary Label -> Score umwandeln
35
- return {r["label"]: float(r["score"]) for r in results}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  demo = gr.Interface(
38
- fn=classify,
39
- inputs=gr.Audio(type="filepath", label="Audio hochladen"),
40
- outputs=gr.Label(num_top_classes=5, label="Erkannte Geräusche"),
41
- title="Barking Detection (CLAP Zero-Shot)",
42
- description="Lade eine Aufnahme hoch. Das Modell schätzt u.a., ob ein Hund bellt."
 
 
 
 
 
 
 
43
  )
44
 
45
- if __name__ == "__main__":
46
  demo.launch()
 
1
  import gradio as gr
2
  from transformers import pipeline
3
+ import librosa
4
+ import numpy as np
5
 
6
+ # Zero-shot Audio Classifier (CLAP)
7
  classifier = pipeline(
8
  task="zero-shot-audio-classification",
9
  model="laion/clap-htsat-unfused"
10
  )
11
 
12
+ # Wir interessieren uns nur für "dog barking"
13
+ DOG_LABEL = "dog barking"
14
+
15
+ # Parameter für die Analyse
16
+ WINDOW_SECONDS = 1.5 # Länge eines Analysefensters
17
+ HOP_SECONDS = 0.75 # Schrittweite zwischen Fenstern
18
+ BARK_THRESHOLD = 0.5 # Ab welcher Wahrscheinlichkeit gilt das Fenster als "bellen"
19
+ MAX_PAUSE_BETWEEN_BARKS = 3.0 # >3 s Pause = neues Bell-Ereignis
20
+
21
+
22
+ def analyze_barking(audio_path):
23
+ # Audio laden (Mono, 16 kHz)
24
+ y, sr = librosa.load(audio_path, sr=16000, mono=True)
25
+ duration = len(y) / sr
26
+
27
+ if duration == 0:
28
+ return "Keine gültige Audiodatei."
29
+
30
+ bark_windows = []
31
+
32
+ # Überlappende Fenster über die gesamte Aufnahme schieben
33
+ t = 0.0
34
+ while t < duration:
35
+ start = t
36
+ end = min(t + WINDOW_SECONDS, duration)
37
+ start_idx = int(start * sr)
38
+ end_idx = int(end * sr)
39
+ segment = y[start_idx:end_idx]
40
+
41
+ # Leere / extrem leise Segmente überspringen
42
+ if len(segment) == 0 or np.mean(np.abs(segment)) < 1e-4:
43
+ t += HOP_SECONDS
44
+ continue
45
+
46
+ # CLAP auf dieses Segment anwenden
47
+ result = classifier(
48
+ {"array": segment, "sampling_rate": sr},
49
+ candidate_labels=[DOG_LABEL],
50
+ multi_label=False
51
+ )
52
+
53
+ score = result[0]["score"] # Wahrscheinlichkeit für "dog barking"
54
+
55
+ if score >= BARK_THRESHOLD:
56
+ # Dieses Fenster als "Bellen" markieren
57
+ bark_windows.append((start, end))
58
+
59
+ t += HOP_SECONDS
60
+
61
+ if not bark_windows:
62
+ return "Es wurde kein deutliches Hundebellen erkannt (über Schwellwert)."
63
+
64
+ # Fenster zu Episoden zusammenfassen:
65
+ # Wenn zwischen Fenstern > MAX_PAUSE_BETWEEN_BARKS Sekunden Pause ist,
66
+ # startet eine neue Bell-Episode.
67
+ episodes = []
68
+ current_start, current_end = bark_windows[0]
69
+
70
+ for start, end in bark_windows[1:]:
71
+ if start - current_end <= MAX_PAUSE_BETWEEN_BARKS:
72
+ # Gleiches Bell-Ereignis, wir verlängern das Ende
73
+ current_end = max(current_end, end)
74
+ else:
75
+ # Neues Bell-Ereignis
76
+ episodes.append((current_start, current_end))
77
+ current_start, current_end = start, end
78
+
79
+ # Letzte Episode hinzufügen
80
+ episodes.append((current_start, current_end))
81
+
82
+ # Kennzahlen berechnen
83
+ count_episodes = len(episodes)
84
+ total_bark_duration = sum(e_end - e_start for e_start, e_end in episodes)
85
+
86
+ # Schöne Textausgabe bauen
87
+ lines = []
88
+ lines.append(f"**A: Anzahl der Bell-Ereignisse:** {count_episodes}")
89
+ lines.append(f"**B: Gesamtdauer des Bellens:** {total_bark_duration:.1f} Sekunden")
90
+
91
+ lines.append("\n**Details je Bell-Ereignis:**")
92
+ for i, (e_start, e_end) in enumerate(episodes, start=1):
93
+ dur = e_end - e_start
94
+ lines.append(
95
+ f"- Ereignis {i}: von {e_start:.1f}s bis {e_end:.1f}s "
96
+ f"→ Dauer: {dur:.1f}s"
97
+ )
98
+
99
+ return "\n".join(lines)
100
+
101
 
102
  demo = gr.Interface(
103
+ fn=analyze_barking,
104
+ inputs=gr.Audio(type="filepath", label="Audio hochladen (.wav, .mp3)"),
105
+ outputs=gr.Markdown(),
106
+ title="Barking Episode Analyzer",
107
+ description=(
108
+ "Analysiert Hundebellen in einer Aufnahme.\n\n"
109
+ "Regeln:\n"
110
+ "- Bellen wird in Zeitfenstern erkannt.\n"
111
+ "- Wenn länger als 3 Sekunden Pause zwischen Bell-Fenstern ist, "
112
+ "gilt das als neues Bell-Ereignis.\n"
113
+ "- Ausgabe: Anzahl der Ereignisse (A) und Gesamtdauer des Bellens (B)."
114
+ ),
115
  )
116
 
117
+ if __name__ == '__main__':
118
  demo.launch()