-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathASR.bas
More file actions
386 lines (371 loc) · 13.1 KB
/
ASR.bas
File metadata and controls
386 lines (371 loc) · 13.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
B4J=true
Group=Default Group
ModulesStructureVersion=1
Type=StaticCode
Version=8.9
@EndOfDesignText@
'Static code module
Sub Process_Globals
Private fx As JFX
Private sh As Shell
Private mCallback As Object
Private mEventName As String
Private mSize As Int
Private mCurrentIndex As Double
Private stdOutStep As Double = 0.5
End Sub
Public Sub GetParams(engine As String) As ResumableSub
Dim note As String
If engine = "whisper" Then
note = $"
-gpu, --use-gpu The graphic adapter to use for inference
-t N, --threads N [4 ] number of threads to use during computation
-p N, --processors N [1 ] number of processors to use during computation
-ot N, --offset-t N [0 ] time offset in milliseconds
-on N, --offset-n N [0 ] segment index offset
-d N, --duration N [0 ] duration of audio to process in milliseconds
-mc N, --max-context N [-1 ] maximum number of text context tokens to store
-ml N, --max-len N [0 ] maximum segment length in characters
-wt N, --word-thold N [0.01 ] word timestamp probability threshold
-su, --speed-up [false ] speed up audio by x2 (reduced accuracy)
-tr, --translate [false ] translate from source language to english
-l LANG, --language LANG [en ] spoken language
-m FNAME, --model FNAME [models/ggml-base.en.bin] model path
--prompt initial prompt for the model
"$
Else
If getASRPluginList.IndexOf(engine)<>-1 Then
Dim params As Map
params.Initialize
params.Put("preferencesMap",Utils.getPrefMap)
wait for (Main.plugin.RunPlugin(engine&"ASR","getParamsNote",params)) complete (note As String)
End If
End If
Return note
End Sub
Public Sub RecognizeCutAsSpeechLines(dir As String,filename As String,startTime As String,endTime As String,lang As String,engine As String) As ResumableSub
wait for (FFMpeg.CutWav(dir,filename,"cut.wav",startTime,endTime)) Complete (done As Object)
File.Copy(dir,"cut.wav",dir,"cut-o.wav")
wait for (FFMpeg.AddPadding(dir,"cut-o.wav","cut.wav",2)) complete (done As Object)
File.Delete(dir,"cut-o.wav")
Wait For (RecognizeWavAsSpeechLines(File.Combine(dir,"cut.wav"),lang,engine)) Complete (lines As List)
File.Delete(dir,"cut.wav.srt")
File.Delete(dir,"cut.srt")
Return lines
End Sub
Public Sub RecognizeCut(dir As String,filename As String,startTime As String,endTime As String,lang As String,engine As String) As ResumableSub
wait for (FFMpeg.CutWav(dir,filename,"cut.wav",startTime,endTime)) Complete (done As Object)
File.Copy(dir,"cut.wav",dir,"cut-o.wav")
wait for (FFMpeg.AddPadding(dir,"cut-o.wav","cut.wav",2)) complete (done As Object)
File.Delete(dir,"cut-o.wav")
Wait For (RecognizeWavAsText(File.Combine(dir,"cut.wav"),lang,engine)) Complete (str As String)
File.Delete(dir,"cut.wav.srt")
File.Delete(dir,"cut.srt")
Return str
End Sub
Public Sub RecognizeWavAsSpeechLines(filepath As String,lang As String,engine As String) As ResumableSub
wait for (RecognizeWav(filepath,lang,engine)) complete (done As Object)
Dim filename As String = File.GetName(filepath)
Dim dir As String = File.GetFileParent(filepath)
Dim content As String
If File.Exists(dir,filename&".srt") Then
content = File.ReadString(dir,filename&".srt")
End If
If File.Exists(dir,Utils.GetFilenameWithoutExtension(filename)&".srt") Then
content = File.ReadString(dir,Utils.GetFilenameWithoutExtension(filename)&".srt")
End If
content = Utils.RemoveBOM(content)
Dim parser As SrtParser
parser.Initialize
Dim parsedlines As List = parser.Parse(content)
Dim simpleChinese As Boolean = False
Dim traditionalChinese As Boolean = False
Dim cc As OpenCC
If Utils.getPref("convert_chinese_base_on_source_lang",True) Then
If lang == "zh" Or lang == "zh-CN" Then
simpleChinese = True
cc.Initialize
End If
If lang == "zh-TW" Then
traditionalChinese = True
cc.Initialize
End If
End If
If cc.IsInitialized Then
For Each line As SpeechLine In parsedlines
If simpleChinese Then
line.text = cc.ConvertToSimple(line.text)
else if traditionalChinese Then
line.text = cc.ConvertToTraditional(line.text)
End If
Next
End If
Return parsedlines
End Sub
Public Sub RecognizeWavAsText(filepath As String,lang As String,engine As String) As ResumableSub
wait for (RecognizeWav(filepath,lang,engine)) complete (done As Object)
Dim filename As String = File.GetName(filepath)
Dim dir As String = File.GetFileParent(filepath)
Dim content As String
If File.Exists(dir,filename&".srt") Then
content = File.ReadString(dir,filename&".srt")
End If
If File.Exists(dir,Utils.GetFilenameWithoutExtension(filename)&".srt") Then
content = File.ReadString(dir,Utils.GetFilenameWithoutExtension(filename)&".srt")
End If
content = Utils.RemoveBOM(content)
Dim parser As SrtParser
parser.Initialize
Dim parsedlines As List = parser.Parse(content)
Dim sb As StringBuilder
sb.Initialize
For Each parsedline As SpeechLine In parsedlines
sb.Append(parsedline.text)
Next
Dim text As String = sb.ToString
Dim simpleChinese As Boolean = False
Dim traditionalChinese As Boolean = False
Dim cc As OpenCC
If Utils.getPref("convert_chinese_base_on_source_lang",True) Then
If lang == "zh" Or lang == "zh-CN" Then
simpleChinese = True
cc.Initialize
End If
If lang == "zh-TW" Then
traditionalChinese = True
cc.Initialize
End If
End If
If cc.IsInitialized Then
If simpleChinese Then
text = cc.ConvertToSimple(text)
else if traditionalChinese Then
text = cc.ConvertToTraditional(text)
End If
End If
Return text
End Sub
Public Sub RenameWavFile(filepath As String)
Dim pureFilepath As String = Utils.GetFilenameWithoutExtension(filepath)
Dim desiredSRTPath As String = filepath&".srt"
If File.Exists(pureFilepath&".srt","") Then
File.Copy(pureFilepath&".srt","",desiredSRTPath,"")
File.Delete(pureFilepath&".srt","")
End If
End Sub
Public Sub RecognizeWav(filepath As String,lang As String,engine As String) As ResumableSub
If engine = "whisper" Then
If lang.StartsWith("zh") Then
lang = "zh"
End If
Dim args As List
args.Initialize
Dim prompt As String = Utils.getSetting("prompt","")
Dim extraParams As String = Utils.getSetting("extra_params","")
If prompt <> "" Then
args.Add("--prompt")
args.Add(prompt)
End If
Dim hasLang As Boolean = False
If extraParams <> "" Then
For Each param As String In Regex.Split(" ",extraParams)
args.Add(param)
If param == "-l" Then
hasLang = True
End If
Next
End If
args.AddAll(Array("-m",GetModelPath,"-f",filepath,"-osrt"))
If hasLang = False Then
args.AddAll(Array("-l",lang))
End If
Dim sh As Shell
sh.Initialize("sh",GetWhisperPath,args)
sh.WorkingDirectory = File.DirApp
sh.Run(-1)
wait for sh_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
Log(StdOut)
Log(StdErr)
RenameWavFile(filepath)
If ExitCode <> 0 Then
Utils.ReportError(StdOut&StdErr)
End If
Return Success
Else
If getASRPluginList.IndexOf(engine)<>-1 Then
Dim params As Map
params.Initialize
params.Put("path",filepath)
params.Put("lang",lang)
params.Put("extraParams",Utils.getSetting("extra_params",""))
params.Put("preferencesMap",Utils.getPrefMap)
wait for (Main.plugin.RunPlugin(engine&"ASR","recognize",params)) complete (lines As List)
Dim convertedLines As List
convertedLines.Initialize
For Each line As Map In lines
Dim converted As Map
converted.Initialize
converted.Put("startTime",Utils.GetTimeStringFromMilliseconds(line.Get("start")*1000))
converted.Put("endTime",Utils.GetTimeStringFromMilliseconds(line.Get("end")*1000))
converted.Put("source",line.Get("text"))
converted.Put("target","")
convertedLines.Add(converted)
Next
Exporter.ExportToSRT(convertedLines,filepath&".srt",False,0)
Return True
End If
End If
Return False
End Sub
Public Sub RecognizeWavWithProgressInfo(callback As Object, eventname As String, filepath As String,lang As String,engine As String,size As Int) As ResumableSub
mCallback = callback
mEventName = eventname
mCurrentIndex = 0
mSize = size
If engine = "whisper" Then
If lang.StartsWith("zh") Then
lang = "zh"
End If
Dim args As List
args.Initialize
Dim prompt As String = Utils.getSetting("prompt","")
Dim extraParams As String = Utils.getSetting("extra_params","")
If prompt <> "" Then
args.Add("--prompt")
args.Add(prompt)
End If
Dim hasLang As Boolean = False
If extraParams <> "" Then
For Each param As String In Regex.Split(" ",extraParams)
args.Add(param)
If param == "-l" Then
hasLang = True
End If
Next
End If
args.AddAll(Array("-m",GetModelPath,"-f",filepath,"-osrt"))
If hasLang = False Then
args.AddAll(Array("-l",lang))
End If
Dim sh As Shell
sh.Initialize("sh",GetWhisperPath,args)
sh.WorkingDirectory = File.DirApp
sh.RunWithOutputEvents(-1)
wait for sh_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
Log(StdOut)
Log(StdErr)
If ExitCode <> 0 Then
Utils.ReportError(StdOut&StdErr)
End If
Return Success
Else
If getASRPluginList.IndexOf(engine)<>-1 Then
Dim params As Map
params.Initialize
params.Put("path",filepath)
params.Put("lang",lang)
params.Put("extraParams",Utils.getSetting("extra_params",""))
params.Put("preferencesMap",Utils.getPrefMap)
wait for (Main.plugin.RunPlugin(engine&"ASR","recognizeLongFile",params)) complete (done As Object)
Do While True
Sleep(1000)
Log("run get progress")
wait for (Main.plugin.RunPlugin(engine&"ASR","getProgress",params)) complete (progressMap As Map)
Log(progressMap)
If progressDialog.isShowing = False Then
wait for (Main.plugin.RunPlugin(engine&"ASR","stop",params)) complete (done As Object)
Return False
End If
Dim current As Double = progressMap.Get("current")
Dim total As Double = progressMap.Get("total")
Dim normalizedCurrent As Int = 100/total*current
If SubExists(mCallback,mEventName&"_ProgressChanged") Then
CallSubDelayed3(mCallback,mEventName&"_ProgressChanged", normalizedCurrent, 100)
End If
If current == total And current <> -1 Then
Exit
End If
Loop
wait for (Main.plugin.RunPlugin(engine&"ASR","getResult",params)) complete (lines As List)
Log(lines)
Dim convertedLines As List
convertedLines.Initialize
For Each line As Map In lines
Dim converted As Map
converted.Initialize
converted.Put("startTime",Utils.GetTimeStringFromMilliseconds(line.Get("start")*1000))
converted.Put("endTime",Utils.GetTimeStringFromMilliseconds(line.Get("end")*1000))
converted.Put("source",line.Get("text"))
converted.Put("target","")
convertedLines.Add(converted)
Next
Exporter.ExportToSRT(convertedLines,filepath&".srt",False,0)
Return True
End If
End If
Return False
End Sub
Private Sub sh_StdOut (Buffer() As Byte, Length As Int)
Log("StdOut")
Log(Length)
Dim bc As ByteConverter
Dim s As String = bc.StringFromBytes(Buffer,"UTF-8")
Log(s)
mCurrentIndex = mCurrentIndex + stdOutStep
mCurrentIndex = Min(mSize,mCurrentIndex)
File.WriteString(File.DirApp,"progress",s)
If SubExists(mCallback,mEventName&"_ProgressChanged") Then
CallSubDelayed3(mCallback,mEventName&"_ProgressChanged", mCurrentIndex, mSize)
End If
End Sub
Public Sub GetWhisperPath As String
stdOutStep = 0.5
If Utils.DetectOS <> "windows" Then
If Utils.getPref("use_gpu",True) Then
Return File.Combine(File.Combine(File.DirApp,"whisper"),"whisper")
Else
Return File.Combine(File.Combine(File.DirApp,"whisper"),"whisper-cpu")
End If
Else
If Utils.getPref("use_gpu",True) Then
stdOutStep = 1
Return File.Combine(File.Combine(File.DirApp,"whisper"),"main.exe")
Else
Return File.Combine(File.Combine(File.Combine(File.DirApp,"whisper"),"cpp"),"whisper-cli.exe")
End If
End If
End Sub
Public Sub GetModelPath As String
If Utils.getPrefMap.ContainsKey("whisper_model_path") Then
Return Utils.getPrefMap.Get("whisper_model_path")
End If
Dim modelDir As String = File.Combine(File.DirApp,"models")
Dim modelName As String = "ggml-medium.bin"
If File.Exists(modelDir,"model") Then
modelName = File.ReadString(modelDir,"model").Trim
End If
If File.Exists(modelDir,modelName) = False Then
For Each filename As String In File.ListFiles(modelDir)
If filename.EndsWith(".bin") Then
modelName = filename
Exit
End If
Next
End If
Return File.Combine(modelDir,modelName)
End Sub
Public Sub KillCurrentShell
If sh.IsInitialized Then
sh.KillProcess
End If
End Sub
Sub getASRPluginList As List
Dim asrList As List
asrList.Initialize
For Each name As String In Main.plugin.GetAvailablePlugins
If name.EndsWith("ASR") Then
asrList.Add(name.Replace("ASR",""))
End If
Next
Return asrList
End Sub