-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmicstate.c
140 lines (129 loc) · 3.86 KB
/
micstate.c
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
#include <math.h>
#include <Windows.h>
#include <UniversalSpeech.h>
#include <bass.h>
#include <stdbool.h>
#include <stdio.h>
#include <shlwapi.h>
#define ID_TRAY_ICON 101
#define ID_EXIT 102
#define ID_CHECK_HOTKEY 103
int min_level; // The minimum level (in dB) to indicate muted state.
bool load_config();
void check_mic_state();
LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
float linear_to_decibel(float linear);
void show_tray_icon(HWND hwnd, UINT id, HICON icon, LPCSTR message);
void destroy_tray_icon(HWND hwnd, UINT id);
void show_popup_menu(HWND hwnd);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow) {
if (!BASS_RecordInit(-1)) {
MessageBox(NULL, "Failed to initialize BASS.", "Error", MB_ICONERROR);
return 1;
}
if (!load_config()) {
MessageBox(NULL, "Couldn't load configuration.", "Error", MB_ICONERROR);
return 1;
}
WNDCLASS wc = {0};
wc.lpfnWndProc = wnd_proc;
wc.hInstance = hInstance;
wc.lpszClassName = "MicStateWNDClass";
RegisterClass(&wc);
HWND hwnd = CreateWindow(wc.lpszClassName, NULL, 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
HICON icon = LoadIcon(NULL, IDI_APPLICATION);
show_tray_icon(hwnd, ID_TRAY_ICON, icon, "MicState");
MSG msg = {0};;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnregisterHotKey(hwnd, ID_CHECK_HOTKEY);
destroy_tray_icon(hwnd, ID_TRAY_ICON);
return 0;
}
bool load_config() {
char min_level_str[16] = {0};
char config_path[MAX_PATH] = {0};
if (GetCurrentDirectory(sizeof(config_path), config_path) == 0) return false;
if (!PathCombine(config_path, config_path, "config.ini")) return false;
if (GetPrivateProfileString("settings", "min_level", NULL, min_level_str, sizeof(min_level_str), config_path) == 0) return false;
min_level = atoi(min_level_str);
return true;
}
void check_mic_state() {
HRECORD rec = BASS_RecordStart(0, 0, 0, NULL, NULL);
if (rec == 0) {
Beep(100, 100);
return;
}
Sleep(50);
float levels[2];
BASS_ChannelGetLevelEx(rec, levels, 1.0, BASS_LEVEL_MONO);
BASS_ChannelStop(rec);
int level = (int)linear_to_decibel(levels[0]);
speechSay(level <= min_level ? L"Muted" : L"Unmuted", TRUE);
}
LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
case WM_CREATE:
if (!RegisterHotKey(hwnd, ID_CHECK_HOTKEY, MOD_CONTROL | MOD_ALT | MOD_SHIFT, 'M')) {
MessageBox(NULL, "Failed to register hotkey!", "Error", MB_ICONERROR | MB_OK);
return -1;
}
break;
case WM_HOTKEY:
if (wp == ID_CHECK_HOTKEY) check_mic_state();
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case ID_TRAY_ICON:
switch (lp) {
case WM_LBUTTONDBLCLK:
case WM_LBUTTONDOWN:
case WM_RBUTTONDBLCLK:
case WM_RBUTTONDOWN:
show_popup_menu(hwnd);
break;
}
break;
case WM_COMMAND:
if (LOWORD(wp) == ID_EXIT) PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wp, lp);
}
return 0;
}
float linear_to_decibel(float linear) {
if (linear != 0.0f) return 20.0f * log10f(linear);
return -144.0f; // Effectively minus infinity
}
void show_tray_icon(HWND hwnd, UINT id, HICON icon, PCSTR message) {
NOTIFYICONDATA nd = {0};
nd.cbSize = sizeof(NOTIFYICONDATA);
nd.hWnd = hwnd;
nd.uID = id;
nd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nd.uCallbackMessage = ID_TRAY_ICON;
nd.hIcon = icon;
strncpy(nd.szTip, message, sizeof(nd.szTip) - 1);
Shell_NotifyIcon(NIM_ADD, &nd);
}
void destroy_tray_icon(HWND hwnd, UINT id) {
NOTIFYICONDATA nd = {0};
nd.cbSize = sizeof(NOTIFYICONDATA);
nd.hWnd = hwnd;
nd.uID = id;
Shell_NotifyIcon(NIM_DELETE, &nd);
}
void show_popup_menu(HWND hwnd) {
HMENU menu = CreatePopupMenu();
AppendMenu(menu, MF_STRING, ID_EXIT, "E&xit");
POINT cursor;
GetCursorPos(&cursor);
SetForegroundWindow(hwnd);
TrackPopupMenu(menu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, cursor.x, cursor.y, 0, hwnd, NULL);
DestroyMenu(menu);
}