1 /* in_flac - Winamp2 FLAC input plugin
\r
2 * Copyright (C) 2002,2003,2004,2005 Josh Coalson
\r
4 * This program is free software; you can redistribute it and/or
\r
5 * modify it under the terms of the GNU General Public License
\r
6 * as published by the Free Software Foundation; either version 2
\r
7 * of the License, or (at your option) any later version.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
14 * You should have received a copy of the GNU General Public License
\r
15 * along with this program; if not, write to the Free Software
\r
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
19 #include <windows.h>
\r
20 #include <commctrl.h>
\r
24 #include "resource.h"
\r
27 static char buffer[256];
\r
28 static char ini_name[MAX_PATH];
\r
34 #define RI(x, def) (x = GetPrivateProfileInt("FLAC", #x, def, ini_name))
\r
35 #define WI(x) WritePrivateProfileString("FLAC", #x, itoa(x, buffer, 10), ini_name)
\r
36 #define RS(x, n, def) GetPrivateProfileString("FLAC", #x, def, x, n, ini_name)
\r
37 #define WS(x) WritePrivateProfileString("FLAC", #x, x, ini_name)
\r
39 static const char default_format[] = "[%artist% - ]$if2(%title%,%filename%)";
\r
40 static const char default_sep[] = ", ";
\r
46 GetModuleFileName(NULL, ini_name, sizeof(ini_name));
\r
47 p = strrchr(ini_name, '.');
\r
48 if (!p) p = ini_name + strlen(ini_name);
\r
51 flac_cfg.title.tag_format_w = NULL;
\r
56 RS(flac_cfg.title.tag_format, sizeof(flac_cfg.title.tag_format), default_format);
\r
57 if (flac_cfg.title.tag_format_w)
\r
58 free(flac_cfg.title.tag_format_w);
\r
59 flac_cfg.title.tag_format_w = FLAC_plugin__convert_ansi_to_wide(flac_cfg.title.tag_format);
\r
60 /* @@@ FIXME: trailing spaces */
\r
61 RS(flac_cfg.title.sep, sizeof(flac_cfg.title.sep), default_sep);
\r
62 RI(flac_cfg.tag.reserve_space, 1);
\r
64 RI(flac_cfg.display.show_bps, 1);
\r
65 RI(flac_cfg.output.misc.stop_err, 0);
\r
66 RI(flac_cfg.output.replaygain.enable, 1);
\r
67 RI(flac_cfg.output.replaygain.album_mode, 0);
\r
68 RI(flac_cfg.output.replaygain.hard_limit, 0);
\r
69 RI(flac_cfg.output.replaygain.preamp, 0);
\r
70 RI(flac_cfg.output.resolution.normal.dither_24_to_16, 0);
\r
71 RI(flac_cfg.output.resolution.replaygain.dither, 0);
\r
72 RI(flac_cfg.output.resolution.replaygain.noise_shaping, 1);
\r
73 RI(flac_cfg.output.resolution.replaygain.bps_out, 16);
\r
78 WS(flac_cfg.title.tag_format);
\r
79 WI(flac_cfg.tag.reserve_space);
\r
80 WS(flac_cfg.title.sep);
\r
82 WI(flac_cfg.display.show_bps);
\r
83 WI(flac_cfg.output.misc.stop_err);
\r
84 WI(flac_cfg.output.replaygain.enable);
\r
85 WI(flac_cfg.output.replaygain.album_mode);
\r
86 WI(flac_cfg.output.replaygain.hard_limit);
\r
87 WI(flac_cfg.output.replaygain.preamp);
\r
88 WI(flac_cfg.output.resolution.normal.dither_24_to_16);
\r
89 WI(flac_cfg.output.resolution.replaygain.dither);
\r
90 WI(flac_cfg.output.resolution.replaygain.noise_shaping);
\r
91 WI(flac_cfg.output.resolution.replaygain.bps_out);
\r
98 #define PREAMP_RANGE 24
\r
100 #define Check(x,y) CheckDlgButton(hwnd, x, y ? BST_CHECKED : BST_UNCHECKED)
\r
101 #define GetCheck(x) (IsDlgButtonChecked(hwnd, x)==BST_CHECKED)
\r
102 #define GetSel(x) SendDlgItemMessage(hwnd, x, CB_GETCURSEL, 0, 0)
\r
103 #define GetPos(x) SendDlgItemMessage(hwnd, x, TBM_GETPOS, 0, 0)
\r
104 #define Enable(x,y) EnableWindow(GetDlgItem(hwnd, x), y)
\r
106 static INT_PTR CALLBACK GeneralProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
\r
111 case WM_INITDIALOG:
\r
112 SendDlgItemMessage(hwnd, IDC_TITLE, EM_LIMITTEXT, 255, 0);
\r
113 SendDlgItemMessage(hwnd, IDC_SEP, EM_LIMITTEXT, 15, 0);
\r
115 SetDlgItemText(hwnd, IDC_TITLE, flac_cfg.title.tag_format);
\r
116 SetDlgItemText(hwnd, IDC_SEP, flac_cfg.title.sep);
\r
117 Check(IDC_ID3V1, 0);
\r
118 /*! Check(IDC_RESERVE, flac_cfg.tag.reserve_space); */
\r
119 Check(IDC_BPS, flac_cfg.display.show_bps);
\r
120 Check(IDC_ERRORS, flac_cfg.output.misc.stop_err);
\r
124 switch (LOWORD(wParam))
\r
128 GetDlgItemText(hwnd, IDC_TITLE, flac_cfg.title.tag_format, sizeof(flac_cfg.title.tag_format));
\r
129 if (flac_cfg.title.tag_format_w)
\r
130 free(flac_cfg.title.tag_format_w);
\r
131 GetDlgItemText(hwnd, IDC_SEP, flac_cfg.title.sep, sizeof(flac_cfg.title.sep));
\r
132 flac_cfg.title.tag_format_w = FLAC_plugin__convert_ansi_to_wide(flac_cfg.title.tag_format);
\r
134 /*! flac_cfg.tag.reserve_space = GetCheck(IDC_RESERVE); */
\r
135 flac_cfg.display.show_bps = GetCheck(IDC_BPS);
\r
136 flac_cfg.output.misc.stop_err = GetCheck(IDC_ERRORS);
\r
140 Check(IDC_ID3V1, 0);
\r
141 Check(IDC_RESERVE, 1);
\r
143 Check(IDC_ERRORS, 0);
\r
144 /* fall throught */
\r
146 case IDC_TAGZ_DEFAULT:
\r
147 SetDlgItemText(hwnd, IDC_TITLE, default_format);
\r
150 case IDC_TAGZ_HELP:
\r
151 MessageBox(hwnd, tagz_manual, "Help", 0);
\r
161 static void UpdatePreamp(HWND hwnd, HWND hamp)
\r
163 int pos = SendMessage(hamp, TBM_GETPOS, 0, 0) - PREAMP_RANGE;
\r
164 sprintf(buffer, "%d dB", pos);
\r
165 SetDlgItemText(hwnd, IDC_PA, buffer);
\r
168 static void UpdateRG(HWND hwnd)
\r
170 int on = GetCheck(IDC_ENABLE);
\r
171 Enable(IDC_ALBUM, on);
\r
172 Enable(IDC_LIMITER, on);
\r
173 Enable(IDC_PREAMP, on);
\r
174 Enable(IDC_PA, on);
\r
177 static void UpdateDither(HWND hwnd)
\r
179 int on = GetCheck(IDC_DITHERRG);
\r
180 Enable(IDC_SHAPE, on);
\r
183 static INT_PTR CALLBACK OutputProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
\r
188 case WM_INITDIALOG:
\r
189 Check(IDC_ENABLE, flac_cfg.output.replaygain.enable);
\r
190 Check(IDC_ALBUM, flac_cfg.output.replaygain.album_mode);
\r
191 Check(IDC_LIMITER, flac_cfg.output.replaygain.hard_limit);
\r
192 Check(IDC_DITHER, flac_cfg.output.resolution.normal.dither_24_to_16);
\r
193 Check(IDC_DITHERRG, flac_cfg.output.resolution.replaygain.dither);
\r
194 /* prepare preamp slider */
\r
196 HWND hamp = GetDlgItem(hwnd, IDC_PREAMP);
\r
197 SendMessage(hamp, TBM_SETRANGE, 1, MAKELONG(0, PREAMP_RANGE*2));
\r
198 SendMessage(hamp, TBM_SETPOS, 1, flac_cfg.output.replaygain.preamp+PREAMP_RANGE);
\r
199 UpdatePreamp(hwnd, hamp);
\r
201 /* fill comboboxes */
\r
203 HWND hlist = GetDlgItem(hwnd, IDC_TO);
\r
204 SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"16 bps");
\r
205 SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"24 bps");
\r
206 SendMessage(hlist, CB_SETCURSEL, flac_cfg.output.resolution.replaygain.bps_out/8 - 2, 0);
\r
208 hlist = GetDlgItem(hwnd, IDC_SHAPE);
\r
209 SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"None");
\r
210 SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"Low");
\r
211 SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"Medium");
\r
212 SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"High");
\r
213 SendMessage(hlist, CB_SETCURSEL, flac_cfg.output.resolution.replaygain.noise_shaping, 0);
\r
216 UpdateDither(hwnd);
\r
220 switch (LOWORD(wParam))
\r
224 flac_cfg.output.replaygain.enable = GetCheck(IDC_ENABLE);
\r
225 flac_cfg.output.replaygain.album_mode = GetCheck(IDC_ALBUM);
\r
226 flac_cfg.output.replaygain.hard_limit = GetCheck(IDC_LIMITER);
\r
227 flac_cfg.output.replaygain.preamp = GetPos(IDC_PREAMP) - PREAMP_RANGE;
\r
228 flac_cfg.output.resolution.normal.dither_24_to_16 = GetCheck(IDC_DITHER);
\r
229 flac_cfg.output.resolution.replaygain.dither = GetCheck(IDC_DITHERRG);
\r
230 flac_cfg.output.resolution.replaygain.noise_shaping = GetSel(IDC_SHAPE);
\r
231 flac_cfg.output.resolution.replaygain.bps_out = (GetSel(IDC_TO)+2)*8;
\r
235 Check(IDC_ENABLE, 1);
\r
236 Check(IDC_ALBUM, 0);
\r
237 Check(IDC_LIMITER, 0);
\r
238 Check(IDC_DITHER, 0);
\r
239 Check(IDC_DITHERRG, 0);
\r
241 SendDlgItemMessage(hwnd, IDC_PREAMP, TBM_SETPOS, 1, PREAMP_RANGE);
\r
242 SendDlgItemMessage(hwnd, IDC_TO, CB_SETCURSEL, 0, 0);
\r
243 SendDlgItemMessage(hwnd, IDC_SHAPE, CB_SETCURSEL, 1, 0);
\r
245 UpdatePreamp(hwnd, GetDlgItem(hwnd, IDC_PREAMP));
\r
247 UpdateDither(hwnd);
\r
249 /* active check-boxes */
\r
254 UpdateDither(hwnd);
\r
260 if (GetDlgCtrlID((HWND)lParam)==IDC_PREAMP)
\r
261 UpdatePreamp(hwnd, (HWND)lParam);
\r
268 #define NUM_PAGES 2
\r
275 HWND all[NUM_PAGES];
\r
278 static void ScreenToClientRect(HWND hwnd, RECT *rect)
\r
280 POINT pt = { rect->left, rect->top };
\r
281 ScreenToClient(hwnd, &pt);
\r
285 pt.x = rect->right;
\r
286 pt.y = rect->bottom;
\r
287 ScreenToClient(hwnd, &pt);
\r
288 rect->right = pt.x;
\r
289 rect->bottom = pt.y;
\r
292 static void SendCommand(HWND hwnd, int command)
\r
294 LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
\r
295 SendMessage(data->hdlg, WM_COMMAND, command, 0);
\r
298 static void BroadcastCommand(HWND hwnd, int command)
\r
300 LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
\r
303 for (i=0; i<NUM_PAGES; i++)
\r
304 SendMessage(data->all[i], WM_COMMAND, command, 0);
\r
307 static void OnSelChange(HWND hwnd)
\r
309 LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
\r
310 int index = TabCtrl_GetCurSel(data->htab);
\r
311 if (index < 0) return;
\r
312 /* hide previous */
\r
314 ShowWindow(data->hdlg, SW_HIDE);
\r
316 data->hdlg = data->all[index];
\r
317 SetWindowPos(data->hdlg, HWND_TOP, data->r.left, data->r.top, data->r.right-data->r.left, data->r.bottom-data->r.top, SWP_SHOWWINDOW);
\r
321 static INT_PTR CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
\r
323 static activePage = 0;
\r
328 case WM_INITDIALOG:
\r
330 LOCALDATA *data = LocalAlloc(LPTR, sizeof(LOCALDATA));
\r
331 HINSTANCE inst = (HINSTANCE)lParam;
\r
335 SetWindowLong(hwnd, GWL_USERDATA, (LONG)data);
\r
336 data->htab = GetDlgItem(hwnd, IDC_TABS);
\r
339 item.mask = TCIF_TEXT;
\r
340 data->all[0] = CreateDialog(inst, MAKEINTRESOURCE(IDD_CONFIG_GENERAL), hwnd, GeneralProc);
\r
341 item.pszText = "General";
\r
342 TabCtrl_InsertItem(data->htab, 0, &item);
\r
344 data->all[1] = CreateDialog(inst, MAKEINTRESOURCE(IDD_CONFIG_OUTPUT), hwnd, OutputProc);
\r
345 item.pszText = "Output";
\r
346 TabCtrl_InsertItem(data->htab, 1, &item);
\r
347 /* get rect (after adding pages) */
\r
348 GetWindowRect(data->htab, &data->r);
\r
349 ScreenToClientRect(hwnd, &data->r);
\r
350 TabCtrl_AdjustRect(data->htab, 0, &data->r);
\r
351 /* simulate item change */
\r
352 TabCtrl_SetCurSel(data->htab, activePage);
\r
359 LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
\r
362 activePage = TabCtrl_GetCurSel(data->htab);
\r
364 for (i=0; i<NUM_PAGES; i++)
\r
365 DestroyWindow(data->all[i]);
\r
372 switch (LOWORD(wParam))
\r
376 BroadcastCommand(hwnd, IDOK);
\r
379 EndDialog(hwnd, LOWORD(wParam));
\r
382 SendCommand(hwnd, IDC_RESET);
\r
388 if (LOWORD(wParam) == IDC_TABS)
\r
390 NMHDR *hdr = (NMHDR*)lParam;
\r
394 case TCN_SELCHANGE:
\r
406 int DoConfig(HINSTANCE inst, HWND parent)
\r
408 return DialogBoxParam(inst, MAKEINTRESOURCE(IDD_CONFIG), parent, DialogProc, (LONG)inst) == IDOK;
\r