alaatiger989 commited on
Commit
9a199b4
·
verified ·
1 Parent(s): fc64a78

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +180 -0
  2. Downloading model.txt +1 -0
  3. app.py +414 -0
  4. app_api.py +306 -0
  5. app_api_2.py +490 -0
  6. arabic_recording.wav +3 -0
  7. creating env.txt +26 -0
  8. main.py +24 -0
  9. nid.wav +3 -0
  10. pn.wav +3 -0
  11. recordings/case_name_20250909_144019.wav +3 -0
  12. recordings/case_name_20250909_144453.wav +3 -0
  13. recordings/case_name_20250909_155450.wav +3 -0
  14. recordings/case_name_20250909_155812.wav +3 -0
  15. recordings/case_name_20250909_155921.wav +3 -0
  16. recordings/case_name_20250909_170323.wav +3 -0
  17. recordings/case_name_20250909_170702.wav +3 -0
  18. recordings/case_name_20250924_200610.wav +3 -0
  19. recordings/name_20250909_143929.wav +3 -0
  20. recordings/name_20250909_143955.wav +3 -0
  21. recordings/name_20250909_144405.wav +3 -0
  22. recordings/name_20250909_144432.wav +3 -0
  23. recordings/name_20250909_155412.wav +3 -0
  24. recordings/name_20250909_155430.wav +3 -0
  25. recordings/name_20250909_155755.wav +3 -0
  26. recordings/name_20250909_155905.wav +3 -0
  27. recordings/name_20250909_170307.wav +3 -0
  28. recordings/name_20250909_170647.wav +3 -0
  29. recordings/name_20250924_200542.wav +3 -0
  30. recordings/name_20250924_202837.wav +3 -0
  31. recordings/nid_20250909_142059.wav +3 -0
  32. recordings/nid_20250909_143513.wav +3 -0
  33. recordings/nid_20250909_143739.wav +3 -0
  34. recordings/nid_20250909_143835.wav +3 -0
  35. recordings/nid_20250909_143901.wav +3 -0
  36. recordings/nid_20250909_144232.wav +3 -0
  37. recordings/nid_20250909_144254.wav +3 -0
  38. recordings/nid_20250909_144321.wav +3 -0
  39. recordings/nid_20250909_144751.wav +3 -0
  40. recordings/nid_20250909_144821.wav +3 -0
  41. recordings/nid_20250909_144845.wav +3 -0
  42. recordings/nid_20250909_155231.wav +3 -0
  43. recordings/nid_20250909_155548.wav +3 -0
  44. recordings/nid_20250909_155608.wav +3 -0
  45. recordings/nid_20250909_155738.wav +3 -0
  46. recordings/nid_20250909_155849.wav +3 -0
  47. recordings/nid_20250909_165246.wav +3 -0
  48. recordings/nid_20250909_165306.wav +3 -0
  49. recordings/nid_20250909_165751.wav +3 -0
  50. recordings/nid_20250909_165824.wav +3 -0
