csprojectworkspace commited on
Commit
08855d8
·
verified ·
1 Parent(s): ce00c49

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -28
app.py CHANGED
@@ -12,32 +12,35 @@ CORS(app)
12
  MODEL_PATH = "CRNN_model_final.h5"
13
 
14
  print("Chargement du modele CRNN...")
15
- model = tf.keras.models.load_model(MODEL_PATH)
16
  print("Modele charge!")
17
  print(f"Input shape: {model.input_shape}")
18
  print(f"Output shape: {model.output_shape}")
19
 
20
- def extract_mfcc(audio, sr, n_mfcc=13):
21
- mfccs = librosa.feature.mfcc(y=audio, sr=sr, n_mfcc=n_mfcc)
22
- mfccs = (mfccs - np.mean(mfccs)) / (np.std(mfccs) + 1e-8)
23
- return mfccs
24
 
25
  def predict_vad(audio, sr):
26
- mfccs = extract_mfcc(audio, sr, n_mfcc=13)
27
- features = mfccs.T
28
- features = np.expand_dims(features, axis=0)
 
 
 
 
 
 
 
 
 
 
29
 
30
  prediction = model.predict(features, verbose=0)
 
 
31
 
32
- if prediction.shape[-1] == 2:
33
- confidence = float(np.max(prediction))
34
- label = "voice" if np.argmax(prediction) == 1 else "silence"
35
- else:
36
- confidence = float(prediction[0][0])
37
- label = "voice" if confidence > 0.5 else "silence"
38
- confidence = confidence if label == "voice" else 1 - confidence
39
 
40
- return label, confidence
41
 
42
  @app.after_request
43
  def after_request(response):
@@ -54,7 +57,7 @@ def home():
54
  def health():
55
  if request.method == 'OPTIONS':
56
  return make_response('', 204)
57
- return jsonify({'status': 'ok', 'model': 'CRNN VAD + GCC-PHAT DOA'})
58
 
59
  @app.route('/api/analyze', methods=['POST', 'OPTIONS'])
60
  def analyze():
@@ -75,38 +78,39 @@ def analyze():
75
 
76
  n_channels = y.shape[0] if y.ndim > 1 else 1
77
  duration = y.shape[-1] / sr
78
- n_frames = max(1, int(duration * 10))
79
 
80
- vad_label, vad_confidence = predict_vad(y_mono, sr)
 
 
 
81
 
82
- frame_length = len(y_mono) // n_frames
83
  vad_timeline = []
84
  for i in range(n_frames):
85
- start_sample = i * frame_length
86
- end_sample = min((i + 1) * frame_length, len(y_mono))
87
  frame_audio = y_mono[start_sample:end_sample]
88
 
89
- if len(frame_audio) > sr * 0.05:
90
- frame_label, frame_conf = predict_vad(frame_audio, sr)
91
  else:
92
  frame_label, frame_conf = vad_label, vad_confidence
93
 
94
  vad_timeline.append({
95
- 'start': round(i * 0.1, 2),
96
- 'end': round((i + 1) * 0.1, 2),
97
  'label': frame_label,
98
  'confidence': round(frame_conf, 3)
99
  })
100
 
101
  doa_angle = -25.5 + np.random.randn() * 10
102
- doa_trajectory = [{'time': round(i*0.1,2), 'angle': round(doa_angle + np.random.randn()*3, 1)} for i in range(n_frames)]
103
 
104
  voice_ratio = sum(1 for f in vad_timeline if f['label'] == 'voice') / len(vad_timeline)
105
 
106
  return jsonify({
107
  'success': True,
108
  'metadata': {'channels': int(n_channels), 'sampleRate': int(sr), 'duration': round(duration, 2), 'samples': int(y.shape[-1])},
109
- 'vad': {'prediction': vad_label, 'confidence': round(vad_confidence, 3), 'timeline': vad_timeline},
110
  'doa': {'angle': round(doa_angle, 1), 'confidence': 0.89, 'trajectory': doa_trajectory},
111
  'metrics': {'snr': round(10 * np.log10(np.mean(y_mono**2) / 1e-10), 1), 'voiceRatio': round(voice_ratio, 2), 'meanDoa': round(np.mean([d['angle'] for d in doa_trajectory]), 1)}
112
  })
 
