summaryrefslogtreecommitdiffstats
path: root/Examples/WhisperDesktop/CaptureDlg.h
blob: c66b10d114f763b2de8b06ad3cde452b34364732 (plain)
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
#pragma once
#include "AppState.h"
#include "Utils/WTL/atlddx.h"
#include "Utils/miscUtils.h"
#include "Utils/LanguageDropdown.h"
#include "Utils/TranslateCheckbox.h"
#include "Utils/PendingState.h"
#include "CircleIndicator.h"

class CaptureDlg :
	public CDialogImpl<CaptureDlg>,
	public CWinDataExchange<CaptureDlg>,
	public iThreadPoolCallback
{
	AppState& appState;

public:
	static constexpr UINT IDD = IDD_CAPTURE_DIALOG;
	static constexpr UINT WM_CALLBACK_COMPLETION = WM_APP + 1;
	static constexpr UINT WM_CALLBACK_STATUS = WM_APP + 2;

	CaptureDlg( AppState& app ) : appState( app ) { }

	HRESULT show();

	BEGIN_MSG_MAP( CaptureDlg )
		MESSAGE_HANDLER( WM_INITDIALOG, OnInitDialog )
		ON_BUTTON_CLICK( IDC_CONSOLE, cbConsole.click )
		ON_BUTTON_CLICK( IDC_DEV_REFRESH, onDeviceRefresh );
		ON_BUTTON_CLICK( IDC_BROWSE_RESULT, onBrowseResult );
		ON_BUTTON_CLICK( IDC_SAVE_TEXT, onSaveTextCheckbox );
		ON_BUTTON_CLICK( IDC_RUN_CAPTURE, onRunCapture );

		ON_BUTTON_CLICK( IDCANCEL, onClose )
		ON_BUTTON_CLICK( IDC_BACK, onBack )
		ON_BUTTON_CLICK( IDC_TRANSCRIBE, onTranscribe );

		MESSAGE_HANDLER( WM_CALLBACK_COMPLETION, onThreadQuit );
		MESSAGE_HANDLER( WM_CALLBACK_STATUS, onThreadStatus );
	END_MSG_MAP()

	BEGIN_DDX_MAP( CaptureDlg )
		DDX_CONTROL_HANDLE( IDC_DEVICE, cbCaptureDevice )
		DDX_CONTROL_HANDLE( IDC_RUN_CAPTURE, btnRunCapture );
		DDX_CONTROL_HANDLE( IDC_TRANSCRIBE_PROGRESS, progressBar );
		DDX_CONTROL_HANDLE( IDC_SAVE_TEXT, checkSave )
		DDX_CONTROL_HANDLE( IDC_SAVE_APPEND, checkAppend )
		DDX_CONTROL_HANDLE( IDC_SAVE_TIMESTAMPS, checkTimestamps )
		DDX_CONTROL_HANDLE( IDC_PATH_RESULT, transcribeOutputPath )
		DDX_CONTROL_HANDLE( IDC_BROWSE_RESULT, transcribeOutputBrowse );

		DDX_CONTROL( IDC_VOICE_ACTIVITY, voiceActivity );
		DDX_CONTROL( IDC_TRANS_STATUS, transcribeActivity );
		DDX_CONTROL( IDC_STALL_STATUS, stalled );
		
	END_DDX_MAP()

private:
	PendingState pendingState;
	void setPending( bool nowPending );

	LRESULT OnInitDialog( UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled );

	void onClose()
	{
		ATLVERIFY( EndDialog( IDCANCEL ) );
	}
	void onBack()
	{
		ATLVERIFY( EndDialog( IDC_BACK ) );
	}
	void onTranscribe()
	{
		ATLVERIFY( EndDialog( IDC_TRANSCRIBE ) );
	}

	// List capture devices, and populate the combobox
	bool listDevices();
	void onDeviceRefresh();
	bool selectDevice( LPCTSTR endpoint );

	static HRESULT __stdcall listDevicesCallback( int len, const Whisper::sCaptureDevice* buffer, void* pv ) noexcept;
	ConsoleCheckbox cbConsole;
	LanguageDropdown languageSelector;
	TranslateCheckbox cbTranslate;
	CComboBox cbCaptureDevice;

	void onBrowseResult();

	enum struct eTextFlags : uint32_t;
	CButton	checkSave, checkAppend, checkTimestamps;
	CEdit transcribeOutputPath;
	CButton transcribeOutputBrowse;
	void onSaveTextCheckbox();
	eTextFlags getOutputFlags();

	CButton btnRunCapture;
	CProgressBarCtrl progressBar;
	ThreadPoolWork work;

	struct sCaptureDevice
	{
		CString displayName;
		CString endpoint;
	};
	std::vector<sCaptureDevice> devices;

	void showError( LPCTSTR text, HRESULT hr );

	CircleIndicator voiceActivity;
	CircleIndicator transcribeActivity;
	CircleIndicator stalled;

	struct sThreadState
	{
		volatile bool stopRequested;
		bool translate;
		eTextFlags flags;
		CAtlFile* file;
		uint32_t language;
		Whisper::sCaptureParams captureParams;
		CString endpoint;
		CString textOutputPath;
		CString errorMessage;
	};
	sThreadState threadState;
	bool captureRunning = false;

	void getThreadError();
	void onRunCapture();
	HRESULT runCapture();
	void __stdcall poolCallback() noexcept override final;

	LRESULT onThreadQuit( UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
	LRESULT onThreadStatus( UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled );

	static HRESULT __stdcall cbCancel( void* pv ) noexcept;
	static HRESULT __stdcall cbStatus( void* pv, Whisper::eCaptureStatus status ) noexcept;

	static HRESULT __cdecl newSegmentCallback( Whisper::iContext* ctx, uint32_t n_new, void* user_data ) noexcept;

	HRESULT appendTextFile( Whisper::iTranscribeResult* results, uint32_t newSegments );
};