unit1.pas
5.9 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
unit Unit1;
{$mode objfpc}{$H+}
{$IFDEF DARWIN}
{$modeswitch objectivec1} {For getting resource directory}
{$ENDIF}
interface
uses
Classes, SysUtils, StrUtils, Forms, Controls,
Graphics, Dialogs, StdCtrls,
sherpa_onnx, ComCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
InitBtn: TButton;
ProgressBar: TProgressBar;
ResultMemo: TMemo;
StartBtn: TButton;
SelectFileDlg: TOpenDialog;
SelectFileBtn: TButton;
FileNameEdt: TEdit;
ProgressLabel: TLabel;
procedure FileNameEdtChange(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure InitBtnClick(Sender: TObject);
procedure SelectFileBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure StartBtnClick(Sender: TObject);
private
public
procedure UpdateResult(
Msg: AnsiString;
StartTime: Single;
StopTime: Single;
TotalDuration: Single);
procedure UpdateProgress(StopTime: Single; TotalDuration: Single);
procedure UpdateInitStatus(Status: AnsiString);
public
Vad: TSherpaOnnxVoiceActivityDetector;
OfflineRecognizer: TSherpaOnnxOfflineRecognizer;
end;
var
Form1: TForm1;
implementation
uses
my_worker,
my_init
{$IFDEF DARWIN}
,MacOSAll
,CocoaAll
{$ENDIF}
;
{See https://wiki.lazarus.freepascal.org/Locating_the_macOS_application_resources_directory}
{$IFDEF DARWIN}
{Note: The returned path contains a trailing /}
function GetResourcesPath(): AnsiString;
var
pathStr: shortstring;
status: Boolean = false;
begin
status := CFStringGetPascalString(CFStringRef(NSBundle.mainBundle.resourcePath), @pathStr, 255, CFStringGetSystemEncoding());
if status = true then
Result := pathStr + PathDelim
else
raise Exception.Create('Error in GetResourcesPath()');
end;
{$ENDIF}
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
StartBtn.Enabled := False;
SelectFileDlg.Filter := 'All Files|*.wav';
FileNameEdt.Enabled := False;
SelectFileBtn.Enabled := False;
ResultMemo.Lines.Add('1. It supports only 1 channel, 16-bit, 16000Hz wav files');
ResultMemo.Lines.Add('2. There should be no Chinese characters in the file path.');
ProgressBar.Position := 0;
ProgressLabel.Caption := '';
end;
procedure TForm1.StartBtnClick(Sender: TObject);
begin
if StartBtn.Caption = 'Stop' then
begin
if (MyWorkerThread <> nil) and not MyWorkerThread.Finished then
MyWorkerThread.Terminate;
StartBtn.Caption := 'Start';
Exit;
end;
ResultMemo.Lines.Clear();
ResultMemo.Lines.Add('Start processing');
ProgressBar.Position := 0;
ProgressLabel.Caption := Format('%d%%', [ProgressBar.Position]);
MyWorkerThread := TMyWorkerThread.Create(False, FileNameEdt.Text);
StartBtn.Caption := 'Stop';
end;
procedure TForm1.SelectFileBtnClick(Sender: TObject);
begin
if SelectFileDlg.Execute then
begin
FileNameEdt.Text := SelectFileDlg.FileName;
end;
end;
procedure TForm1.FileNameEdtChange(Sender: TObject);
begin
if FileExists(FileNameEdt.Text) then
StartBtn.Enabled := True
else
StartBtn.Enabled := False;
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
if (MyWorkerThread <> nil) and (not MyWorkerThread.Finished) then
begin
MyWorkerThread.Terminate;
MyWorkerThread.WaitFor;
end;
FreeAndNil(Vad);
FreeAndNil(OfflineRecognizer);
end;
procedure TForm1.UpdateProgress(StopTime: Single; TotalDuration: Single);
var
Percent: Single;
begin
if (StopTime <> 0) and (TotalDuration <> 0) then
begin
Percent := StopTime / TotalDuration * 100;
ProgressBar.Position := Round(Percent);
ProgressLabel.Caption := Format('%d%%', [ProgressBar.Position]);
end;
end;
procedure TForm1.UpdateResult(
Msg: AnsiString;
StartTime: Single;
StopTime: Single;
TotalDuration: Single);
var
NewResult: AnsiString;
begin
UpdateProgress(StopTime, TotalDuration);
if (Msg = 'DONE!') or
(Msg = 'Cancelled!') or
EndsStr('16-bit encoded wave files', Msg) or
EndsStr('. Please select a new file', Msg) then
begin
Form1.StartBtn.Caption := 'Start';
NewResult := Msg;
end
else
begin
NewResult := Format('%.3f -- %.3f %s', [StartTime, StopTime, Msg]);
end;
if Msg = 'DONE!' then
begin
ProgressBar.Position := 100;
ProgressLabel.Caption := '100%';
end;
Form1.ResultMemo.Lines.Add(NewResult);
end;
procedure TForm1.UpdateInitStatus(Status: AnsiString);
begin
if EndsStr('model is initialized succesfully!', Status) then
begin
Form1.ResultMemo.Lines.Add(Status);
Form1.ResultMemo.Lines.Add('Please select a 16000Hz wave file to generate subtiles');
Form1.ResultMemo.Lines.Add('You can download some test wave files from https://github.com/k2-fsa/sherpa-onnx/releases/tag/asr-models');
Form1.ResultMemo.Lines.Add('For instance:');
Form1.ResultMemo.Lines.Add(' Chinese test wave: https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/lei-jun-test.wav');
Form1.ResultMemo.Lines.Add(' English test wave: https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/Obama.wav');
FileNameEdt.Enabled := True;
SelectFileBtn.Enabled := True;
end
else
begin
ShowMessage(Status);
Form1.ResultMemo.Lines.Clear();
Form1.ResultMemo.Lines.Add('Please refer to');
Form1.ResultMemo.Lines.Add('https://k2-fsa.github.io/sherpa/onnx/lazarus/generate-subtitles.html#download-models');
Form1.ResultMemo.Lines.Add('for how to download models');
InitBtn.Enabled := True;
end;
end;
procedure TForm1.InitBtnClick(Sender: TObject);
var
ModelDir: AnsiString;
begin
{$IFDEF DARWIN}
ModelDir := GetResourcesPath;
{$ELSE}
ModelDir := './';
{$ENDIF}
Form1.ResultMemo.Lines.Clear();
ResultMemo.Lines.Add('Initializing the model. Please wait...');
MyInitThread := TMyInitThread.Create(False, ModelDir);
InitBtn.Enabled := False;
end;
end.