summaryrefslogtreecommitdiffstats
path: root/Examples/WhisperDesktop/LoadModelDlg.cpp
diff options
context:
space:
mode:
authorKonstantin <const@const.me>2023-01-16 14:52:43 +0100
committerKonstantin <const@const.me>2023-01-16 14:52:43 +0100
commit8c4603c73675958efc960fbd4bb599a2909d106a (patch)
tree714dc6fc9a1672d5fd7f89676b97e10959662abc /Examples/WhisperDesktop/LoadModelDlg.cpp
parent990a8d0dbaefc996244097397259e92758b15cce (diff)
Source codes
Diffstat (limited to 'Examples/WhisperDesktop/LoadModelDlg.cpp')
-rw-r--r--Examples/WhisperDesktop/LoadModelDlg.cpp206
1 files changed, 206 insertions, 0 deletions
diff --git a/Examples/WhisperDesktop/LoadModelDlg.cpp b/Examples/WhisperDesktop/LoadModelDlg.cpp
new file mode 100644
index 0000000..1b2bf03
--- /dev/null
+++ b/Examples/WhisperDesktop/LoadModelDlg.cpp
@@ -0,0 +1,206 @@
+#include "stdafx.h"
+#include "LoadModelDlg.h"
+#include "Utils/miscUtils.h"
+#include "Utils/logger.h"
+
+constexpr int progressMaxInteger = 1024 * 8;
+
+HRESULT LoadModelDlg::show()
+{
+ auto res = DoModal( nullptr );
+ if( res == -1 )
+ return HRESULT_FROM_WIN32( GetLastError() );
+ if( res == IDOK )
+ {
+ HRESULT hr = appState.lastScreenLoad();
+ switch( hr )
+ {
+ case SCREEN_TRANSCRIBE:
+ case SCREEN_CAPTURE:
+ return hr;
+ default:
+ return SCREEN_TRANSCRIBE;
+ }
+ }
+ return S_OK;
+}
+
+LRESULT LoadModelDlg::OnInitDialog( UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
+{
+ // First DDX call, hooks up variables to controls.
+ DoDataExchange( false );
+
+ cbConsole.initialize( m_hWnd, IDC_CONSOLE, appState );
+ implPopulateCombobox( cbModelType, appState.source.impl );
+ modelPath.SetWindowTextW( appState.source.path );
+
+ HRESULT hr = work.create( this );
+ if( FAILED( hr ) )
+ {
+ CString text = L"CreateThreadpoolWork failed\n";
+ text += formatErrorMessage( hr );
+ ::MessageBox( m_hWnd, text, L"Unable to load the model", MB_OK | MB_ICONWARNING );
+ return TRUE;
+ }
+
+ editorsWindows.reserve( 5 );
+ editorsWindows = { modelPath, cbModelType, GetDlgItem( IDC_BROWSE ), GetDlgItem( IDOK ), GetDlgItem( IDCANCEL ) };
+ pendingWindows.reserve( 2 );
+ pendingWindows = { GetDlgItem( IDC_PENDING_TEXT ), progressBar };
+
+ progressBar.SetRange32( 0, progressMaxInteger );
+ progressBar.SetStep( 1 );
+
+ appState.setupIcon( this );
+ ATLVERIFY( CenterWindow() );
+ if( !appState.source.found || !appState.automaticallyLoadModel )
+ return 0;
+
+ // AppState.findModelSource() method has located model parameters in registry;
+ // Post a notification identical to the "OK" button click event.
+ PostMessage( WM_COMMAND, IDOK, (LPARAM)( GetDlgItem( IDOK ).m_hWnd ) );
+
+ return 0;
+}
+
+LRESULT LoadModelDlg::OnBrowse( UINT, INT, HWND, BOOL& bHandled )
+{
+ bHandled = TRUE;
+
+ CString path;
+ modelPath.GetWindowText( path );
+ if( !getOpenFileName( m_hWnd, L"Select a GGML Model File", L"Binary files (*.bin)\0*.bin\0\0", path ) )
+ return 0;
+
+ modelPath.SetWindowText( path );
+ appState.source.path = path;
+ return 0;
+}
+
+LRESULT LoadModelDlg::validationError( LPCTSTR message )
+{
+ reportError( m_hWnd, message, L"Unable to load the model" );
+ return 0;
+}
+
+LRESULT LoadModelDlg::validationError( LPCTSTR message, HRESULT hr )
+{
+ reportError( m_hWnd, message, L"Unable to load the model", hr );
+ return 0;
+}
+
+void LoadModelDlg::setPending( bool nowPending )
+{
+ const BOOL enable = nowPending ? FALSE : TRUE;
+ for( HWND w : editorsWindows )
+ ::EnableWindow( w, enable );
+
+ const int show = nowPending ? SW_NORMAL : SW_HIDE;
+ for( HWND w : pendingWindows )
+ ::ShowWindow( w, show );
+
+ if( nowPending )
+ progressBar.SetMarquee( TRUE, 0 );
+ else
+ progressBar.SetMarquee( FALSE, 0 );
+}
+
+LRESULT LoadModelDlg::OnOk( UINT, INT, HWND, BOOL& bHandled )
+{
+ modelPath.GetWindowText( path );
+ if( path.GetLength() <= 0 )
+ return validationError( L"Please select a model GGML file" );
+
+ {
+ CAtlFile file;
+ HRESULT hr = file.Create( path, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING );
+ if( FAILED( hr ) )
+ return validationError( L"Unable to open the model file", hr );
+
+ ULONGLONG cb = 0;
+ file.GetSize( cb );
+ appState.source.sizeInBytes = cb;
+ }
+
+ impl = implGetValue( cbModelType );
+ if( impl == (Whisper::eModelImplementation)0 )
+ return validationError( L"Please select a model type" );
+
+ setPending( true );
+ work.post();
+ return 0;
+}
+
+void __stdcall LoadModelDlg::poolCallback() noexcept
+{
+ CComPtr<Whisper::iModel> model;
+ clearLastError();
+ loadError = L"";
+ Whisper::sLoadModelCallbacks lmcb;
+ lmcb.cancel = nullptr;
+ lmcb.progress = &LoadModelDlg::progressCallback;
+ lmcb.pv = this;
+ HRESULT hr = Whisper::loadModel( path, impl, &lmcb, &model );
+ if( SUCCEEDED( hr ) )
+ appState.model = model;
+ else
+ getLastError( loadError );
+
+ this->PostMessage( WM_CALLBACK_STATUS, (WPARAM)hr );
+}
+
+HRESULT __stdcall LoadModelDlg::progressCallback( double val, void* pv ) noexcept
+{
+ LoadModelDlg& dialog = *(LoadModelDlg*)pv;
+ constexpr double mul = progressMaxInteger;
+ int pos = lround( mul * val );
+ dialog.progressBar.PostMessage( PBM_SETPOS, pos, 0 );
+ return S_OK;
+}
+
+LRESULT LoadModelDlg::OnCallbackStatus( UINT, WPARAM wParam, LPARAM, BOOL& bHandled )
+{
+ setPending( false );
+
+ bHandled = TRUE;
+ const HRESULT hr = (HRESULT)wParam;
+ if( FAILED( hr ) )
+ {
+ LPCTSTR failMessage = L"Error loading the model";
+ if( loadError.GetLength() > 0 )
+ {
+ CString tmp = failMessage;
+ tmp += L"\n";
+ tmp += loadError;
+ return validationError( tmp, hr );
+ }
+ else
+ return validationError( failMessage, hr );
+ }
+
+ appState.source.path = path;
+ appState.source.impl = impl;
+ appState.saveModelSource();
+
+ EndDialog( IDOK );
+ return 0;
+}
+
+LRESULT LoadModelDlg::OnHyperlink( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
+{
+ const UINT code = pnmh->code;
+ switch( code )
+ {
+ case NM_CLICK:
+ case NM_RETURN:
+ break;
+ default:
+ return 0;
+ }
+
+ PNMLINK pNMLink = (PNMLINK)pnmh;
+ LPCTSTR url = pNMLink->item.szUrl;
+ ShellExecute( NULL, L"open", url, NULL, NULL, SW_SHOW );
+ bHandled = TRUE;
+ return 0;
+} \ No newline at end of file