Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +180 -0
- Downloading model.txt +1 -0
- app.py +414 -0
- app_api.py +306 -0
- app_api_2.py +490 -0
- arabic_recording.wav +3 -0
- creating env.txt +26 -0
- main.py +24 -0
- nid.wav +3 -0
- pn.wav +3 -0
- recordings/case_name_20250909_144019.wav +3 -0
- recordings/case_name_20250909_144453.wav +3 -0
- recordings/case_name_20250909_155450.wav +3 -0
- recordings/case_name_20250909_155812.wav +3 -0
- recordings/case_name_20250909_155921.wav +3 -0
- recordings/case_name_20250909_170323.wav +3 -0
- recordings/case_name_20250909_170702.wav +3 -0
- recordings/case_name_20250924_200610.wav +3 -0
- recordings/name_20250909_143929.wav +3 -0
- recordings/name_20250909_143955.wav +3 -0
- recordings/name_20250909_144405.wav +3 -0
- recordings/name_20250909_144432.wav +3 -0
- recordings/name_20250909_155412.wav +3 -0
- recordings/name_20250909_155430.wav +3 -0
- recordings/name_20250909_155755.wav +3 -0
- recordings/name_20250909_155905.wav +3 -0
- recordings/name_20250909_170307.wav +3 -0
- recordings/name_20250909_170647.wav +3 -0
- recordings/name_20250924_200542.wav +3 -0
- recordings/name_20250924_202837.wav +3 -0
- recordings/nid_20250909_142059.wav +3 -0
- recordings/nid_20250909_143513.wav +3 -0
- recordings/nid_20250909_143739.wav +3 -0
- recordings/nid_20250909_143835.wav +3 -0
- recordings/nid_20250909_143901.wav +3 -0
- recordings/nid_20250909_144232.wav +3 -0
- recordings/nid_20250909_144254.wav +3 -0
- recordings/nid_20250909_144321.wav +3 -0
- recordings/nid_20250909_144751.wav +3 -0
- recordings/nid_20250909_144821.wav +3 -0
- recordings/nid_20250909_144845.wav +3 -0
- recordings/nid_20250909_155231.wav +3 -0
- recordings/nid_20250909_155548.wav +3 -0
- recordings/nid_20250909_155608.wav +3 -0
- recordings/nid_20250909_155738.wav +3 -0
- recordings/nid_20250909_155849.wav +3 -0
- recordings/nid_20250909_165246.wav +3 -0
- recordings/nid_20250909_165306.wav +3 -0
- recordings/nid_20250909_165751.wav +3 -0
- 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
|