csprojectworkspace commited on
Commit
4c94e8e
·
verified ·
1 Parent(s): 2402bcb

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -0
app.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify, make_response
2
+ from flask_cors import CORS
3
+ import numpy as np
4
+ import librosa
5
+ import io
6
+ import os
7
+
8
+ app = Flask(__name__)
9
+ CORS(app, resources={r"/api/*": {"origins": "*"}})
10
+
11
+ @app.after_request
12
+ def after_request(response):
13
+ response.headers.add('Access-Control-Allow-Origin', '*')
14
+ response.headers.add('Access-Control-Allow-Headers', '*')
15
+ response.headers.add('Access-Control-Allow-Methods', 'GET,POST,OPTIONS')
16
+ return response
17
+
18
+ @app.route('/', methods=['GET'])
19
+ def home():
20
+ return jsonify({'message': 'AcoustiTrack API - CNN-1D VAD + GCC-PHAT DOA', 'status': 'running'})
21
+
22
+ @app.route('/api/health', methods=['GET', 'OPTIONS'])
23
+ def health():
24
+ if request.method == 'OPTIONS':
25
+ return make_response('', 204)
26
+ return jsonify({'status': 'ok', 'model': 'CNN-1D VAD + GCC-PHAT DOA'})
27
+
28
+ @app.route('/api/analyze', methods=['POST', 'OPTIONS'])
29
+ def analyze():
30
+ if request.method == 'OPTIONS':
31
+ return make_response('', 204)
32
+ try:
33
+ if 'audio' not in request.files:
34
+ return jsonify({'error': 'Aucun fichier audio'}), 400
35
+
36
+ audio_file = request.files['audio']
37
+ audio_bytes = audio_file.read()
38
+
39
+ y, sr = librosa.load(io.BytesIO(audio_bytes), sr=16000, mono=False)
40
+
41
+ if y.ndim == 1:
42
+ y = np.tile(y, (4, 1))
43
+
44
+ n_channels = y.shape[0] if y.ndim > 1 else 1
45
+ duration = y.shape[-1] / sr
46
+
47
+ # ============================================
48
+ # VOTRE MODELE CNN-1D ICI
49
+ # Chargez votre modele et faites l'inference
50
+ # ============================================
51
+ vad_prediction = "voice"
52
+ vad_confidence = 0.962
53
+ doa_angle = -25.5
54
+
55
+ n_frames = max(1, int(duration * 10))
56
+ vad_timeline = []
57
+ for i in range(n_frames):
58
+ vad_timeline.append({
59
+ 'start': round(i * 0.1, 2),
60
+ 'end': round((i + 1) * 0.1, 2),
61
+ 'label': 'voice' if np.random.random() > 0.3 else 'silence',
62
+ 'confidence': round(0.85 + np.random.random() * 0.15, 3)
63
+ })
64
+
65
+ doa_trajectory = []
66
+ for i in range(n_frames):
67
+ doa_trajectory.append({
68
+ 'time': round(i * 0.1, 2),
69
+ 'angle': round(doa_angle + np.random.randn() * 5, 1)
70
+ })
71
+
72
+ voice_frames = sum(1 for f in vad_timeline if f['label'] == 'voice')
73
+
74
+ return jsonify({
75
+ 'success': True,
76
+ 'metadata': {
77
+ 'channels': int(n_channels),
78
+ 'sampleRate': int(sr),
79
+ 'duration': round(duration, 2),
80
+ 'samples': int(y.shape[-1])
81
+ },
82
+ 'vad': {
83
+ 'prediction': vad_prediction,
84
+ 'confidence': vad_confidence,
85
+ 'timeline': vad_timeline
86
+ },
87
+ 'doa': {
88
+ 'angle': doa_angle,
89
+ 'confidence': 0.89,
90
+ 'trajectory': doa_trajectory
91
+ },
92
+ 'metrics': {
93
+ 'snr': 18.5,
94
+ 'voiceRatio': round(voice_frames / len(vad_timeline), 2),
95
+ 'meanDoa': round(float(np.mean([d['angle'] for d in doa_trajectory])), 1)
96
+ }
97
+ })
98
+ except Exception as e:
99
+ return jsonify({'error': str(e)}), 500
100
+
101
+ if __name__ == '__main__':
102
+ port = int(os.environ.get('PORT', 7860))
103
+ app.run(host='0.0.0.0', port=port)