12
  MODEL_PATH = "CRNN_model_final.h5"
13
 
14
  print("Chargement du modele CRNN...")
15
+ model = tf.keras.models.load_model(MODEL_PATH, compile=False)
16
  print("Modele charge!")
17
  print(f"Input shape: {model.input_shape}")
18
  print(f"Output shape: {model.output_shape}")
19
 
20
+ SILENCE_CLASSES = [13, 14]
 
 
 
21
 
22
  def predict_vad(audio, sr):
23
+ if sr != 16000:
24
+ audio = librosa.resample(audio, orig_sr=sr, target_sr=16000)
25
+
26
+ target_length = 1024
27
+
28
+ if len(audio) < target_length:
29
+ audio = np.pad(audio, (0, target_length - len(audio)), mode='constant')
30
+ elif len(audio) > target_length:
31
+ start = (len(audio) - target_length) // 2
32
+ audio = audio[start:start + target_length]
33
+
34
+ audio = audio / (np.max(np.abs(audio)) + 1e-8)
35
+ features = audio.reshape(1, target_length, 1)
36
 
37
  prediction = model.predict(features, verbose=0)
38
+ predicted_class = int(np.argmax(prediction[0]))
39
+ confidence = float(np.max(prediction[0]))
40
 
41
+ label = "silence" if predicted_class in SILENCE_CLASSES else "voice"
 
 
 
 
 
 
42
 
43
+ return label, confidence, predicted_class
44
 
45
  @app.after_request
46
  def after_request(response):
 
57
  def health():
58
  if request.method == 'OPTIONS':
59
  return make_response('', 204)
60
+ return jsonify({'status': 'ok', 'model': 'CRNN VAD'})
61
 
62
  @app.route('/api/analyze', methods=['POST', 'OPTIONS'])
63
  def analyze():
 
78
 
79
  n_channels = y.shape[0] if y.ndim > 1 else 1
80
  duration = y.shape[-1] / sr
 
81
 
82
+ vad_label, vad_confidence, pred_class = predict_vad(y_mono, sr)
83
+
84
+ frame_size = 1024
85
+ n_frames = max(1, len(y_mono) // frame_size)
86
 
 
87
  vad_timeline = []
88
  for i in range(n_frames):
89
+ start_sample = i * frame_size
90
+ end_sample = min(start_sample + frame_size, len(y_mono))
91
  frame_audio = y_mono[start_sample:end_sample]
92
 
93
+ if len(frame_audio) >= 256:
94
+ frame_label, frame_conf, _ = predict_vad(frame_audio, sr)
95
  else:
96
  frame_label, frame_conf = vad_label, vad_confidence
97
 
98
  vad_timeline.append({
99
+ 'start': round(start_sample / sr, 3),
100
+ 'end': round(end_sample / sr, 3),
101
  'label': frame_label,
102
  'confidence': round(frame_conf, 3)
103
  })
104
 
105
  doa_angle = -25.5 + np.random.randn() * 10
106
+ doa_trajectory = [{'time': round(i * (duration/n_frames), 2), 'angle': round(doa_angle + np.random.randn()*3, 1)} for i in range(n_frames)]
107
 
108
  voice_ratio = sum(1 for f in vad_timeline if f['label'] == 'voice') / len(vad_timeline)
109
 
110
  return jsonify({
111
  'success': True,
112
  'metadata': {'channels': int(n_channels), 'sampleRate': int(sr), 'duration': round(duration, 2), 'samples': int(y.shape[-1])},
113
+ 'vad': {'prediction': vad_label, 'confidence': round(vad_confidence, 3), 'predicted_class': pred_class, 'timeline': vad_timeline},
114
  'doa': {'angle': round(doa_angle, 1), 'confidence': 0.89, 'trajectory': doa_trajectory},
115
  'metrics': {'snr': round(10 * np.log10(np.mean(y_mono**2) / 1e-10), 1), 'voiceRatio': round(voice_ratio, 2), 'meanDoa': round(np.mean([d['angle'] for d in doa_trajectory]), 1)}
116
  })