.gitattributes CHANGED
@@ -33,3 +33,183 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ arabic_recording.wav filter=lfs diff=lfs merge=lfs -text
37
+ nid.wav filter=lfs diff=lfs merge=lfs -text
38
+ pn.wav filter=lfs diff=lfs merge=lfs -text
39
+ recordings/case_name_20250909_144019.wav filter=lfs diff=lfs merge=lfs -text
40
+ recordings/case_name_20250909_144453.wav filter=lfs diff=lfs merge=lfs -text
41
+ recordings/case_name_20250909_155450.wav filter=lfs diff=lfs merge=lfs -text
42
+ recordings/case_name_20250909_155812.wav filter=lfs diff=lfs merge=lfs -text
43
+ recordings/case_name_20250909_155921.wav filter=lfs diff=lfs merge=lfs -text
44
+ recordings/case_name_20250909_170323.wav filter=lfs diff=lfs merge=lfs -text
45
+ recordings/case_name_20250909_170702.wav filter=lfs diff=lfs merge=lfs -text
46
+ recordings/case_name_20250924_200610.wav filter=lfs diff=lfs merge=lfs -text
47
+ recordings/name_20250909_143929.wav filter=lfs diff=lfs merge=lfs -text
48
+ recordings/name_20250909_143955.wav filter=lfs diff=lfs merge=lfs -text
49
+ recordings/name_20250909_144405.wav filter=lfs diff=lfs merge=lfs -text
50
+ recordings/name_20250909_144432.wav filter=lfs diff=lfs merge=lfs -text
51
+ recordings/name_20250909_155412.wav filter=lfs diff=lfs merge=lfs -text
52
+ recordings/name_20250909_155430.wav filter=lfs diff=lfs merge=lfs -text
53
+ recordings/name_20250909_155755.wav filter=lfs diff=lfs merge=lfs -text
54
+ recordings/name_20250909_155905.wav filter=lfs diff=lfs merge=lfs -text
55
+ recordings/name_20250909_170307.wav filter=lfs diff=lfs merge=lfs -text
56
+ recordings/name_20250909_170647.wav filter=lfs diff=lfs merge=lfs -text
57
+ recordings/name_20250924_200542.wav filter=lfs diff=lfs merge=lfs -text
58
+ recordings/name_20250924_202837.wav filter=lfs diff=lfs merge=lfs -text
59
+ recordings/nid_20250909_142059.wav filter=lfs diff=lfs merge=lfs -text
60
+ recordings/nid_20250909_143513.wav filter=lfs diff=lfs merge=lfs -text
61
+ recordings/nid_20250909_143739.wav filter=lfs diff=lfs merge=lfs -text
62
+ recordings/nid_20250909_143835.wav filter=lfs diff=lfs merge=lfs -text
63
+ recordings/nid_20250909_143901.wav filter=lfs diff=lfs merge=lfs -text
64
+ recordings/nid_20250909_144232.wav filter=lfs diff=lfs merge=lfs -text
65
+ recordings/nid_20250909_144254.wav filter=lfs diff=lfs merge=lfs -text
66
+ recordings/nid_20250909_144321.wav filter=lfs diff=lfs merge=lfs -text
67
+ recordings/nid_20250909_144751.wav filter=lfs diff=lfs merge=lfs -text
68
+ recordings/nid_20250909_144821.wav filter=lfs diff=lfs merge=lfs -text
69
+ recordings/nid_20250909_144845.wav filter=lfs diff=lfs merge=lfs -text
70
+ recordings/nid_20250909_155231.wav filter=lfs diff=lfs merge=lfs -text
71
+ recordings/nid_20250909_155548.wav filter=lfs diff=lfs merge=lfs -text
72
+ recordings/nid_20250909_155608.wav filter=lfs diff=lfs merge=lfs -text
73
+ recordings/nid_20250909_155738.wav filter=lfs diff=lfs merge=lfs -text
74
+ recordings/nid_20250909_155849.wav filter=lfs diff=lfs merge=lfs -text
75
+ recordings/nid_20250909_165246.wav filter=lfs diff=lfs merge=lfs -text
76
+ recordings/nid_20250909_165306.wav filter=lfs diff=lfs merge=lfs -text
77
+ recordings/nid_20250909_165751.wav filter=lfs diff=lfs merge=lfs -text
78
+ recordings/nid_20250909_165824.wav filter=lfs diff=lfs merge=lfs -text
79
+ recordings/nid_20250909_170138.wav filter=lfs diff=lfs merge=lfs -text
80
+ recordings/nid_20250909_170225.wav filter=lfs diff=lfs merge=lfs -text
81
+ recordings/nid_20250909_170249.wav filter=lfs diff=lfs merge=lfs -text
82
+ recordings/nid_20250909_170454.wav filter=lfs diff=lfs merge=lfs -text
83
+ recordings/nid_20250909_170510.wav filter=lfs diff=lfs merge=lfs -text
84
+ recordings/nid_20250909_170525.wav filter=lfs diff=lfs merge=lfs -text
85
+ recordings/nid_20250909_170628.wav filter=lfs diff=lfs merge=lfs -text
86
+ recordings/nid_20250909_171108.wav filter=lfs diff=lfs merge=lfs -text
87
+ recordings/nid_20250909_171128.wav filter=lfs diff=lfs merge=lfs -text
88
+ recordings/nid_20250909_171143.wav filter=lfs diff=lfs merge=lfs -text
89
+ recordings/nid_20250909_171403.wav filter=lfs diff=lfs merge=lfs -text
90
+ recordings/nid_20250909_172000.wav filter=lfs diff=lfs merge=lfs -text
91
+ recordings/nid_20250909_172022.wav filter=lfs diff=lfs merge=lfs -text
92
+ recordings/nid_20250909_172037.wav filter=lfs diff=lfs merge=lfs -text
93
+ recordings/nid_20250909_172215.wav filter=lfs diff=lfs merge=lfs -text
94
+ recordings/nid_20250924_190026.wav filter=lfs diff=lfs merge=lfs -text
95
+ recordings/nid_20250924_190048.wav filter=lfs diff=lfs merge=lfs -text
96
+ recordings/nid_20250924_190113.wav filter=lfs diff=lfs merge=lfs -text
97
+ recordings/nid_20250924_190139.wav filter=lfs diff=lfs merge=lfs -text
98
+ recordings/nid_20250924_193554.wav filter=lfs diff=lfs merge=lfs -text
99
+ recordings/nid_20250924_193645.wav filter=lfs diff=lfs merge=lfs -text
100
+ recordings/nid_20250924_193831.wav filter=lfs diff=lfs merge=lfs -text
101
+ recordings/nid_20250924_195919.wav filter=lfs diff=lfs merge=lfs -text
102
+ recordings/nid_20250924_200017.wav filter=lfs diff=lfs merge=lfs -text
103
+ recordings/nid_20250924_200225.wav filter=lfs diff=lfs merge=lfs -text
104
+ recordings/nid_20250924_200327.wav filter=lfs diff=lfs merge=lfs -text
105
+ recordings/nid_20250924_200456.wav filter=lfs diff=lfs merge=lfs -text
106
+ recordings/nid_20250924_200525.wav filter=lfs diff=lfs merge=lfs -text
107
+ recordings/nid_20250924_200946.wav filter=lfs diff=lfs merge=lfs -text
108
+ recordings/nid_20250924_201105.wav filter=lfs diff=lfs merge=lfs -text
109
+ recordings/nid_20250924_201847.wav filter=lfs diff=lfs merge=lfs -text
110
+ recordings/nid_20250924_201924.wav filter=lfs diff=lfs merge=lfs -text
111
+ recordings/nid_20250924_202232.wav filter=lfs diff=lfs merge=lfs -text
112
+ recordings/nid_20250924_202334.wav filter=lfs diff=lfs merge=lfs -text
113
+ recordings/nid_20250924_202518.wav filter=lfs diff=lfs merge=lfs -text
114
+ recordings/nid_20250924_202637.wav filter=lfs diff=lfs merge=lfs -text
115
+ recordings/nid_20250924_202658.wav filter=lfs diff=lfs merge=lfs -text
116
+ recordings/nid_20250924_202725.wav filter=lfs diff=lfs merge=lfs -text
117
+ recordings/nid_20250924_202856.wav filter=lfs diff=lfs merge=lfs -text
118
+ recordings/nid_20250924_202917.wav filter=lfs diff=lfs merge=lfs -text
119
+ recordings/nid_20250924_202939.wav filter=lfs diff=lfs merge=lfs -text
120
+ recordings/nid_20250924_202958.wav filter=lfs diff=lfs merge=lfs -text
121
+ recordings/nid_20250924_203018.wav filter=lfs diff=lfs merge=lfs -text
122
+ recordings/nid_20250924_203243.wav filter=lfs diff=lfs merge=lfs -text
123
+ recordings/nid_20250924_203318.wav filter=lfs diff=lfs merge=lfs -text
124
+ recordings/nid_20250924_203901.wav filter=lfs diff=lfs merge=lfs -text
125
+ recordings/nid_20250924_213039.wav filter=lfs diff=lfs merge=lfs -text
126
+ recordings/nid_20250924_213332.wav filter=lfs diff=lfs merge=lfs -text
127
+ recordings/nid_20250924_213415.wav filter=lfs diff=lfs merge=lfs -text
128
+ recordings/nid_20250924_215139.wav filter=lfs diff=lfs merge=lfs -text
129
+ recordings/nid_20250924_215742.wav filter=lfs diff=lfs merge=lfs -text
130
+ recordings/nid_20250924_220323.wav filter=lfs diff=lfs merge=lfs -text
131
+ recordings/nid_20250924_220610.wav filter=lfs diff=lfs merge=lfs -text
132
+ recordings/nid_20250924_220942.wav filter=lfs diff=lfs merge=lfs -text
133
+ recordings/nid_20250924_221305.wav filter=lfs diff=lfs merge=lfs -text
134
+ recordings/nid_20250924_221623.wav filter=lfs diff=lfs merge=lfs -text
135
+ recordings/nid_20250924_221735.wav filter=lfs diff=lfs merge=lfs -text
136
+ recordings/nid_20250924_221954.wav filter=lfs diff=lfs merge=lfs -text
137
+ recordings/nid_20250924_222031.wav filter=lfs diff=lfs merge=lfs -text
138
+ recordings/nid_20250924_222055.wav filter=lfs diff=lfs merge=lfs -text
139
+ recordings/nid_20250924_222126.wav filter=lfs diff=lfs merge=lfs -text
140
+ recordings/nid_20250925_103705.wav filter=lfs diff=lfs merge=lfs -text
141
+ recordings/nid_20250925_103842.wav filter=lfs diff=lfs merge=lfs -text
142
+ recordings/nid_20250925_104013.wav filter=lfs diff=lfs merge=lfs -text
143
+ recordings/nid_20250925_104056.wav filter=lfs diff=lfs merge=lfs -text
144
+ recordings/phone_20250909_140723.wav filter=lfs diff=lfs merge=lfs -text
145
+ recordings/phone_20250909_141138.wav filter=lfs diff=lfs merge=lfs -text
146
+ recordings/phone_20250909_141212.wav filter=lfs diff=lfs merge=lfs -text
147
+ recordings/phone_20250909_141256.wav filter=lfs diff=lfs merge=lfs -text
148
+ recordings/phone_20250909_141359.wav filter=lfs diff=lfs merge=lfs -text
149
+ recordings/phone_20250909_142839.wav filter=lfs diff=lfs merge=lfs -text
150
+ recordings/phone_20250909_143206.wav filter=lfs diff=lfs merge=lfs -text
151
+ recordings/phone_20250909_143242.wav filter=lfs diff=lfs merge=lfs -text
152
+ recordings/phone_20250909_143308.wav filter=lfs diff=lfs merge=lfs -text
153
+ recordings/phone_20250909_143425.wav filter=lfs diff=lfs merge=lfs -text
154
+ recordings/phone_20250909_143449.wav filter=lfs diff=lfs merge=lfs -text
155
+ recordings/phone_20250909_144046.wav filter=lfs diff=lfs merge=lfs -text
156
+ recordings/phone_20250909_144111.wav filter=lfs diff=lfs merge=lfs -text
157
+ recordings/phone_20250909_144132.wav filter=lfs diff=lfs merge=lfs -text
158
+ recordings/phone_20250909_144211.wav filter=lfs diff=lfs merge=lfs -text
159
+ recordings/phone_20250909_144519.wav filter=lfs diff=lfs merge=lfs -text
160
+ recordings/phone_20250909_144552.wav filter=lfs diff=lfs merge=lfs -text
161
+ recordings/phone_20250909_144616.wav filter=lfs diff=lfs merge=lfs -text
162
+ recordings/phone_20250909_144644.wav filter=lfs diff=lfs merge=lfs -text
163
+ recordings/phone_20250909_144706.wav filter=lfs diff=lfs merge=lfs -text
164
+ recordings/phone_20250909_144728.wav filter=lfs diff=lfs merge=lfs -text
165
+ recordings/phone_20250909_155318.wav filter=lfs diff=lfs merge=lfs -text
166
+ recordings/phone_20250909_155349.wav filter=lfs diff=lfs merge=lfs -text
167
+ recordings/phone_20250909_155514.wav filter=lfs diff=lfs merge=lfs -text
168
+ recordings/phone_20250909_155531.wav filter=lfs diff=lfs merge=lfs -text
169
+ recordings/phone_20250909_155657.wav filter=lfs diff=lfs merge=lfs -text
170
+ recordings/phone_20250909_155833.wav filter=lfs diff=lfs merge=lfs -text
171
+ recordings/phone_20250909_170206.wav filter=lfs diff=lfs merge=lfs -text
172
+ recordings/phone_20250909_170436.wav filter=lfs diff=lfs merge=lfs -text
173
+ recordings/phone_20250909_170608.wav filter=lfs diff=lfs merge=lfs -text
174
+ recordings/phone_20250924_172013.wav filter=lfs diff=lfs merge=lfs -text
175
+ recordings/phone_20250924_173904.wav filter=lfs diff=lfs merge=lfs -text
176
+ recordings/phone_20250924_173928.wav filter=lfs diff=lfs merge=lfs -text
177
+ recordings/phone_20250924_174543.wav filter=lfs diff=lfs merge=lfs -text
178
+ recordings/phone_20250924_184304.wav filter=lfs diff=lfs merge=lfs -text
179
+ recordings/phone_20250924_184519.wav filter=lfs diff=lfs merge=lfs -text
180
+ recordings/phone_20250924_184618.wav filter=lfs diff=lfs merge=lfs -text
181
+ recordings/phone_20250924_185008.wav filter=lfs diff=lfs merge=lfs -text
182
+ recordings/phone_20250924_185556.wav filter=lfs diff=lfs merge=lfs -text
183
+ recordings/phone_20250924_185707.wav filter=lfs diff=lfs merge=lfs -text
184
+ recordings/phone_20250924_185935.wav filter=lfs diff=lfs merge=lfs -text
185
+ recordings/phone_20250924_190723.wav filter=lfs diff=lfs merge=lfs -text
186
+ recordings/phone_20250924_190828.wav filter=lfs diff=lfs merge=lfs -text
187
+ recordings/phone_20250924_190905.wav filter=lfs diff=lfs merge=lfs -text
188
+ recordings/phone_20250924_192105.wav filter=lfs diff=lfs merge=lfs -text
189
+ recordings/phone_20250924_192132.wav filter=lfs diff=lfs merge=lfs -text
190
+ recordings/phone_20250924_192201.wav filter=lfs diff=lfs merge=lfs -text
191
+ recordings/phone_20250924_193531.wav filter=lfs diff=lfs merge=lfs -text
192
+ recordings/phone_20250924_200629.wav filter=lfs diff=lfs merge=lfs -text
193
+ recordings/phone_20250924_200649.wav filter=lfs diff=lfs merge=lfs -text
194
+ recordings/phone_20250924_200714.wav filter=lfs diff=lfs merge=lfs -text
195
+ recordings/phone_20250924_200732.wav filter=lfs diff=lfs merge=lfs -text
196
+ recordings/phone_20250924_200905.wav filter=lfs diff=lfs merge=lfs -text
197
+ recordings/recording_20250909_140117.wav filter=lfs diff=lfs merge=lfs -text
198
+ recordings/upload_nid_20250909_142240.wav filter=lfs diff=lfs merge=lfs -text
199
+ recordings/upload_nid_20250909_145232.wav filter=lfs diff=lfs merge=lfs -text
200
+ recordings/upload_nid_20250909_155235.wav filter=lfs diff=lfs merge=lfs -text
201
+ recordings/upload_nid_20250909_155331.wav filter=lfs diff=lfs merge=lfs -text
202
+ recordings/upload_nid_20250909_155351.wav filter=lfs diff=lfs merge=lfs -text
203
+ recordings/upload_nid_20250909_155359.wav filter=lfs diff=lfs merge=lfs -text
204
+ recordings/upload_nid_20250909_155418.wav filter=lfs diff=lfs merge=lfs -text
205
+ recordings/upload_nid_20250909_155437.wav filter=lfs diff=lfs merge=lfs -text
206
+ recordings/upload_nid_20250909_155517.wav filter=lfs diff=lfs merge=lfs -text
207
+ recordings/upload_nid_20250909_155534.wav filter=lfs diff=lfs merge=lfs -text
208
+ recordings/upload_nid_20250909_155550.wav filter=lfs diff=lfs merge=lfs -text
209
+ recordings/upload_nid_20250909_155611.wav filter=lfs diff=lfs merge=lfs -text
210
+ recordings/upload_phone_20250909_141748.wav filter=lfs diff=lfs merge=lfs -text
211
+ recordings/upload_phone_20250909_142024.wav filter=lfs diff=lfs merge=lfs -text
212
+ recordings/upload_phone_20250909_142041.wav filter=lfs diff=lfs merge=lfs -text
213
+ recordings/upload_phone_20250909_142238.wav filter=lfs diff=lfs merge=lfs -text
214
+ recordings/upload_phone_20250909_142949.wav filter=lfs diff=lfs merge=lfs -text
215
+ stt_ar_fastconformer_large_pc_finetuned.nemo filter=lfs diff=lfs merge=lfs -text
Downloading model.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ https://huggingface.co/nvidia/stt_ar_fastconformer_hybrid_large_pcd_v1.0
app.py ADDED
@@ -0,0 +1,414 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import sounddevice as sd
2
+ # import streamlit as st
3
+ # import os
4
+ # import re
5
+ # import numpy as np
6
+ # import wave
7
+ # import requests
8
+ # from datetime import datetime
9
+
10
+ # API_URL = "http://localhost:8000/transcribe"
11
+
12
+ # # Record audio
13
+ # def record_audio(duration=15, fs=16000):
14
+ # st.write("🔴 Recording... Speak Arabic now!")
15
+ # recording = sd.rec(int(duration * fs), samplerate=fs, channels=1, dtype='int16')
16
+ # sd.wait()
17
+ # st.write("✅ Recording finished")
18
+ # return recording, fs
19
+
20
+ # # Save recording
21
+ # def save_wav(recording, fs, out_dir="recordings"):
22
+ # os.makedirs(out_dir, exist_ok=True)
23
+ # timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
24
+ # file_path = os.path.join(out_dir, f"recording_{timestamp}.wav")
25
+
26
+ # # Normalize
27
+ # max_val = np.max(np.abs(recording))
28
+ # if max_val > 0:
29
+ # recording = (recording / max_val * 32767).astype(np.int16)
30
+
31
+ # with wave.open(file_path, "wb") as wf:
32
+ # wf.setnchannels(1)
33
+ # wf.setsampwidth(2)
34
+ # wf.setframerate(fs)
35
+ # wf.writeframes(recording.tobytes())
36
+
37
+ # return file_path
38
+
39
+ # # Call API
40
+ # def transcribe_audio(file_path):
41
+ # with open(file_path, "rb") as f:
42
+ # files = {"file": (file_path, f, "audio/wav")}
43
+ # response = requests.post(API_URL, files=files)
44
+
45
+ # if response.status_code == 200:
46
+ # return response.json().get("transcription", "")
47
+ # else:
48
+ # st.error(f"❌ API Error {response.status_code}: {response.text}")
49
+ # return ""
50
+
51
+ # # Extract phone number
52
+ # def extract_phone_number(text):
53
+ # match = re.search(r"01[0-9]{9}", text)
54
+ # return match.group(0) if match else None
55
+
56
+ # # Extract national ID
57
+ # def extract_national_id(text):
58
+ # digits = re.findall(r"\d+", text)
59
+ # candidate = "".join(digits)
60
+ # if len(candidate) == 14:
61
+ # return candidate
62
+ # elif len(candidate) > 14:
63
+ # return candidate[:14]
64
+ # elif 7 <= len(candidate) < 14:
65
+ # return f"⚠️ Incomplete ID: {candidate} ({len(candidate)} digits)"
66
+ # else:
67
+ # return None
68
+
69
+ # # ---------------- UI ----------------
70
+ # st.title("📞 Phone & National ID Capture (with Name + Case Name)")
71
+
72
+ # # Session state
73
+ # if "phone_number" not in st.session_state:
74
+ # st.session_state.phone_number = None
75
+ # if "national_id" not in st.session_state:
76
+ # st.session_state.national_id = None
77
+ # if "name" not in st.session_state:
78
+ # st.session_state.name = ""
79
+ # if "case_name" not in st.session_state:
80
+ # st.session_state.case_name = ""
81
+
82
+ # # Step 1: Phone number
83
+ # st.subheader("Step 1: Provide your phone number")
84
+ # col1, col2 = st.columns(2)
85
+
86
+ # with col1:
87
+ # if st.button("🎙️ Record Phone Number"):
88
+ # rec, fs = record_audio()
89
+ # wav_path = save_wav(rec, fs)
90
+ # st.audio(wav_path)
91
+ # text = transcribe_audio(wav_path)
92
+ # st.write("📝 Transcription:", text)
93
+ # phone = extract_phone_number(text)
94
+ # if phone:
95
+ # st.session_state.phone_number = phone
96
+ # st.success(f"📱 Detected Phone Number: {phone}")
97
+ # else:
98
+ # st.error("❌ No valid phone number detected")
99
+
100
+ # with col2:
101
+ # phone_upload = st.file_uploader("Or upload phone number audio", type=["wav", "mp3", "m4a"])
102
+ # if phone_upload is not None:
103
+ # temp_path = os.path.join("recordings", f"upload_phone_{datetime.now().strftime('%Y%m%d_%H%M%S')}.wav")
104
+ # os.makedirs("recordings", exist_ok=True)
105
+ # with open(temp_path, "wb") as f:
106
+ # f.write(phone_upload.read())
107
+ # st.audio(temp_path)
108
+ # text = transcribe_audio(temp_path)
109
+ # st.write("📝 Transcription:", text)
110
+ # phone = extract_phone_number(text)
111
+ # if phone:
112
+ # st.session_state.phone_number = phone
113
+ # st.success(f"📱 Detected Phone Number: {phone}")
114
+ # else:
115
+ # st.error("❌ No valid phone number detected")
116
+
117
+ # # Step 2: National ID
118
+ # st.subheader("Step 2: Provide your national ID")
119
+ # col3, col4 = st.columns(2)
120
+
121
+ # with col3:
122
+ # if st.button("🎙️ Record National ID"):
123
+ # rec, fs = record_audio()
124
+ # wav_path = save_wav(rec, fs)
125
+ # st.audio(wav_path)
126
+ # text = transcribe_audio(wav_path)
127
+ # st.write("📝 Transcription:", text)
128
+ # nid = extract_national_id(text)
129
+ # if nid:
130
+ # st.session_state.national_id = nid
131
+ # st.success(f"🪪 Detected National ID: {nid}")
132
+ # else:
133
+ # st.error("❌ No valid national ID detected")
134
+
135
+ # with col4:
136
+ # nid_upload = st.file_uploader("Or upload national ID audio", type=["wav", "mp3", "m4a"])
137
+ # if nid_upload is not None:
138
+ # temp_path = os.path.join("recordings", f"upload_nid_{datetime.now().strftime('%Y%m%d_%H%M%S')}.wav")
139
+ # os.makedirs("recordings", exist_ok=True)
140
+ # with open(temp_path, "wb") as f:
141
+ # f.write(nid_upload.read())
142
+ # st.audio(temp_path)
143
+ # text = transcribe_audio(temp_path)
144
+ # st.write("📝 Transcription:", text)
145
+ # nid = extract_national_id(text)
146
+ # if nid:
147
+ # st.session_state.national_id = nid
148
+ # st.success(f"🪪 Detected National ID: {nid}")
149
+ # else:
150
+ # st.error("❌ No valid national ID detected")
151
+
152
+ # # Step 3: Manual fields
153
+ # st.subheader("Step 3: Provide additional info")
154
+ # st.session_state.name = st.text_input("👤 Enter your Name", st.session_state.name)
155
+ # st.session_state.case_name = st.text_input("📂 Enter Case Name", st.session_state.case_name)
156
+
157
+ # # Final summary
158
+ # st.subheader("📋 Summary")
159
+ # if st.session_state.phone_number:
160
+ # st.info(f"📱 Phone Number: {st.session_state.phone_number}")
161
+ # if st.session_state.national_id:
162
+ # st.info(f"🪪 National ID: {st.session_state.national_id}")
163
+ # if st.session_state.name:
164
+ # st.info(f"👤 Name: {st.session_state.name}")
165
+ # if st.session_state.case_name:
166
+ # st.info(f"📂 Case Name: {st.session_state.case_name}")
167
+
168
+ # if st.session_state.phone_number and st.session_state.national_id and st.session_state.name and st.session_state.case_name:
169
+ # st.success("✅ All details captured successfully!")
170
+
171
+
172
+ import sounddevice as sd
173
+ import streamlit as st
174
+ import os
175
+ import re
176
+ import numpy as np
177
+ import wave
178
+ import requests
179
+ from datetime import datetime
180
+
181
+ API_URL = "http://localhost:8070/transcribe"
182
+
183
+ # Record audio
184
+ def record_audio(duration=15, fs=16000):
185
+ st.write("🔴 Recording... Speak Arabic now!")
186
+ # recording = sd.rec(int(duration * fs), samplerate=fs, channels=1, dtype='int16')
187
+ recording = sd.rec(int(16000 * 10), samplerate=16000, channels=1, dtype='int16')
188
+ sd.wait()
189
+ st.write("✅ Recording finished")
190
+ return recording, fs
191
+
192
+ # Save recording
193
+ # def save_wav(recording, fs, out_dir="recordings", prefix="recording"):
194
+ # os.makedirs(out_dir, exist_ok=True)
195
+ # timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
196
+ # file_path = os.path.join(out_dir, f"{prefix}_{timestamp}.wav")
197
+
198
+ # # Normalize
199
+ # max_val = np.max(np.abs(recording))
200
+ # if max_val > 0:
201
+ # recording = (recording / max_val * 32767).astype(np.int16)
202
+
203
+ # with wave.open(file_path, "wb") as wf:
204
+ # wf.setnchannels(1)
205
+ # wf.setsampwidth(2)
206
+ # wf.setframerate(fs)
207
+ # wf.writeframes(recording.tobytes())
208
+
209
+ # return file_path
210
+ import scipy.io.wavfile as wav
211
+
212
+ # def save_wav(recording, fs, out_dir="recordings", prefix="recording"):
213
+ # os.makedirs(out_dir, exist_ok=True)
214
+ # timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
215
+ # file_path = os.path.join(out_dir, f"{prefix}_{timestamp}.wav")
216
+
217
+ # # Save directly using scipy.io.wavfile
218
+ # wav.write(file_path, fs, recording)
219
+
220
+ # return file_path
221
+ # Call API
222
+ def transcribe_audio(file_path):
223
+ with open(file_path, "rb") as f:
224
+ files = {"file": (file_path, f, "audio/wav")}
225
+ response = requests.post(API_URL, files=files)
226
+
227
+ if response.status_code == 200:
228
+ return response.json().get("transcription", "")
229
+ else:
230
+ st.error(f"❌ API Error {response.status_code}: {response.text}")
231
+ return ""
232
+
233
+
234
+ def save_wav(recording, fs, out_dir="recordings", prefix="recording"):
235
+ os.makedirs(out_dir, exist_ok=True)
236
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
237
+ file_path = os.path.join(out_dir, f"{prefix}_{timestamp}.wav")
238
+
239
+ # Flatten to 1D if stereo-like shape
240
+ if recording.ndim > 1:
241
+ recording = recording[:, 0]
242
+
243
+ wav.write(file_path, fs, recording.astype(np.int16))
244
+
245
+ return file_path
246
+
247
+ # Extract phone number
248
+ def extract_phone_number(text):
249
+ digits = re.findall(r"\d+", text)
250
+ candidate = "".join(digits)
251
+ return candidate if candidate.startswith("01") and len(candidate) == 11 else None
252
+
253
+ # Extract national ID
254
+ def extract_national_id(text):
255
+ digits = re.findall(r"\d+", text)
256
+ candidate = "".join(digits)
257
+ if len(candidate) == 14:
258
+ return candidate
259
+ elif len(candidate) > 14:
260
+ return candidate[:14]
261
+ elif 7 <= len(candidate) < 14:
262
+ return f"⚠️ Incomplete ID: {candidate} ({len(candidate)} digits)"
263
+ else:
264
+ return None
265
+
266
+ # ---------------- UI ----------------
267
+ st.title("📞 Phone, National ID, Name & Case Name Capture")
268
+
269
+ # Session state
270
+ for key in ["phone_number", "national_id", "name", "case_name"]:
271
+ if key not in st.session_state:
272
+ st.session_state[key] = None
273
+
274
+ # Step 1: Phone number
275
+ st.subheader("Step 1: Provide your phone number")
276
+ col1, col2 = st.columns(2)
277
+
278
+ with col1:
279
+ if st.button("🎙️ Record Phone Number"):
280
+ rec, fs = record_audio()
281
+ wav_path = save_wav(rec, fs, prefix="phone")
282
+ st.audio(wav_path)
283
+ text = transcribe_audio(wav_path)
284
+ st.write("📝 Transcription:", text)
285
+ phone = extract_phone_number(text)
286
+ if phone:
287
+ st.session_state.phone_number = phone
288
+ st.success(f"📱 Detected Phone Number: {phone}")
289
+ else:
290
+ st.error("❌ No valid phone number detected")
291
+
292
+ with col2:
293
+ phone_upload = st.file_uploader("Or upload phone number audio", type=["wav", "mp3", "m4a"])
294
+ if phone_upload is not None:
295
+ temp_path = os.path.join("recordings", f"upload_phone_{datetime.now().strftime('%Y%m%d_%H%M%S')}.wav")
296
+ os.makedirs("recordings", exist_ok=True)
297
+ with open(temp_path, "wb") as f:
298
+ f.write(phone_upload.read())
299
+ st.audio(temp_path)
300
+ text = transcribe_audio(temp_path)
301
+ st.write("📝 Transcription:", text)
302
+ phone = extract_phone_number(text)
303
+ if phone:
304
+ st.session_state.phone_number = phone
305
+ st.success(f"📱 Detected Phone Number: {phone}")
306
+ else:
307
+ st.error("❌ No valid phone number detected")
308
+
309
+ # Step 2: National ID
310
+ st.subheader("Step 2: Provide your national ID")
311
+ col3, col4 = st.columns(2)
312
+
313
+ with col3:
314
+ if st.button("🎙️ Record National ID"):
315
+ rec, fs = record_audio()
316
+ wav_path = save_wav(rec, fs, prefix="nid")
317
+ st.audio(wav_path)
318
+ text = transcribe_audio(wav_path)
319
+ st.write("📝 Transcription:", text)
320
+ nid = extract_national_id(text)
321
+ if nid:
322
+ st.session_state.national_id = nid
323
+ st.success(f"🪪 Detected National ID: {nid}")
324
+ else:
325
+ st.error("❌ No valid national ID detected")
326
+
327
+ with col4:
328
+ nid_upload = st.file_uploader("Or upload national ID audio", type=["wav", "mp3", "m4a"])
329
+ if nid_upload is not None:
330
+ temp_path = os.path.join("recordings", f"upload_nid_{datetime.now().strftime('%Y%m%d_%H%M%S')}.wav")
331
+ os.makedirs("recordings", exist_ok=True)
332
+ with open(temp_path, "wb") as f:
333
+ f.write(nid_upload.read())
334
+ st.audio(temp_path)
335
+ text = transcribe_audio(temp_path)
336
+ st.write("📝 Transcription:", text)
337
+ nid = extract_national_id(text)
338
+ if nid:
339
+ st.session_state.national_id = nid
340
+ st.success(f"🪪 Detected National ID: {nid}")
341
+ else:
342
+ st.error("❌ No valid national ID detected")
343
+
344
+ # Step 3: Name (audio input)
345
+ st.subheader("Step 3: Provide your Name")
346
+ col5, col6 = st.columns(2)
347
+
348
+ with col5:
349
+ if st.button("🎙️ Record Name"):
350
+ rec, fs = record_audio()
351
+ wav_path = save_wav(rec, fs, prefix="name")
352
+ st.audio(wav_path)
353
+ text = transcribe_audio(wav_path)
354
+ st.write("📝 Transcription:", text)
355
+ if text.strip():
356
+ st.session_state.name = text.strip()
357
+ st.success(f"👤 Name: {text.strip()}")
358
+
359
+ with col6:
360
+ name_upload = st.file_uploader("Or upload name audio", type=["wav", "mp3", "m4a"])
361
+ if name_upload is not None:
362
+ temp_path = os.path.join("recordings", f"upload_name_{datetime.now().strftime('%Y%m%d_%H%M%S')}.wav")
363
+ os.makedirs("recordings", exist_ok=True)
364
+ with open(temp_path, "wb") as f:
365
+ f.write(name_upload.read())
366
+ st.audio(temp_path)
367
+ text = transcribe_audio(temp_path)
368
+ st.write("📝 Transcription:", text)
369
+ if text.strip():
370
+ st.session_state.name = text.strip()
371
+ st.success(f"👤 Name: {text.strip()}")
372
+
373
+ # Step 4: Case Name (audio input)
374
+ st.subheader("Step 4: Provide Case Name")
375
+ col7, col8 = st.columns(2)
376
+
377
+ with col7:
378
+ if st.button("🎙️ Record Case Name"):
379
+ rec, fs = record_audio()
380
+ wav_path = save_wav(rec, fs, prefix="case_name")
381
+ st.audio(wav_path)
382
+ text = transcribe_audio(wav_path)
383
+ st.write("📝 Transcription:", text)
384
+ if text.strip():
385
+ st.session_state.case_name = text.strip()
386
+ st.success(f"📂 Case Name: {text.strip()}")
387
+
388
+ with col8:
389
+ case_upload = st.file_uploader("Or upload case name audio", type=["wav", "mp3", "m4a"])
390
+ if case_upload is not None:
391
+ temp_path = os.path.join("recordings", f"upload_case_{datetime.now().strftime('%Y%m%d_%H%M%S')}.wav")
392
+ os.makedirs("recordings", exist_ok=True)
393
+ with open(temp_path, "wb") as f:
394
+ f.write(case_upload.read())
395
+ st.audio(temp_path)
396
+ text = transcribe_audio(temp_path)
397
+ st.write("📝 Transcription:", text)
398
+ if text.strip():
399
+ st.session_state.case_name = text.strip()
400
+ st.success(f"📂 Case Name: {text.strip()}")
401
+
402
+ # Final summary
403
+ st.subheader("📋 Summary")
404
+ if st.session_state.phone_number:
405
+ st.info(f"📱 Phone Number: {st.session_state.phone_number}")
406
+ if st.session_state.national_id:
407
+ st.info(f"🪪 National ID: {st.session_state.national_id}")
408
+ if st.session_state.name:
409
+ st.info(f"👤 Name: {st.session_state.name}")
410
+ if st.session_state.case_name:
411
+ st.info(f"📂 Case Name: {st.session_state.case_name}")
412
+
413
+ if st.session_state.phone_number and st.session_state.national_id and st.session_state.name and st.session_state.case_name:
414
+ st.success("✅ All details captured successfully!")
app_api.py ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile, Form
2
+ from fastapi.responses import JSONResponse
3
+ import uvicorn
4
+ import tempfile
5
+ import nemo.collections.asr as nemo_asr
6
+ import re
7
+ import os
8
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
9
+ import torch
10
+ from word2number import w2n
11
+ from deep_translator import GoogleTranslator
12
+
13
+ # ===== Arabic number mapping (expanded) =====
14
+ arabic_numbers = {
15
+ # Basic digits
16
+ "صفر": "0", "زيرو": "0", "٠": "0","زيو": "0","زير": "0","زر": "0","زروا": "0","زرا": "0","زيره ": "0","زرو ": "0",
17
+ "واحد": "1", "واحدة": "1", "١": "1",
18
+ "اتنين": "2", "اثنين": "2", "إثنين": "2", "اثنان": "2", "إثنان": "2", "٢": "2",
19
+ "تلاتة": "3", "ثلاثة": "3", "٣": "3",
20
+ "اربعة": "4", "أربعة": "4", "٤": "4",
21
+ "خمسة": "5", "٥": "5",
22
+ "ستة": "6", "٦": "6",
23
+ "سبعة": "7", "٧": "7",
24
+ "تمانية": "8", "ثمانية": "8", "٨": "8",
25
+ "تسعة": "9", "٩": "9",
26
+
27
+ # Teens
28
+ "عشرة": "10", "١٠": "10",
29
+ # 11
30
+ "احد عشر": "11", "واحد عشر": "11", "حداشر": "11",
31
+ "١ عشر": "11", "1 عشر": "11", "١عشر": "11", "1عشر": "11",
32
+ "١١": "11", "11": "11",
33
+
34
+ # 12
35
+ "اثنا عشر": "12", "اثني عشر": "12", "اتناشر": "12",
36
+ "٢ عشر": "12", "2 عشر": "12", "٢عشر": "12", "2عشر": "12",
37
+ "١٢": "12", "12": "12",
38
+
39
+ # 13
40
+ "ثلاثة عشر": "13", "تلاتة عشر": "13", "تلتاشر": "13",
41
+ "٣ عشر": "13", "3 عشر": "13", "٣عشر": "13", "3عشر": "13",
42
+ "١٣": "13", "13": "13",
43
+
44
+ # 14
45
+ "أربعة عشر": "14", "اربعة عشر": "14", "اربعتاشر": "14",
46
+ "٤ عشر": "14", "4 عشر": "14", "٤عشر": "14", "4عشر": "14",
47
+ "١٤": "14", "14": "14",
48
+
49
+ # 15
50
+ "خمسة عشر": "15", "خمسه عشر": "15", "خمستاشر": "15",
51
+ "٥ عشر": "15", "5 عشر": "15", "٥عشر": "15", "5عشر": "15",
52
+ "١٥": "15", "15": "15",
53
+
54
+ # 16
55
+ "ستة عشر": "16", "سته عشر": "16", "ستاشر": "16",
56
+ "٦ عشر": "16", "6 عشر": "16", "٦عشر": "16", "6عشر": "16",
57
+ "١٦": "16", "16": "16",
58
+
59
+ # 17
60
+ "سبعة عشر": "17", "سبعه عشر": "17", "سبعتاشر": "17",
61
+ "٧ عشر": "17", "7 عشر": "17", "٧عشر": "17", "7عشر": "17",
62
+ "١٧": "17", "17": "17",
63
+
64
+ # 18
65
+ "ثمانية عشر": "18", "تمانية عشر": "18", "طمنتاشر": "18",
66
+ "٨ عشر": "18", "8 عشر": "18", "٨عشر": "18", "8عشر": "18",
67
+ "١٨": "18", "18": "18",
68
+
69
+ # 19
70
+ "تسعة عشر": "19", "تسعه عشر": "19", "تسعتاشر": "19",
71
+ "٩ عشر": "19", "9 عشر": "19", "٩عشر": "19", "9عشر": "19",
72
+ "١٩": "19", "19": "19",
73
+
74
+ # Tens
75
+ "عشرين": "20", "٢٠": "20",
76
+ "تلاتين": "30", "ثلاثين": "30", "٣٠": "30",
77
+ "اربعين": "40", "أربعين": "40", "٤٠": "40",
78
+ "خمسين": "50", "٥٠": "50",
79
+ "ستين": "60", "٦٠": "60",
80
+ "سبعين": "70", "٧٠": "70",
81
+ "تمانين": "80", "ثمانين": "80", "٨٠": "80","تمانون": "80","ثمانون": "80",
82
+ "تسعين": "90", "٩٠": "90",
83
+
84
+ # Hundreds
85
+ "مية": "100", "مائة": "100", "مئة": "100", "١٠٠": "100",
86
+ "ميتين": "200", "مائتين": "200",
87
+ "تلاتمية": "300", "ثلاثمائة": "300",
88
+ "اربعمية": "400", "أربعمائة": "400",
89
+ "خمسمية": "500", "خمسمائة": "500",
90
+ "ستمية": "600", "ستمائة": "600",
91
+ "سبعمية": "700", "سبعمائة": "700",
92
+ "تمانمية": "800", "ثمانمائة": "800",
93
+ "تسعمية": "900", "تسعمائة": "900",
94
+
95
+ # Thousands
96
+ "ألف": "1000", "الف": "1000", "١٠٠٠": "1000",
97
+ "ألفين": "2000", "الفين": "2000",
98
+ "تلات تلاف": "3000", "ثلاثة آلاف": "3000",
99
+ "اربعة آلاف": "4000", "أربعة آلاف": "4000",
100
+ "خمسة آلاف": "5000",
101
+ "ستة آلاف": "6000",
102
+ "سبعة آلاف": "7000",
103
+ "تمانية آلاف": "8000", "ثمانية آلاف": "8000",
104
+ "تسعة آلاف": "9000",
105
+
106
+ # Large numbers
107
+ "عشرة آلاف": "10000",
108
+ "مية ألف": "100000", "مائة ألف": "100000",
109
+ "مليون": "1000000", "١٠٠٠٠٠٠": "1000000",
110
+ "ملايين": "1000000",
111
+ "مليار": "1000000000", "١٠٠٠٠٠٠٠٠٠": "1000000000",
112
+ # ===== Compound tens (Arabic + digit forms) =====
113
+ "واحد وعشرون": "21", "1 وعشرون": "21",
114
+ "اثنان وعشرون": "22", "٢ وعشرون": "22",
115
+ "ثلاثة وعشرون": "23", "٣ وعشرون": "23",
116
+ "اربعة وعشرون": "24", "٤ وعشرون": "24",
117
+ "خمسة وعشرون": "25", "٥ وعشرون": "25",
118
+ "ستة وعشرون": "26", "٦ وعشرون": "26",
119
+ "سبعة وعشرون": "27", "٧ وعشرون": "27",
120
+ "تمانية وعشرون": "28", "ثمانية وعشرون": "28", "٨ وعشرون": "28",
121
+ "تسعة وعشرون": "29", "٩ وعشرون": "29",
122
+
123
+ "ثمانية وثمانون": "88", "8 وثمانون": "88",
124
+ "اثنان وثمانون": "82", "٢ وثمانون": "82",
125
+ "خمسة وستون": "65", "5 وستون": "65",
126
+ "ستة عشر": "16", "٦ عشر": "16",
127
+ "اثنا عشر": "12", "١٢": "12",
128
+ "ثلاثة وثلاثون": "33", "٣٣": "33", "33": "33",
129
+ "أربعة وأربعون": "44", "٤٤": "44", "44": "44",
130
+ "خمسة وخمسون": "55", "٥٥": "55", "55": "55",
131
+ "ستة وستون": "66", "٦٦": "66", "66": "66",
132
+ "سبعة وسبعون": "77", "٧٧": "77", "77": "77",
133
+ "ثمانية وثمانون": "88", "٨٨": "88", "88": "88",
134
+ "تسعة وتسعون": "99", "٩٩": "99", "99": "99",
135
+ }
136
+
137
+ def replace_arabic_numbers(text: str) -> str:
138
+ for word, digit in arabic_numbers.items():
139
+ text = re.sub(rf"\b{word}\b", digit, text)
140
+ return text
141
+
142
+
143
+ # ===== FastAPI app =====
144
+ app = FastAPI(title="Arabic ASR API", description="ASR API with NeMo and Arabic digit conversion")
145
+
146
+ # Load model once on startup
147
+ @app.on_event("startup")
148
+ def load_model():
149
+ global asr_model
150
+ global model
151
+ global tokenizer
152
+ global device
153
+ #model_path = os.getenv("NEMO_MODEL_PATH", "C:/Users/thegh/Python_Projects/Expertflow/UnderProgress/Peter_Projects/nvidia_asr_eg_conformer_better_than_whisper/stt_ar_fastconformer_hybrid_large_pcd_v1.0.nemo")
154
+ model_path = "C:/Users/thegh/Python_Projects/Expertflow/UnderProgress/Peter_Projects/NP_Detection_Nvidia_conformer/stt_ar_fastconformer_hybrid_large_pc_v1.0.nemo"
155
+ asr_model = nemo_asr.models.EncDecCTCModel.restore_from(model_path)
156
+ # Load once globally
157
+ # model_name = "alaasayed_ai/Egyptian_Arabic_to_English"
158
+ model_translator_name = "ukaAi/Egyptian_dialect_to_arabic"
159
+ tokenizer = AutoTokenizer.from_pretrained(model_translator_name)
160
+ model = AutoModelForSeq2SeqLM.from_pretrained(model_translator_name)
161
+
162
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
163
+ model = model.to(device)
164
+ def translate_egyptian_to_english(text: str) -> str:
165
+ """
166
+ Translates Egyptian Arabic text to English using the fine-tuned NLLB model.
167
+
168
+ Parameters:
169
+ - text (str): The input Egyptian Arabic text
170
+
171
+ Returns:
172
+ - str: The translated English text
173
+ """
174
+ tokenizer.src_lang = "arz_Arab"
175
+ forced_bos_token_id = tokenizer.convert_tokens_to_ids("eng_Latn")
176
+
177
+ inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True, max_length=512)
178
+ inputs = {k: v.to(device) for k, v in inputs.items()}
179
+
180
+ translated = model.generate(
181
+ **inputs,
182
+ forced_bos_token_id=forced_bos_token_id,
183
+ max_length=512,
184
+ num_beams=4,
185
+ early_stopping=True
186
+ )
187
+
188
+ return tokenizer.decode(translated[0], skip_special_tokens=True)
189
+ # Cardinal and tens
190
+ WORD_TO_NUM = {
191
+ "zero": 0, "one": 1, "two": 2, "three": 3, "four": 4, "five": 5,
192
+ "six": 6, "seven": 7, "eight": 8, "nine": 9, "ten": 10,
193
+ "eleven": 11, "twelve": 12, "thirteen": 13, "fourteen": 14,
194
+ "fifteen": 15, "sixteen": 16, "seventeen": 17, "eighteen": 18,
195
+ "nineteen": 19, "twenty": 20, "thirty": 30, "forty": 40,
196
+ "fifty": 50, "sixty": 60, "seventy": 70, "eighty": 80, "ninety": 90
197
+ }
198
+
199
+ # Ordinals
200
+ ORDINAL_TO_NUM = {
201
+ "first": 1, "second": 2, "third": 3, "fourth": 4, "fifth": 5,
202
+ "sixth": 6, "seventh": 7, "eighth": 8, "ninth": 9, "tenth": 10,
203
+ "eleventh": 11, "twelfth": 12, "thirteenth": 13, "fourteenth": 14,
204
+ "fifteenth": 15, "sixteenth": 16, "seventeenth": 17, "eighteenth": 18,
205
+ "nineteenth": 19, "twentieth": 20, "thirtieth": 30, "fortieth": 40,
206
+ "fiftieth": 50, "sixtieth": 60, "seventieth": 70, "eightieth": 80, "ninetieth": 90
207
+ }
208
+
209
+ def normalize_token(token: str):
210
+ """Convert a single token or hyphenated token into a number if possible."""
211
+ token = token.lower()
212
+
213
+ # Handle ordinals
214
+ if token in ORDINAL_TO_NUM:
215
+ return ORDINAL_TO_NUM[token]
216
+
217
+ # Handle hyphenated compounds like 'thirty-nine'
218
+ if "-" in token:
219
+ parts = token.split("-")
220
+ nums = [WORD_TO_NUM.get(p) for p in parts if p in WORD_TO_NUM]
221
+ if nums:
222
+ return sum(nums)
223
+
224
+ # Handle normal cardinals
225
+ return WORD_TO_NUM.get(token)
226
+
227
+
228
+ def words_to_numbers(phrase: str):
229
+ tokens = phrase.lower().strip().split()
230
+ nums = [normalize_token(t) for t in tokens if normalize_token(t) is not None]
231
+
232
+ if not nums:
233
+ return []
234
+
235
+ # Case: three tokens like "two one ninety" → 91
236
+ if len(nums) == 3:
237
+ return [int(f"{nums[0]}{nums[1]}") + nums[2]]
238
+
239
+ # Case: two tokens like "five thirty" → 35
240
+ if len(nums) == 2:
241
+ if nums[1] >= 20:
242
+ return [nums[0] + nums[1]]
243
+ else:
244
+ return [int("".join(str(n) for n in nums))]
245
+
246
+ # Otherwise, return each token separately
247
+ return nums
248
+
249
+
250
+ def parse_numbers(text: str):
251
+ chunks = re.split(r"[,\.;]", text)
252
+ result = []
253
+ for chunk in chunks:
254
+ result.extend(words_to_numbers(chunk))
255
+ return " ".join(str(n) for n in result)
256
+ @app.post("/transcribe")
257
+ async def transcribe_audio(file: UploadFile = File(...)):
258
+ # Save uploaded file to a temp path
259
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
260
+ tmp.write(await file.read())
261
+ tmp_path = tmp.name
262
+
263
+ try:
264
+ # Run transcription
265
+ result = asr_model.transcribe([tmp_path])
266
+ print(result)
267
+ raw_text = result[0].text
268
+ print(raw_text)
269
+
270
+ result = translate_egyptian_to_english(raw_text)
271
+
272
+ print("\n=== English Translation ===\n")
273
+ print(result)
274
+
275
+ print(parse_numbers(result))
276
+ # print (w2n.word_to_num(result))
277
+ # Convert Arabic numbers
278
+ # cleaned_text = replace_arabic_numbers(raw_text)
279
+ # print("\n\n")
280
+ # print(cleaned_text)
281
+ # print("\n\n")
282
+ return JSONResponse(content={"transcription": raw_text})
283
+
284
+ finally:
285
+ os.remove(tmp_path)
286
+
287
+
288
+ @app.post("/transcribe-bytes")
289
+ async def transcribe_audio_bytes(audio_bytes: bytes = File(...)):
290
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
291
+ tmp.write(audio_bytes)
292
+ tmp_path = tmp.name
293
+
294
+ try:
295
+ result = asr_model.transcribe([tmp_path])
296
+ raw_text = result[0].text
297
+ cleaned_text = replace_arabic_numbers(raw_text)
298
+
299
+ return JSONResponse(content={"transcription": cleaned_text})
300
+
301
+ finally:
302
+ os.remove(tmp_path)
303
+
304
+
305
+ if __name__ == "__main__":
306
+ uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)
app_api_2.py ADDED
@@ -0,0 +1,490 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # from fastapi import FastAPI, File, UploadFile
2
+ # from fastapi.responses import JSONResponse
3
+ # import uvicorn
4
+ # import tempfile
5
+ # import nemo.collections.asr as nemo_asr
6
+ # import re
7
+ # import os
8
+ # import librosa
9
+ # import soundfile as sf
10
+
11
+ # # ===== Arabic number mapping (expanded) =====
12
+ # arabic_numbers = {
13
+ # "صفر": "0", "زيرو": "0", "٠": "0", "زيو": "0", "زير": "0",
14
+ # "واحد": "1", "واحدة": "1", "١": "1",
15
+ # "اتنين": "2", "اثنين": "2", "اثنان": "2", "٢": "2",
16
+ # "تلاتة": "3", "ثلاثة": "3", "٣": "3","ثلاث": "3","تلات": "3",
17
+ # "اربعة": "4", "أربعة": "4", "٤": "4",
18
+ # "خمسة": "5", "٥": "5","خمسه": "5",
19
+ # "ستة": "6", "٦": "6",
20
+ # "سبعة": "7", "٧": "7","سبعه": "7",
21
+ # "تمانية": "8", "ثمانية": "8", "٨": "8",
22
+ # "تسعة": "9", "٩": "9",
23
+ # "عشرة": "10", "١٠": "10","عشره": "10",
24
+ # "حداشر": "11", "احد عشر": "11", "احداشر": "11",
25
+ # "اتناشر": "12", "اثنا عشر": "12",
26
+ # "تلتاشر": "13", "ثلاثة عشر": "13",
27
+ # "اربعتاشر": "14", "أربعة عشر": "14",
28
+ # "خمستاشر": "15", "خمسة عشر": "15",
29
+ # "ستاشر": "16", "ستة عشر": "16",
30
+ # "سبعتاشر": "17", "سبعة عشر": "17",
31
+ # "طمنتاشر": "18", "ثمانية عشر": "18",
32
+ # "تسعتاشر": "19", "تسعة عشر": "19",
33
+ # "عشرين": "20", "٢٠": "20",
34
+ # "تلاتين": "30", "ثلاثين": "30", "٣٠": "30",
35
+ # "اربعين": "40", "أربعين": "40", "٤٠": "40",
36
+ # "خمسين": "50", "٥٠": "50",
37
+ # "ستين": "60", "٦٠": "60",
38
+ # "سبعين": "70", "٧٠": "70",
39
+ # "تمانين": "80", "ثمانين": "80", "٨٠": "80",
40
+ # "تسعين": "90", "٩٠": "90",
41
+ # "مية": "100", "مائة": "100", "مئة": "100", "١٠٠": "100",
42
+ # "ميتين": "200", "مائتين": "200",
43
+ # "تلاتمية": "300", "ثلاثمائة": "300",
44
+ # "اربعمية": "400", "أربعمائة": "400",
45
+ # "خمسمية": "500", "خمسمائة": "500",
46
+ # "ستمية": "600", "ستمائة": "600",
47
+ # "سبعمية": "700", "سبعمائة": "700",
48
+ # "تمانمية": "800", "ثمانمائة": "800",
49
+ # "تسعمية": "900", "تسعمائة": "900",
50
+ # "ألف": "1000", "الف": "1000", "١٠٠٠": "1000",
51
+ # "ألفين": "2000", "الفين": "2000",
52
+ # "تلات تلاف": "3000", "ثلاثة آلاف": "3000",
53
+ # "اربعة آلاف": "4000", "أربعة آلاف": "4000",
54
+ # "خمسة آلاف": "5000",
55
+ # "ستة آلاف": "6000",
56
+ # "سبعة آلاف": "7000",
57
+ # "تمانية آلاف": "8000", "ثمانية آلاف": "8000",
58
+ # "تسعة آلاف": "9000",
59
+ # "عشرة آلاف": "10000",
60
+ # "مية ألف": "100000", "مائة ألف": "100000",
61
+ # "مليون": "1000000", "ملايين": "1000000",
62
+ # "مليار": "1000000000"
63
+ # }
64
+
65
+ # # ===== Helpers =====
66
+ # def normalize_arabic(text: str) -> str:
67
+ # diacritics = re.compile(r'[\u0617-\u061A\u064B-\u0652]')
68
+ # text = re.sub(diacritics, '', text)
69
+ # text = re.sub(r'[إأآا]', 'ا', text)
70
+ # text = re.sub(r'ى', 'ي', text)
71
+ # text = re.sub(r'ؤ', 'و', text)
72
+ # text = re.sub(r'ئ', 'ي', text)
73
+ # text = re.sub(r'ة', 'ه', text)
74
+ # return text
75
+
76
+ # def replace_arabic_numbers(text: str) -> str:
77
+ # for word, digit in arabic_numbers.items():
78
+ # text = re.sub(fr"(?:^|\s){word}(?:$|\s)", f" {digit} ", text)
79
+ # return " ".join(text.split())
80
+
81
+ # def join_digit_sequences(text: str) -> str:
82
+ # tokens = text.split()
83
+ # out, buffer = [], []
84
+ # for tok in tokens:
85
+ # if tok.isdigit() and len(tok) == 1:
86
+ # buffer.append(tok)
87
+ # else:
88
+ # if buffer:
89
+ # out.append("".join(buffer))
90
+ # buffer = []
91
+ # out.append(tok)
92
+ # if buffer:
93
+ # out.append("".join(buffer))
94
+ # return " ".join(out)
95
+
96
+ # def ensure_16k_wav(input_path, output_path):
97
+ # y, sr = librosa.load(input_path, sr=16000, mono=True)
98
+ # sf.write(output_path, y, 16000)
99
+
100
+ # # ===== FastAPI app =====
101
+ # app = FastAPI(title="Arabic ASR API", description="ASR API with NeMo and Arabic digit conversion")
102
+
103
+ # @app.on_event("startup")
104
+ # def load_model():
105
+ # global asr_model
106
+ # model_path = "C:/Users/thegh/Python_Projects/Expertflow/UnderProgress/Peter_Projects/NP_Detection_Nvidia_conformer/asr-egyptian-nemo-v2.0.nemo"
107
+ # asr_model = nemo_asr.models.EncDecCTCModel.restore_from(model_path)
108
+
109
+ # @app.post("/transcribe")
110
+ # async def transcribe_audio(file: UploadFile = File(...)):
111
+ # with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
112
+ # tmp.write(await file.read())
113
+ # tmp_path = tmp.name
114
+
115
+ # # Resample to 16kHz
116
+ # resampled_path = tmp_path.replace(".wav", "_16k.wav")
117
+ # ensure_16k_wav(tmp_path, resampled_path)
118
+
119
+ # try:
120
+ # result = asr_model.transcribe([resampled_path])
121
+ # raw_text = result[0].text
122
+
123
+ # raw_text = normalize_arabic(raw_text)
124
+ # cleaned_text = replace_arabic_numbers(raw_text)
125
+ # cleaned_text = join_digit_sequences(cleaned_text)
126
+
127
+ # return JSONResponse(content={"transcription": cleaned_text})
128
+
129
+ # finally:
130
+ # os.remove(tmp_path)
131
+ # if os.path.exists(resampled_path):
132
+ # os.remove(resampled_path)
133
+
134
+ # @app.post("/transcribe-bytes")
135
+ # async def transcribe_audio_bytes(audio_bytes: bytes = File(...)):
136
+ # with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
137
+ # tmp.write(audio_bytes)
138
+ # tmp_path = tmp.name
139
+
140
+ # resampled_path = tmp_path.replace(".wav", "_16k.wav")
141
+ # ensure_16k_wav(tmp_path, resampled_path)
142
+
143
+ # try:
144
+ # result = asr_model.transcribe([resampled_path])
145
+ # raw_text = result[0].text
146
+
147
+ # raw_text = normalize_arabic(raw_text)
148
+ # cleaned_text = replace_arabic_numbers(raw_text)
149
+ # cleaned_text = join_digit_sequences(cleaned_text)
150
+
151
+ # return JSONResponse(content={"transcription": cleaned_text})
152
+
153
+ # finally:
154
+ # os.remove(tmp_path)
155
+ # if os.path.exists(resampled_path):
156
+ # os.remove(resampled_path)
157
+
158
+ # if __name__ == "__main__":
159
+ # uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)
160
+ from fastapi import FastAPI, File, UploadFile
161
+ from fastapi.responses import JSONResponse
162
+ import uvicorn
163
+ import tempfile
164
+ import nemo.collections.asr as nemo_asr
165
+ import re
166
+ import os
167
+ import librosa
168
+ import soundfile as sf
169
+
170
+ # ===== Arabic + English number mapping (expanded) =====
171
+ arabic_numbers = {
172
+ # Arabic digits
173
+ "صفر": "0", "زيرو": "0", "٠": "0", "زيو": "0", "زير": "0","زينوا": "0",
174
+ "واحد": "1", "واحدة": "1", "١": "1",
175
+ "اتنين": "2", "اثنين": "2", "اثنان": "2", "٢": "2",
176
+ "تلاتة": "3", "ثلاثة": "3", "٣": "3", "ثلاث": "3", "تلات": "3",
177
+ "اربعة": "4", "أربعة": "4", "٤": "4",
178
+ "خمسة": "5", "٥": "5", "خمسه": "5",
179
+ "ستة": "6", "٦": "6",
180
+ "سبعة": "7", "٧": "7", "سبعه": "7",
181
+ "تمانية": "8", "ثمانية": "8", "٨": "8",
182
+ "تسعة": "9", "٩": "9",
183
+ "عشرة": "10", "١٠": "10", "عشره": "10",
184
+ "حداشر": "11", "احد عشر": "11", "احداشر": "11",
185
+ "اتناشر": "12", "اثنا عشر": "12",
186
+ "تلتاشر": "13", "ثلاثة عشر": "13",
187
+ "اربعتاشر": "14", "أربعة عشر": "14",
188
+ "خمستاشر": "15", "خمسة عشر": "15",
189
+ "ستاشر": "16", "ستة عشر": "16",
190
+ "سبعتاشر": "17", "سبعة عشر": "17",
191
+ "طمنتاشر": "18", "ثمانية عشر": "18",
192
+ "تسعتاشر": "19", "تسعة عشر": "19",
193
+ "عشرين": "20", "٢٠": "20",
194
+ "تلاتين": "30", "ثلاثين": "30", "٣٠": "30",
195
+ "اربعين": "40", "أربعين": "40", "٤٠": "40",
196
+ "خمسين": "50", "٥٠": "50",
197
+ "ستين": "60", "٦٠": "60",
198
+ "سبعين": "70", "٧٠": "70",
199
+ "تمانين": "80", "ثمانين": "80", "٨٠": "80",
200
+ "تسعين": "90", "٩٠": "90",
201
+ "مية": "100", "مائة": "100", "مئة": "100", "١٠٠": "100",
202
+ "ميتين": "200", "مائتين": "200",
203
+ "تلاتمية": "300", "ثلاثمائة": "300",
204
+ "اربعمية": "400", "أربعمائة": "400",
205
+ "خمسمية": "500", "خمسمائة": "500",
206
+ "ستمية": "600", "ستمائة": "600",
207
+ "سبعمية": "700", "سبعمائة": "700",
208
+ "تمانمية": "800", "ثمانمائة": "800",
209
+ "تسعمية": "900", "تسعمائة": "900",
210
+ "ألف": "1000", "الف": "1000", "١٠٠٠": "1000",
211
+ "ألفين": "2000", "الفين": "2000",
212
+ "تلات تلاف": "3000", "ثلاثة آلاف": "3000",
213
+ "اربعة آلاف": "4000", "أربعة آلاف": "4000",
214
+ "خمسة آلاف": "5000",
215
+ "ستة آلاف": "6000",
216
+ "سبعة آلاف": "7000",
217
+ "تمانية آلاف": "8000", "ثمانية آلاف": "8000",
218
+ "تسعة آلاف": "9000",
219
+ "عشرة آلاف": "10000",
220
+ "مية ألف": "100000", "مائة ألف": "100000",
221
+ "مليون": "1000000", "ملايين": "1000000",
222
+ "مليار": "1000000000",
223
+
224
+ # English digits
225
+ "zero": "0", "one": "1", "two": "2", "to": "2", "too": "2", "three": "3",
226
+ "four": "4", "for": "4", "five": "5", "six": "6", "seven": "7",
227
+ "eight": "8", "nine": "9", "ten": "10",
228
+ "eleven": "11", "twelve": "12", "thirteen": "13", "fourteen": "14",
229
+ "fifteen": "15", "sixteen": "16", "seventeen": "17",
230
+ "eighteen": "18", "nineteen": "19", "twenty": "20",
231
+ "thirty": "30", "forty": "40", "fifty": "50",
232
+ "sixty": "60", "seventy": "70", "eighty": "80", "ninety": "90",
233
+ "hundred": "100", "thousand": "1000", "million": "1000000",
234
+
235
+ # Arabic variants
236
+ "تلاته": "3", "اربعه": "4", "سته": "6",
237
+ "تمانيه": "8", "ثماني": "80", "تسعه": "9",
238
+ "واحده": "1", "عشره": "10",
239
+ "حداشر": "11", "اتناشر": "12",
240
+ "تلاته عشر": "13", "اربعه عشر": "14",
241
+ "خمسه عشر": "15", "سته عشر": "16",
242
+ "سبعه عشر": "17", "ثمانيه عشر": "18",
243
+ "تسعه عشر": "19",
244
+
245
+ # English tricky forms
246
+ "oh": "0",
247
+ "double zero": "00",
248
+ "double one": "11",
249
+ "double two": "22",
250
+ "double three": "33",
251
+ "double four": "44",
252
+ "double five": "55",
253
+ "double six": "66",
254
+ "double seven": "77",
255
+ "double eight": "88",
256
+ "double nine": "99",
257
+ "for": "4", "to": "2", "too": "2",
258
+ "nite": "9", "fiv": "5",
259
+
260
+ # 🔹 Repeated Digits
261
+ "واحد واحد": "11",
262
+ "اثنين اثنين": "22",
263
+ "اتنين اتنين": "22",
264
+ "ثلاثة ثلاثة": "33",
265
+ "تلاتة تلاتة": "33",
266
+ "أربعة أربعة": "44",
267
+ "اربعة اربعة": "44",
268
+ "خمسة خمسة": "55",
269
+ "ستة ستة": "66",
270
+ "سبعة سبعة": "77",
271
+ "ثمانية ثمانية": "88",
272
+ "تمانية تمانية": "88",
273
+ "تسعة تسعة": "99",
274
+
275
+ # 🔹 Hundreds
276
+ "مئة": "100",
277
+ "مية": "100",
278
+ "مئتين": "200",
279
+ "ميتين": "200",
280
+ "ثلاثمية": "300",
281
+ "تلتمية": "300",
282
+ "أربعمية": "400",
283
+ "اربعمية": "400",
284
+ "خمسمية": "500",
285
+ "ستمية": "600",
286
+ "سبعمية": "700",
287
+ "تمانمية": "800",
288
+ "تسعمية": "900",
289
+
290
+ # 🔹 Teens
291
+ "أحد عشر": "11",
292
+ "حداشر": "11",
293
+ "اثنا عشر": "12",
294
+ "اتناشر": "12",
295
+ "ثلاثة عشر": "13",
296
+ "تلاتاشر": "13",
297
+ "أربعة عشر": "14",
298
+ "اربعتاشر": "14",
299
+ "خمسة عشر": "15",
300
+ "خمسطاشر": "15",
301
+ "ستة عشر": "16",
302
+ "ستاشر": "16",
303
+ "سبعة عشر": "17",
304
+ "سبعتاشر": "17",
305
+ "ثمانية عشر": "18",
306
+ "طمنتاشر": "18",
307
+ "تسعة عشر": "19",
308
+ "تسعتاشر": "19",
309
+
310
+ # 🔹 Tens
311
+ "عشرين": "20",
312
+ "تلاتين": "30",
313
+ "ثلاثين": "30",
314
+ "أربعين": "40",
315
+ "اربعين": "40",
316
+ "خمسين": "50",
317
+ "ستين": "60",
318
+ "سبعين": "70",
319
+ "ثمانين": "80",
320
+ "تمانين": "80",
321
+ "ثامنين": "80",
322
+ "تسعين": "90",
323
+
324
+ # 🔹 Mixed Word + Digits
325
+ "خمسة صفر": "50",
326
+ "ثلاثة صفر صفر": "300",
327
+ "تلاتة صفر صفر": "300",
328
+ "واحد صفر": "10",
329
+ "واحد صفر واحد": "101",
330
+ "واحد اثنين": "12",
331
+ "واحد اتنين": "12",
332
+ "واحد ثلاثة": "13",
333
+ "واحد تلاتة": "13",
334
+ "واحد خمسة": "15",
335
+ "عشرة عشرة": "1010",
336
+ # Zero
337
+ "صفر": "0",
338
+ "زيرو": "0",
339
+ "زيو": "0",
340
+ "٠": "0",
341
+
342
+ # One
343
+ "واحد": "1",
344
+ "واحدة": "1",
345
+ "١": "1",
346
+
347
+ # Two
348
+ "اتنين": "2",
349
+ "اتنين": "2",
350
+ "اثنين": "2",
351
+ "اثنان": "2",
352
+ "٢": "2",
353
+
354
+ # Three
355
+ "تلاتة": "3",
356
+ "تلات": "3",
357
+ "ثلاثة": "3",
358
+ "ثلاث": "3",
359
+ "٣": "3",
360
+
361
+ # Four
362
+ "اربعة": "4",
363
+ "أربعة": "4",
364
+ "٤": "4",
365
+
366
+ # Five
367
+ "خمسة": "5",
368
+ "خمسه": "5",
369
+ "٥": "5",
370
+
371
+ # Six
372
+ "ستة": "6",
373
+ "ست": "6",
374
+ "٦": "6",
375
+
376
+ # Seven
377
+ "سبعة": "7",
378
+ "سبعه": "7",
379
+ "٧": "7",
380
+
381
+ # Eight
382
+ "تمانية": "8",
383
+ "تمنية": "8",
384
+ "ثمانية": "8",
385
+ "ثماني": "8",
386
+ "ثمان": "8",
387
+ "ثمانيّة": "8",
388
+ "ثماني": "8",
389
+ "٨": "8",
390
+
391
+ # Nine
392
+ "تسعة": "9",
393
+ "تسعه": "9",
394
+ "٩": "9"
395
+ }
396
+
397
+ # ===== Helpers =====
398
+ def normalize_arabic(text: str) -> str:
399
+ diacritics = re.compile(r'[\u0617-\u061A\u064B-\u0652]')
400
+ text = re.sub(diacritics, '', text)
401
+ text = re.sub(r'[إأآا]', 'ا', text)
402
+ text = re.sub(r'ى', 'ي', text)
403
+ text = re.sub(r'ؤ', 'و', text)
404
+ text = re.sub(r'ئ', 'ي', text)
405
+ text = re.sub(r'ة', 'ه', text)
406
+ return text
407
+
408
+ def replace_arabic_numbers(text: str) -> str:
409
+ for word, digit in arabic_numbers.items():
410
+ text = re.sub(fr"(?:^|\s){word}(?:$|\s)", f" {digit} ", text, flags=re.IGNORECASE)
411
+ return " ".join(text.split())
412
+
413
+ def join_digit_sequences(text: str) -> str:
414
+ tokens = text.split()
415
+ out, buffer = [], []
416
+ for tok in tokens:
417
+ if tok.isdigit() and len(tok) == 1:
418
+ buffer.append(tok)
419
+ else:
420
+ if buffer:
421
+ out.append("".join(buffer)) # join sequences like 8 5 -> 85
422
+ buffer = []
423
+ out.append(tok)
424
+ if buffer:
425
+ out.append("".join(buffer))
426
+ return " ".join(out)
427
+
428
+ def ensure_16k_wav(input_path, output_path):
429
+ y, sr = librosa.load(input_path, sr=16000, mono=True)
430
+ sf.write(output_path, y, 16000)
431
+
432
+ # ===== FastAPI app =====
433
+ app = FastAPI(title="Arabic ASR API", description="ASR API with NeMo and Arabic/English digit conversion")
434
+
435
+ @app.on_event("startup")
436
+ def load_model():
437
+ global asr_model
438
+ model_path = "C:/Users/thegh/Python_Projects/Expertflow/UnderProgress/Peter_Projects/NP_Detection_Nvidia_conformer/stt_ar_fastconformer_hybrid_large_pc_v1.0.nemo"
439
+ asr_model = nemo_asr.models.EncDecCTCModel.restore_from(model_path)
440
+
441
+ @app.post("/transcribe")
442
+ async def transcribe_audio(file: UploadFile = File(...)):
443
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
444
+ tmp.write(await file.read())
445
+ tmp_path = tmp.name
446
+
447
+ resampled_path = tmp_path.replace(".wav", "_16k.wav")
448
+ ensure_16k_wav(tmp_path, resampled_path)
449
+
450
+ try:
451
+ result = asr_model.transcribe([resampled_path])
452
+ raw_text = result[0].text
453
+ print(raw_text)
454
+ raw_text = normalize_arabic(raw_text)
455
+ cleaned_text = replace_arabic_numbers(raw_text)
456
+ cleaned_text = join_digit_sequences(cleaned_text)
457
+
458
+ return JSONResponse(content={"transcription": cleaned_text})
459
+
460
+ finally:
461
+ os.remove(tmp_path)
462
+ if os.path.exists(resampled_path):
463
+ os.remove(resampled_path)
464
+
465
+ @app.post("/transcribe-bytes")
466
+ async def transcribe_audio_bytes(audio_bytes: bytes = File(...)):
467
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
468
+ tmp.write(audio_bytes)
469
+ tmp_path = tmp.name
470
+
471
+ resampled_path = tmp_path.replace(".wav", "_16k.wav")
472
+ ensure_16k_wav(tmp_path, resampled_path)
473
+
474
+ try:
475
+ result = asr_model.transcribe([resampled_path])
476
+ raw_text = result[0].text
477
+
478
+ raw_text = normalize_arabic(raw_text)
479
+ cleaned_text = replace_arabic_numbers(raw_text)
480
+ cleaned_text = join_digit_sequences(cleaned_text)
481
+
482
+ return JSONResponse(content={"transcription": cleaned_text})
483
+
484
+ finally:
485
+ os.remove(tmp_path)
486
+ if os.path.exists(resampled_path):
487
+ os.remove(resampled_path)
488
+
489
+ if __name__ == "__main__":
490
+ uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)
arabic_recording.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:69e69f1a8dfd83a548a609c1b1f0b82a112447c598e71a7120c50cf599f5982a
3
+ size 320044
creating env.txt ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ python -m venv asr_env
2
+ Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
3
+ asr_env\Scripts\activate
4
+ pip install nemo_toolkit sounddevice scipy
5
+ pip install hydra-core==1.3.2
6
+ pip install lightning==2.2.1
7
+ pip install lhotse
8
+ pip install einops
9
+ pip install transformers
10
+ pip install sentencepiece
11
+ pip install pandas
12
+ pip install jiwer
13
+ pip install librosa
14
+ pip install webdataset
15
+ pip install webdataset
16
+ pip install pyannote.core
17
+ pip install pyannote.audio
18
+ pip install datasets
19
+ pip install editdistance
20
+ pip install ipython
21
+ pip install huggingface_hub==0.34.4
22
+
23
+ $env:NEMO_MODEL_PATH="C:\Users\Administrator\Projects\NP_nvidia_conformer\stt_ar_fastconformer_hybrid_large_pcd_v1.0.nemo"
24
+
25
+ python -m streamlit run app.py
26
+ python -m uvicorn app_api:app --host 0.0.0.0 --port 8070 --reload
main.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sounddevice as sd
2
+ import scipy.io.wavfile as wav
3
+ import nemo.collections.asr as nemo_asr
4
+
5
+ # ===== SETTINGS =====
6
+ SAMPLE_RATE = 16000
7
+ DURATION = 10 # seconds
8
+ OUTPUT_FILE = "arabic_recording.wav"
9
+
10
+ # ===== STEP 1: Record audio =====
11
+ print("🎙️ Recording... Speak Arabic now!")
12
+ audio = sd.rec(int(SAMPLE_RATE * DURATION), samplerate=SAMPLE_RATE, channels=1, dtype='int16')
13
+ sd.wait()
14
+ wav.write(OUTPUT_FILE, SAMPLE_RATE, audio)
15
+ print(f"✅ Recording finished. Saved as {OUTPUT_FILE}")
16
+
17
+ # ===== STEP 2: Load ASR model =====
18
+ print("📥 Loading Arabic ASR model...")
19
+ asr_model = nemo_asr.models.EncDecCTCModel.restore_from("C:/Users/thegh/Python_Projects/Expertflow/UnderProgress/Peter_Projects/nvidia_asr_eg_conformer_better_than_whisper/stt_ar_fastconformer_hybrid_large_pcd_v1.0.nemo")
20
+
21
+ # ===== STEP 3: Transcribe =====
22
+ print("🔍 Transcribing...")
23
+ transcription = asr_model.transcribe([OUTPUT_FILE])
24
+ print("📝 Transcription:", transcription[0])
nid.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:28196f306c4203691a675aba248cee8b1b6086e25cc6b1b0f6e80b6f15f6d203
3
+ size 480044
pn.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e27d4d2bbfdb49ddb5258ef3f69c670de01c165ae5311b0d1b7562a66109cd0d
3
+ size 480044
recordings/case_name_20250909_144019.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e4ce60742dcc7e7cf5dd5471a658c96bb3a56b70fe87ab6d41cb045d063f63e0
3
+ size 480044
recordings/case_name_20250909_144453.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:69e656cf7ac6c438217ee245b5dce11a7de1770c86f3ec177bca741ae9dbd834
3
+ size 480044
recordings/case_name_20250909_155450.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d602dce673c8040b7067e7d4e025e74c5f85a066a872539e0c97cae14ae045ae
3
+ size 320044
recordings/case_name_20250909_155812.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:593675815f80e5378f9dc7570ae0b54723c74579f1c8e704db1377210cea1c8b
3
+ size 320044
recordings/case_name_20250909_155921.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:deccab7fd347d90086229df8a76f102e729dc18e77ddc9ef8dd2a6118a735c58
3
+ size 320044
recordings/case_name_20250909_170323.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:35c686a2d39bde06e7946d1c62f0cbd4f38db3621d198ea3ab8caaa80ff8fd24
3
+ size 320044
recordings/case_name_20250909_170702.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d5b1f0f2e7d90b7b543f1a73c01381cae3dcd13d53d4ba7602c8015b9c31c740
3
+ size 320044
recordings/case_name_20250924_200610.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a1cce3c759d3c8110677f55c305b03cf32f2513bc87d4e264236df917c1421d1
3
+ size 320044
recordings/name_20250909_143929.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1cb4526915aa263eb641995eda73f3f97d8fa64ef392eed3d7c78ec26de28979
3
+ size 480044
recordings/name_20250909_143955.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c18f7c0ddc66ee22faeb556e19685644f6fdba42da151951917d12066e12ca4b
3
+ size 480044
recordings/name_20250909_144405.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:156343600d42c617bc6ff3e0cf8d9a5b2496c669c3df5dd6198da2edc8789918
3
+ size 480044
recordings/name_20250909_144432.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:17111b91c15186023b981d90f78e019ba5a08732f55829152b95e908de85e731
3
+ size 480044
recordings/name_20250909_155412.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b3e235ff08dd58ac4473dcb61830b3efadaa592c3d8e119db6afe2292a5cde6b
3
+ size 320044
recordings/name_20250909_155430.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e1d997cb4c861a5c85d0496bd40519b60af65fd46ae0c78fbcc7114a6e6fe6d3
3
+ size 320044
recordings/name_20250909_155755.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6019ed92a9f018cf134d2a71977c7ee4ab9606254877c74b025a2f0e8a423ab2
3
+ size 320044
recordings/name_20250909_155905.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:20406885f1d603e292978be8f3ed00e04033c60f9470aa6b0d885bad475155e3
3
+ size 320044
recordings/name_20250909_170307.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a5d0089543ca5d0a4ef73966f5489e328aae57b68e2a06de4d52e3536e654307
3
+ size 320044
recordings/name_20250909_170647.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4f7f0f07b624e56ac63207a23d2e54acf0b8d674b00777874001a8878657e360
3
+ size 320044
recordings/name_20250924_200542.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:581257c00e8111835069ddb373793339857b4033735e1409b955e06b82d776bc
3
+ size 320044
recordings/name_20250924_202837.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:06fe7a6dff2e570391f4e6821c77e5963813dfd8767b37ecc9caf21d144b25ac
3
+ size 320044
recordings/nid_20250909_142059.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:38ed48894135e6f92e0e428f27c176a79cd7519c83c3d685321cd22bb42e5b58
3
+ size 480044
recordings/nid_20250909_143513.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7c30475287c68770f2b71157faaf1d5ea707e15ceda672133f89f87c0b4756b7
3
+ size 480044
recordings/nid_20250909_143739.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fae5fac2e1507ca414e7d49ac2a0160ec2aa4899729ba489e101569c26498103
3
+ size 480044
recordings/nid_20250909_143835.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0effbb67fb0a569061feaf7cc7aad9ab765a8de3ce79db6c0d2ffd753456ecdb
3
+ size 480044
recordings/nid_20250909_143901.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e04c0a855fa4daae2f3f9217279a03618f8285dedddd3b245463e67789e4d0f0
3
+ size 480044
recordings/nid_20250909_144232.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:66f4b88a1e24a6e7e1f40858c1cf47bb6713ea628b8490e7734fc2571f799d9b
3
+ size 480044
recordings/nid_20250909_144254.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a84fd4e3de934c50349878b256eb444ae495ff4a00ae3469612cace2065f0e56
3
+ size 480044
recordings/nid_20250909_144321.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3678e8e832a55cd6e26f0ff60e2b981fb930aab9ccd17b4c9b1cff812bfa408c
3
+ size 480044
recordings/nid_20250909_144751.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:059c44a3e513b9bcf2f291332cac08d85916eda6d7f9e9255aaa9ed6039dc397
3
+ size 480044
recordings/nid_20250909_144821.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c9f22ca10b2d76de478d19059d28dd069b7ec5ccacfeacedbf72428fa5ba5097
3
+ size 480044
recordings/nid_20250909_144845.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a3032493cce45f28cafa105889849b8f36297bce8b26f3f7efe12b2f672c41db
3
+ size 480044
recordings/nid_20250909_155231.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e955511fc29e4b2f79bc965500953a21c5c7783ce0d056c9a31691011eb86be6
3
+ size 320044
recordings/nid_20250909_155548.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:16f2c641707582dd46b23bb5a9052ccb26c9bdc037c5598cc0f08f4890caf0fa
3
+ size 320044
recordings/nid_20250909_155608.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dbabc607909fdcb37e038bb219fac5cd7ecf04e58ff5ea2e8c9c24e89911d210
3
+ size 320044
recordings/nid_20250909_155738.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:17e8c822b743d63feac8d1f73569f11c5e8c4c194570821d153dfdc04631e6e2
3
+ size 320044
recordings/nid_20250909_155849.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:874c046138aa8c4d027cf0ce7264be41eb9651073c68494ac97b4c9f13e646f5
3
+ size 320044
recordings/nid_20250909_165246.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6b34efe57fc87502dee62228601118b6deec6259dad5d87e66e4f5f2eec94106
3
+ size 320044
recordings/nid_20250909_165306.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:099771f6f816cb407a270cfad86ce6a95b6b9e7fc3ba9d0cca017adb462ac396
3
+ size 320044
recordings/nid_20250909_165751.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f5634375424dc750832e26d3d163d4417e2700165d676e3a50d2ff00205cbddc
3
+ size 320044
recordings/nid_20250909_165824.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e70a01a94969390a5f471606dcf8fd09717eda39f24aff14a48178a7b33cded6
3
+ size 320044