mulasagg commited on
Commit
1f9e7fa
·
1 Parent(s): e3ea1e9

add fillerscore

Browse files
Files changed (1) hide show
  1. filler_count/filler_score.py +61 -9
filler_count/filler_score.py CHANGED
@@ -1,24 +1,76 @@
1
  import re
2
  import whisper
 
3
 
4
  def analyze_fillers(file_path: str, model_size: str = "base") -> dict:
 
 
 
5
  try:
6
- FILLER_WORDS = ["um", "uh", "hmm", "ah", "er", "eh", "like", "you know", "well"]
 
 
 
 
 
7
 
 
 
 
 
 
8
  model = whisper.load_model(model_size)
9
  result = model.transcribe(file_path, word_timestamps=False, fp16=False)
10
  transcript = result["text"]
11
 
12
- pattern = r"\b(" + "|".join(FILLER_WORDS) + r")\b"
13
- matches = re.findall(pattern, transcript.lower())
 
14
 
15
- filler_counts = {filler: matches.count(filler) for filler in FILLER_WORDS}
 
 
 
 
16
  total_fillers = sum(filler_counts.values())
17
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  return {
19
- # "transcript": transcript,
20
- "filler_counts": {k: v for k, v in filler_counts.items() if v > 0},
21
- "total_fillers": total_fillers
 
22
  }
 
23
  except Exception as e:
24
- raise RuntimeError(f"Error during analysis: {str(e)}")
 
1
  import re
2
  import whisper
3
+ from pydub import AudioSegment # For accurate duration calculation
4
 
5
  def analyze_fillers(file_path: str, model_size: str = "base") -> dict:
6
+ """
7
+ Analyzes English filler words in audio with proper duration handling.
8
+ """
9
  try:
10
+ FILLER_WORDS = [
11
+ "um", "uh", "hmm", "ah", "er", "eh",
12
+ "umm", "uhh", "mmm", "ahh", "err",
13
+ "like", "you know", "well", "so", "actually", "basically",
14
+ "right", "okay", "sort of", "kind of"
15
+ ]
16
 
17
+ # First get accurate duration using pydub
18
+ audio = AudioSegment.from_file(file_path)
19
+ duration = len(audio) / 1000 # Convert ms to seconds
20
+
21
+ # Then run Whisper transcription
22
  model = whisper.load_model(model_size)
23
  result = model.transcribe(file_path, word_timestamps=False, fp16=False)
24
  transcript = result["text"]
25
 
26
+ # Case-insensitive regex matching
27
+ pattern = r"(?<!\w)(" + "|".join(map(re.escape, FILLER_WORDS)) + r")(?!\w)"
28
+ matches = re.findall(pattern, transcript, re.IGNORECASE)
29
 
30
+ # Count occurrences
31
+ filler_counts = {}
32
+ for word in matches:
33
+ key = word.lower()
34
+ filler_counts[key] = filler_counts.get(key, 0) + 1
35
  total_fillers = sum(filler_counts.values())
36
+
37
+ # Calculate rate per minute
38
+ filler_per_min = (total_fillers / duration) * 60 if duration > 0 else 0
39
+
40
+ # Scoring
41
+ if total_fillers == 0:
42
+ filler_score = 100
43
+ elif filler_per_min < 1:
44
+ filler_score = 90
45
+ elif filler_per_min < 3:
46
+ filler_score = 80
47
+ elif filler_per_min < 5:
48
+ filler_score = 60
49
+ elif filler_per_min < 10:
50
+ filler_score = 40
51
+ else:
52
+ filler_score = 20
53
+
54
+ # Generate insight
55
+ top_fillers = sorted(filler_counts.items(), key=lambda x: x[1], reverse=True)[:2]
56
+
57
+ if total_fillers == 0:
58
+ insight = "Excellent! No filler words detected."
59
+ elif total_fillers <= 2:
60
+ insight = f"Minimal fillers ({total_fillers} total), mostly '{top_fillers[0][0]}'."
61
+ elif total_fillers <= 5:
62
+ examples = ", ".join(f"'{f[0]}'" for f in top_fillers)
63
+ insight = f"Moderate fillers ({total_fillers} total), mainly {examples}."
64
+ else:
65
+ examples = ", ".join(f"'{f[0]}'" for f in top_fillers)
66
+ insight = f"Excessive fillers ({total_fillers} total), dominated by {examples}."
67
+
68
  return {
69
+ "filler_counts": filler_counts,
70
+ "total_fillers": total_fillers,
71
+ "filler_score": filler_score,
72
+ "filler_rate_per_min": round(filler_per_min, 1),
73
  }
74
+
75
  except Exception as e:
76
+ raise RuntimeError(f"Analysis failed: {str(e)}")