unit MainForm; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, Vcl.ExtCtrls, System.SyncObjs, System.Math, Vcl.Samples.Spin, CaptureSTT; type TForm1 = class(TForm) Button1: TButton; ResultMemo: TMemo; RmsBar: TProgressBar; RmsTimer: TTimer; UpdateButton: TButton; SilenceEdit: TSpinEdit; OptsMemo: TMemo; LoggingCheckBox: TCheckBox; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormDestroy(Sender: TObject); procedure RmsTimerTimer(Sender: TObject); procedure SilenceEditChange(Sender: TObject); procedure UpdateButtonClick(Sender: TObject); private fCaptureThread: TAudioCaptureThread; fWorker: TTranscriptionWorker; procedure Log(const AMsg: string); procedure HandleTranscriptionResult(const AText: string); public end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin RmsBar.Min := 0; RmsBar.Max := 100; // Initialize worker with result callback fWorker := TTranscriptionWorker.Create(HandleTranscriptionResult); // Default API options OptsMemo.Lines.Clear; OptsMemo.Lines.Add('language=de'); OptsMemo.Lines.Add('task=transcribe'); OptsMemo.Lines.Add('model=large-v3'); OptsMemo.Lines.Add('device=cuda'); OptsMemo.Lines.Add('device_index=0'); OptsMemo.Lines.Add('threads=0'); OptsMemo.Lines.Add('batch_size=8'); OptsMemo.Lines.Add('chunk_size=20'); OptsMemo.Lines.Add('compute_type=float16'); OptsMemo.Lines.Add('beam_size=5'); OptsMemo.Lines.Add('best_of=5'); OptsMemo.Lines.Add('patience=1'); OptsMemo.Lines.Add('length_penalty=1'); OptsMemo.Lines.Add('temperatures=0'); OptsMemo.Lines.Add('compression_ratio_threshold=2.4'); OptsMemo.Lines.Add('log_prob_threshold=-1'); OptsMemo.Lines.Add('no_speech_threshold=0.6'); OptsMemo.Lines.Add('initial_prompt=null'); OptsMemo.Lines.Add('suppress_tokens=-1'); OptsMemo.Lines.Add('suppress_numerals=false'); OptsMemo.Lines.Add('hotwords=Absatz'); OptsMemo.Lines.Add('vad_onset=0.5'); OptsMemo.Lines.Add('vad_offset=0.363'); end; procedure TForm1.FormDestroy(Sender: TObject); begin if Assigned(fCaptureThread) then begin fCaptureThread.Terminate; fCaptureThread.WaitFor; fCaptureThread.Free; end; if Assigned(fWorker) then begin fWorker.Terminate; fWorker.WaitFor; fWorker.Free; end; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if Assigned(fCaptureThread) then begin fCaptureThread.Terminate; fCaptureThread.WaitFor; end; end; procedure TForm1.Log(const AMsg: string); begin if LoggingCheckBox.Checked then ResultMemo.Lines.Add(FormatDateTime('hh:nn:ss', Now) + ': ' + AMsg); end; procedure TForm1.HandleTranscriptionResult(const AText: string); begin ResultMemo.Lines.Add(AText); end; procedure TForm1.Button1Click(Sender: TObject); begin if not Assigned(fCaptureThread) then begin fCaptureThread := TAudioCaptureThread.Create( fWorker, 'http://minerva.lan:8000/speech-to-text', OptsMemo.Lines, procedure(const Msg: string) begin TThread.Queue(nil, procedure begin Log(Msg); end); end ); // Apply initial silence settings SilenceEditChange(nil); fCaptureThread.Start; Button1.Caption := 'Stop Recording'; end else begin fCaptureThread.Terminate; fCaptureThread.WaitFor; FreeAndNil(fCaptureThread); Button1.Caption := 'Start Recording'; RmsBar.Position := 0; end; end; procedure TForm1.RmsTimerTimer(Sender: TObject); var rawRms: Integer; dbValue: Double; begin if Assigned(fCaptureThread) then begin rawRms := fCaptureThread.CurrentRms; if (rawRms > 0) then begin dbValue := 20 * Log10(rawRms / 32768); // Map -60dB..0dB to 0..100% RmsBar.Position := Max(0, Round((dbValue + 60) * (100 / 60))); end else RmsBar.Position := 0; end; end; procedure TForm1.SilenceEditChange(Sender: TObject); begin if Assigned(fCaptureThread) then fCaptureThread.RequiredSilencePackets := Max(1, SilenceEdit.Value * 10); end; procedure TForm1.UpdateButtonClick(Sender: TObject); begin if Assigned(fCaptureThread) then fCaptureThread.ForceUpload; end; end.