major plugin revamp based on x-fixer's code

This commit is contained in:
Josh Coalson
2004-09-24 13:57:40 +00:00
parent 838408a3ee
commit 9745f25e78
30 changed files with 2991 additions and 1963 deletions

View File

@@ -1,3 +1,21 @@
/* in_flac - Winamp2 FLAC input plugin
* Copyright (C) 2002,2003,2004 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
@@ -7,10 +25,11 @@
static char buffer[256];
static char ini_name[MAX_PATH];
//
// Read/write config
//
/*
* Read/write config
*/
#define RI(x, def) (x = GetPrivateProfileInt("FLAC", #x, def, ini_name))
#define WI(x) WritePrivateProfileString("FLAC", #x, itoa(x, buffer, 10), ini_name)
@@ -18,38 +37,65 @@ static char buffer[256];
#define WS(x) WritePrivateProfileString("FLAC", #x, x, ini_name)
static const char default_format[] = "[%artist% - ]$if2(%title%,%filename%)";
static const char default_sep[] = ", ";
void InitConfig()
{
char *p;
GetModuleFileName(NULL, ini_name, sizeof(ini_name));
p = strrchr(ini_name, '.');
if (!p) p = ini_name + strlen(ini_name);
strcpy(p, ".ini");
flac_cfg.title.tag_format_w = NULL;
}
void ReadConfig()
{
RS(flac_cfg.title.tag_format, sizeof(flac_cfg.title.tag_format), default_format);
RS(flac_cfg.title.tag_format, sizeof(flac_cfg.title.tag_format), default_format);
if (flac_cfg.title.tag_format_w)
free(flac_cfg.title.tag_format_w);
flac_cfg.title.tag_format_w = FLAC_plugin__convert_ansi_to_wide(flac_cfg.title.tag_format);
/* @@@ FIXME: trailing spaces */
RS(flac_cfg.title.sep, sizeof(flac_cfg.title.sep), default_sep);
RI(flac_cfg.title.read_v1, 1);
RI(flac_cfg.tag.reserve_space, 1);
RI(flac_cfg.output.replaygain.enable, 1);
RI(flac_cfg.output.replaygain.album_mode, 0);
RI(flac_cfg.output.replaygain.hard_limit, 0);
RI(flac_cfg.output.replaygain.preamp, 0);
RI(flac_cfg.output.resolution.normal.dither_24_to_16, 0);
RI(flac_cfg.output.resolution.replaygain.dither, 0);
RI(flac_cfg.output.resolution.replaygain.noise_shaping, 1);
RI(flac_cfg.output.resolution.replaygain.bps_out, 16);
RI(flac_cfg.display.show_bps, 1);
RI(flac_cfg.output.misk.stop_err, 0);
RI(flac_cfg.output.replaygain.enable, 1);
RI(flac_cfg.output.replaygain.album_mode, 0);
RI(flac_cfg.output.replaygain.hard_limit, 0);
RI(flac_cfg.output.replaygain.preamp, 0);
RI(flac_cfg.output.resolution.normal.dither_24_to_16, 0);
RI(flac_cfg.output.resolution.replaygain.dither, 0);
RI(flac_cfg.output.resolution.replaygain.noise_shaping, 1);
RI(flac_cfg.output.resolution.replaygain.bps_out, 16);
}
void WriteConfig()
{
WS(flac_cfg.title.tag_format);
WS(flac_cfg.title.tag_format);
WI(flac_cfg.title.read_v1);
WI(flac_cfg.tag.reserve_space);
WS(flac_cfg.title.sep);
WI(flac_cfg.output.replaygain.enable);
WI(flac_cfg.output.replaygain.album_mode);
WI(flac_cfg.output.replaygain.hard_limit);
WI(flac_cfg.output.replaygain.preamp);
WI(flac_cfg.output.resolution.normal.dither_24_to_16);
WI(flac_cfg.output.resolution.replaygain.dither);
WI(flac_cfg.output.resolution.replaygain.noise_shaping);
WI(flac_cfg.output.resolution.replaygain.bps_out);
WI(flac_cfg.display.show_bps);
WI(flac_cfg.output.misk.stop_err);
WI(flac_cfg.output.replaygain.enable);
WI(flac_cfg.output.replaygain.album_mode);
WI(flac_cfg.output.replaygain.hard_limit);
WI(flac_cfg.output.replaygain.preamp);
WI(flac_cfg.output.resolution.normal.dither_24_to_16);
WI(flac_cfg.output.resolution.replaygain.dither);
WI(flac_cfg.output.resolution.replaygain.noise_shaping);
WI(flac_cfg.output.resolution.replaygain.bps_out);
}
//
// Dialog
//
/*
* Dialog
*/
#define PREAMP_RANGE 24
@@ -59,284 +105,308 @@ void WriteConfig()
#define GetPos(x) SendDlgItemMessage(hwnd, x, TBM_GETPOS, 0, 0)
#define Enable(x,y) EnableWindow(GetDlgItem(hwnd, x), y)
static INT_PTR CALLBACK GeneralProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
// init
case WM_INITDIALOG:
SetDlgItemText(hwnd, IDC_TITLE, flac_cfg.title.tag_format);
return TRUE;
// commands
case WM_COMMAND:
switch (LOWORD(wParam))
{
// ok
case IDOK:
GetDlgItemText(hwnd, IDC_TITLE, flac_cfg.title.tag_format, sizeof(flac_cfg.title.tag_format));
break;
// reset
case IDC_RESET:
SetDlgItemText(hwnd, IDC_TITLE, default_format);
break;
// help
case IDC_TAGZ_HELP:
MessageBox(hwnd, tagz_manual, "Help", 0);
break;
}
break;
}
switch (msg)
{
/* init */
case WM_INITDIALOG:
SendDlgItemMessage(hwnd, IDC_TITLE, EM_LIMITTEXT, 255, 0);
SendDlgItemMessage(hwnd, IDC_SEP, EM_LIMITTEXT, 15, 0);
return 0;
SetDlgItemText(hwnd, IDC_TITLE, flac_cfg.title.tag_format);
SetDlgItemText(hwnd, IDC_SEP, flac_cfg.title.sep);
Check(IDC_ID3V1, flac_cfg.title.read_v1);
/*! Check(IDC_RESERVE, flac_cfg.tag.reserve_space); */
Check(IDC_BPS, flac_cfg.display.show_bps);
Check(IDC_ERRORS, flac_cfg.output.misk.stop_err);
return TRUE;
/* commands */
case WM_COMMAND:
switch (LOWORD(wParam))
{
/* ok */
case IDOK:
GetDlgItemText(hwnd, IDC_TITLE, flac_cfg.title.tag_format, sizeof(flac_cfg.title.tag_format));
if (flac_cfg.title.tag_format_w)
free(flac_cfg.title.tag_format_w);
GetDlgItemText(hwnd, IDC_SEP, flac_cfg.title.sep, sizeof(flac_cfg.title.sep));
flac_cfg.title.tag_format_w = FLAC_plugin__convert_ansi_to_wide(flac_cfg.title.tag_format);
flac_cfg.title.read_v1 = GetCheck(IDC_ID3V1);
/*! flac_cfg.tag.reserve_space = GetCheck(IDC_RESERVE); */
flac_cfg.display.show_bps = GetCheck(IDC_BPS);
flac_cfg.output.misk.stop_err = GetCheck(IDC_ERRORS);
break;
/* reset */
case IDC_RESET:
Check(IDC_ID3V1, 1);
Check(IDC_RESERVE, 1);
Check(IDC_BPS, 1);
Check(IDC_ERRORS, 0);
/* fall throught */
/* default */
case IDC_TAGZ_DEFAULT:
SetDlgItemText(hwnd, IDC_TITLE, default_format);
break;
/* help */
case IDC_TAGZ_HELP:
MessageBox(hwnd, tagz_manual, "Help", 0);
break;
}
break;
}
return 0;
}
static void UpdatePreamp(HWND hwnd, HWND hamp)
{
int pos = SendMessage(hamp, TBM_GETPOS, 0, 0) - PREAMP_RANGE;
sprintf(buffer, "%d dB", pos);
SetDlgItemText(hwnd, IDC_PA, buffer);
int pos = SendMessage(hamp, TBM_GETPOS, 0, 0) - PREAMP_RANGE;
sprintf(buffer, "%d dB", pos);
SetDlgItemText(hwnd, IDC_PA, buffer);
}
static void UpdateRG(HWND hwnd)
{
int on = GetCheck(IDC_ENABLE);
Enable(IDC_ALBUM, on);
Enable(IDC_LIMITER, on);
Enable(IDC_PREAMP, on);
Enable(IDC_PA, on);
int on = GetCheck(IDC_ENABLE);
Enable(IDC_ALBUM, on);
Enable(IDC_LIMITER, on);
Enable(IDC_PREAMP, on);
Enable(IDC_PA, on);
}
static void UpdateDither(HWND hwnd)
{
int on = GetCheck(IDC_DITHERRG);
Enable(IDC_SHAPE, on);
int on = GetCheck(IDC_DITHERRG);
Enable(IDC_SHAPE, on);
}
static INT_PTR CALLBACK OutputProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
// init
case WM_INITDIALOG:
Check(IDC_ENABLE, flac_cfg.output.replaygain.enable);
Check(IDC_ALBUM, flac_cfg.output.replaygain.album_mode);
Check(IDC_LIMITER, flac_cfg.output.replaygain.hard_limit);
Check(IDC_DITHER, flac_cfg.output.resolution.normal.dither_24_to_16);
Check(IDC_DITHERRG, flac_cfg.output.resolution.replaygain.dither);
// prepare preamp slider
{
HWND hamp = GetDlgItem(hwnd, IDC_PREAMP);
SendMessage(hamp, TBM_SETRANGE, 1, MAKELONG(0, PREAMP_RANGE*2));
SendMessage(hamp, TBM_SETPOS, 1, flac_cfg.output.replaygain.preamp+PREAMP_RANGE);
UpdatePreamp(hwnd, hamp);
}
// fill comboboxes
{
HWND hlist = GetDlgItem(hwnd, IDC_TO);
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"16 bps");
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"24 bps");
SendMessage(hlist, CB_SETCURSEL, flac_cfg.output.resolution.replaygain.bps_out/8 - 2, 0);
hlist = GetDlgItem(hwnd, IDC_SHAPE);
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"None");
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"Low");
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"Medium");
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"High");
SendMessage(hlist, CB_SETCURSEL, flac_cfg.output.resolution.replaygain.noise_shaping, 0);
}
UpdateRG(hwnd);
UpdateDither(hwnd);
return TRUE;
// commands
case WM_COMMAND:
switch (LOWORD(wParam))
{
// ok
case IDOK:
flac_cfg.output.replaygain.enable = GetCheck(IDC_ENABLE);
flac_cfg.output.replaygain.album_mode = GetCheck(IDC_ALBUM);
flac_cfg.output.replaygain.hard_limit = GetCheck(IDC_LIMITER);
flac_cfg.output.replaygain.preamp = GetPos(IDC_PREAMP) - PREAMP_RANGE;
flac_cfg.output.resolution.normal.dither_24_to_16 = GetCheck(IDC_DITHER);
flac_cfg.output.resolution.replaygain.dither = GetCheck(IDC_DITHERRG);
flac_cfg.output.resolution.replaygain.noise_shaping = GetSel(IDC_SHAPE);
flac_cfg.output.resolution.replaygain.bps_out = (GetSel(IDC_TO)+2)*8;
break;
// reset
case IDC_RESET:
Check(IDC_ENABLE, 1);
Check(IDC_ALBUM, 0);
Check(IDC_LIMITER, 0);
Check(IDC_DITHER, 0);
Check(IDC_DITHERRG, 0);
switch (msg)
{
/* init */
case WM_INITDIALOG:
Check(IDC_ENABLE, flac_cfg.output.replaygain.enable);
Check(IDC_ALBUM, flac_cfg.output.replaygain.album_mode);
Check(IDC_LIMITER, flac_cfg.output.replaygain.hard_limit);
Check(IDC_DITHER, flac_cfg.output.resolution.normal.dither_24_to_16);
Check(IDC_DITHERRG, flac_cfg.output.resolution.replaygain.dither);
/* prepare preamp slider */
{
HWND hamp = GetDlgItem(hwnd, IDC_PREAMP);
SendMessage(hamp, TBM_SETRANGE, 1, MAKELONG(0, PREAMP_RANGE*2));
SendMessage(hamp, TBM_SETPOS, 1, flac_cfg.output.replaygain.preamp+PREAMP_RANGE);
UpdatePreamp(hwnd, hamp);
}
/* fill comboboxes */
{
HWND hlist = GetDlgItem(hwnd, IDC_TO);
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"16 bps");
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"24 bps");
SendMessage(hlist, CB_SETCURSEL, flac_cfg.output.resolution.replaygain.bps_out/8 - 2, 0);
SendDlgItemMessage(hwnd, IDC_PREAMP, TBM_SETPOS, 1, PREAMP_RANGE);
SendDlgItemMessage(hwnd, IDC_TO, CB_SETCURSEL, 0, 0);
SendDlgItemMessage(hwnd, IDC_SHAPE, CB_SETCURSEL, 1, 0);
hlist = GetDlgItem(hwnd, IDC_SHAPE);
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"None");
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"Low");
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"Medium");
SendMessage(hlist, CB_ADDSTRING, 0, (LPARAM)"High");
SendMessage(hlist, CB_SETCURSEL, flac_cfg.output.resolution.replaygain.noise_shaping, 0);
}
UpdateRG(hwnd);
UpdateDither(hwnd);
return TRUE;
/* commands */
case WM_COMMAND:
switch (LOWORD(wParam))
{
/* ok */
case IDOK:
flac_cfg.output.replaygain.enable = GetCheck(IDC_ENABLE);
flac_cfg.output.replaygain.album_mode = GetCheck(IDC_ALBUM);
flac_cfg.output.replaygain.hard_limit = GetCheck(IDC_LIMITER);
flac_cfg.output.replaygain.preamp = GetPos(IDC_PREAMP) - PREAMP_RANGE;
flac_cfg.output.resolution.normal.dither_24_to_16 = GetCheck(IDC_DITHER);
flac_cfg.output.resolution.replaygain.dither = GetCheck(IDC_DITHERRG);
flac_cfg.output.resolution.replaygain.noise_shaping = GetSel(IDC_SHAPE);
flac_cfg.output.resolution.replaygain.bps_out = (GetSel(IDC_TO)+2)*8;
break;
/* reset */
case IDC_RESET:
Check(IDC_ENABLE, 1);
Check(IDC_ALBUM, 0);
Check(IDC_LIMITER, 0);
Check(IDC_DITHER, 0);
Check(IDC_DITHERRG, 0);
UpdatePreamp(hwnd, GetDlgItem(hwnd, IDC_PREAMP));
UpdateRG(hwnd);
UpdateDither(hwnd);
break;
// active check-boxes
case IDC_ENABLE:
UpdateRG(hwnd);
break;
case IDC_DITHERRG:
UpdateDither(hwnd);
break;
}
break;
// scroller
case WM_HSCROLL:
if (GetDlgCtrlID((HWND)lParam)==IDC_PREAMP)
UpdatePreamp(hwnd, (HWND)lParam);
return 0;
}
SendDlgItemMessage(hwnd, IDC_PREAMP, TBM_SETPOS, 1, PREAMP_RANGE);
SendDlgItemMessage(hwnd, IDC_TO, CB_SETCURSEL, 0, 0);
SendDlgItemMessage(hwnd, IDC_SHAPE, CB_SETCURSEL, 1, 0);
return 0;
UpdatePreamp(hwnd, GetDlgItem(hwnd, IDC_PREAMP));
UpdateRG(hwnd);
UpdateDither(hwnd);
break;
/* active check-boxes */
case IDC_ENABLE:
UpdateRG(hwnd);
break;
case IDC_DITHERRG:
UpdateDither(hwnd);
break;
}
break;
/* scroller */
case WM_HSCROLL:
if (GetDlgCtrlID((HWND)lParam)==IDC_PREAMP)
UpdatePreamp(hwnd, (HWND)lParam);
return 0;
}
return 0;
}
#define NUM_PAGES 2
typedef struct
{
HWND htab;
HWND hdlg;
RECT r;
HWND all[NUM_PAGES];
HWND htab;
HWND hdlg;
RECT r;
HWND all[NUM_PAGES];
} LOCALDATA;
static void ScreenToClientRect(HWND hwnd, RECT *rect)
{
POINT pt = { rect->left, rect->top };
ScreenToClient(hwnd, &pt);
rect->left = pt.x;
rect->top = pt.y;
POINT pt = { rect->left, rect->top };
ScreenToClient(hwnd, &pt);
rect->left = pt.x;
rect->top = pt.y;
pt.x = rect->right;
pt.y = rect->bottom;
ScreenToClient(hwnd, &pt);
rect->right = pt.x;
rect->bottom = pt.y;
pt.x = rect->right;
pt.y = rect->bottom;
ScreenToClient(hwnd, &pt);
rect->right = pt.x;
rect->bottom = pt.y;
}
static void SendCommand(HWND hwnd, int command)
{
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
SendMessage(data->hdlg, WM_COMMAND, command, 0);
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
SendMessage(data->hdlg, WM_COMMAND, command, 0);
}
static void BroadcastCommand(HWND hwnd, int command)
{
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
int i;
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
int i;
for (i=0; i<NUM_PAGES; i++)
SendMessage(data->all[i], WM_COMMAND, command, 0);
for (i=0; i<NUM_PAGES; i++)
SendMessage(data->all[i], WM_COMMAND, command, 0);
}
static void OnSelChange(HWND hwnd)
{
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
int index = TabCtrl_GetCurSel(data->htab);
if (index < 0) return;
// hide previous
if (data->hdlg)
ShowWindow(data->hdlg, SW_HIDE);
// display
data->hdlg = data->all[index];
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);
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
int index = TabCtrl_GetCurSel(data->htab);
if (index < 0) return;
/* hide previous */
if (data->hdlg)
ShowWindow(data->hdlg, SW_HIDE);
/* display */
data->hdlg = data->all[index];
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);
SetFocus(hwnd);
}
static INT_PTR CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static activePage = 0;
static activePage = 0;
switch (msg)
{
// init
case WM_INITDIALOG:
{
LOCALDATA *data = LocalAlloc(LPTR, sizeof(LOCALDATA));
HINSTANCE inst = (HINSTANCE)lParam;
TCITEM item;
switch (msg)
{
/* init */
case WM_INITDIALOG:
{
LOCALDATA *data = LocalAlloc(LPTR, sizeof(LOCALDATA));
HINSTANCE inst = (HINSTANCE)lParam;
TCITEM item;
// init
SetWindowLong(hwnd, GWL_USERDATA, (LONG)data);
data->htab = GetDlgItem(hwnd, IDC_TABS);
data->hdlg = NULL;
// add pages
item.mask = TCIF_TEXT;
data->all[0] = CreateDialog(inst, MAKEINTRESOURCE(IDD_CONFIG_GENERAL), hwnd, GeneralProc);
item.pszText = "General";
TabCtrl_InsertItem(data->htab, 0, &item);
/* init */
SetWindowLong(hwnd, GWL_USERDATA, (LONG)data);
data->htab = GetDlgItem(hwnd, IDC_TABS);
data->hdlg = NULL;
/* add pages */
item.mask = TCIF_TEXT;
data->all[0] = CreateDialog(inst, MAKEINTRESOURCE(IDD_CONFIG_GENERAL), hwnd, GeneralProc);
item.pszText = "General";
TabCtrl_InsertItem(data->htab, 0, &item);
data->all[1] = CreateDialog(inst, MAKEINTRESOURCE(IDD_CONFIG_OUTPUT), hwnd, OutputProc);
item.pszText = "Output";
TabCtrl_InsertItem(data->htab, 1, &item);
// get rect (after adding pages)
GetWindowRect(data->htab, &data->r);
ScreenToClientRect(hwnd, &data->r);
TabCtrl_AdjustRect(data->htab, 0, &data->r);
// simulate item change
TabCtrl_SetCurSel(data->htab, activePage);
OnSelChange(hwnd);
}
return TRUE;
// destory
case WM_DESTROY:
{
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
int i;
data->all[1] = CreateDialog(inst, MAKEINTRESOURCE(IDD_CONFIG_OUTPUT), hwnd, OutputProc);
item.pszText = "Output";
TabCtrl_InsertItem(data->htab, 1, &item);
/* get rect (after adding pages) */
GetWindowRect(data->htab, &data->r);
ScreenToClientRect(hwnd, &data->r);
TabCtrl_AdjustRect(data->htab, 0, &data->r);
/* simulate item change */
TabCtrl_SetCurSel(data->htab, activePage);
OnSelChange(hwnd);
}
return TRUE;
/* destory */
case WM_DESTROY:
{
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
int i;
activePage = TabCtrl_GetCurSel(data->htab);
activePage = TabCtrl_GetCurSel(data->htab);
for (i=0; i<NUM_PAGES; i++)
DestroyWindow(data->all[i]);
for (i=0; i<NUM_PAGES; i++)
DestroyWindow(data->all[i]);
LocalFree(data);
}
break;
// commands
case WM_COMMAND:
switch (LOWORD(wParam))
{
// ok/cancel
case IDOK:
BroadcastCommand(hwnd, IDOK);
/* fall through */
case IDCANCEL:
EndDialog(hwnd, LOWORD(wParam));
return TRUE;
case IDC_RESET:
SendCommand(hwnd, IDC_RESET);
break;
}
break;
// notification
case WM_NOTIFY:
if (LOWORD(wParam) == IDC_TABS)
{
NMHDR *hdr = (NMHDR*)lParam;
LocalFree(data);
}
break;
/* commands */
case WM_COMMAND:
switch (LOWORD(wParam))
{
/* ok/cancel */
case IDOK:
BroadcastCommand(hwnd, IDOK);
/* fall through */
case IDCANCEL:
EndDialog(hwnd, LOWORD(wParam));
return TRUE;
case IDC_RESET:
SendCommand(hwnd, IDC_RESET);
break;
}
break;
/* notification */
case WM_NOTIFY:
if (LOWORD(wParam) == IDC_TABS)
{
NMHDR *hdr = (NMHDR*)lParam;
switch (hdr->code)
{
case TCN_SELCHANGE:
OnSelChange(hwnd);
break;
}
}
break;
}
switch (hdr->code)
{
case TCN_SELCHANGE:
OnSelChange(hwnd);
break;
}
}
break;
}
return 0;
return 0;
}
int DoConfig(HINSTANCE inst, HWND parent)
{
return DialogBoxParam(inst, MAKEINTRESOURCE(IDD_CONFIG), parent, DialogProc, (LONG)inst) == IDOK;
return DialogBoxParam(inst, MAKEINTRESOURCE(IDD_CONFIG), parent, DialogProc, (LONG)inst) == IDOK;
}

View File

@@ -1,41 +1,50 @@
/* in_flac - Winamp2 FLAC input plugin
* Copyright (C) 2002,2003,2004 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//
// common stuff
//
#include "playback.h"
typedef struct {
struct {
BOOL enable;
BOOL album_mode;
INT preamp;
BOOL hard_limit;
} replaygain;
struct {
struct {
BOOL dither_24_to_16;
} normal;
struct {
BOOL dither;
INT noise_shaping; /* value must be one of NoiseShaping enum, c.f. plugin_common/replaygain_synthesis.h */
INT bps_out;
} replaygain;
} resolution;
} output_config_t;
/*
* common stuff
*/
typedef struct {
struct {
char tag_format[256];
char sep[16];
WCHAR *tag_format_w;
BOOL read_v1;
} title;
struct {
BOOL reserve_space;
} tag;
struct {
FLAC__bool show_bps;
} display;
output_config_t output;
} flac_config_t;
extern flac_config_t flac_cfg;
extern char ini_name[MAX_PATH];
//
// prototypes
//
/*
* prototypes
*/
void InitConfig();
void ReadConfig();
void WriteConfig();
int DoConfig(HINSTANCE inst, HWND parent);
int DoConfig(HINSTANCE inst, HWND parent);

File diff suppressed because it is too large Load Diff

View File

@@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "in_flac_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Ox /Og /Oi /Os /Op /Gf /Gy /I "include" /I ".." /I "..\..\include" /D "NDEBUG" /D VERSION=\"1.1.1\" /D "in_flac_EXPORTS" /D "FLAC__NO_DLL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
# ADD CPP /nologo /MD /W3 /WX /GX /Ox /Og /Oi /Os /Op /Gf /Gy /I "include" /I ".." /I "..\..\include" /D "NDEBUG" /D VERSION=\"1.1.1\" /D "in_flac_EXPORTS" /D "FLAC__NO_DLL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAGZ_UNICODE" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -70,7 +70,8 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "in_flac_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "include" /I ".." /I "..\..\include" /D "_DEBUG" /D "REAL_STDIO" /D VERSION=\"1.1.1\" /D "in_flac_EXPORTS" /D "FLAC__NO_DLL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "include" /I ".." /I "..\..\include" /D "_DEBUG" /D "REAL_STDIO" /D VERSION=\"1.1.1\" /D "in_flac_EXPORTS" /D "FLAC__NO_DLL" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TAGZ_UNICODE" /YX /FD /GZ /c
# SUBTRACT CPP /WX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -126,6 +127,14 @@ SOURCE=.\infobox.h
# End Source File
# Begin Source File
SOURCE=.\playback.c
# End Source File
# Begin Source File
SOURCE=.\playback.h
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File

View File

@@ -1,290 +1,430 @@
/* in_flac - Winamp2 FLAC input plugin
* Copyright (C) 2002,2003,2004 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <windows.h>
#include <stdio.h>
#include "FLAC/all.h"
#include "plugin_common/all.h"
#include "infobox.h"
#include "config.h"
#include "resource.h"
typedef struct
{
char filename[MAX_PATH];
char filename[MAX_PATH];
FLAC_Plugin__CanonicalTag tag;
} LOCALDATA;
static char buffer[256];
static char buffer[1024];
static char *genres = NULL;
static int genresSize = 0, genresCount = 0, genresChanged = 0;
static DWORD genresSize = 0, genresCount = 0;
static BOOL genresChanged = FALSE, isNT;
static const char infoTitle[] = "FLAC File Info";
//fixme int64
static __inline DWORD FileSize(const char *file)
{
HANDLE hFile = CreateFile(file, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD res;
/*
* Genres
*/
if (hFile == INVALID_HANDLE_VALUE) return 0;
res = GetFileSize(hFile, 0);
CloseHandle(hFile);
return res;
}
/* TODO: write genres in utf-8 ? */
static __inline int GetGenresFileName(char *buffer, int size)
{
char *c;
char *c;
if (!GetModuleFileName(NULL, buffer, size))
return 0;
c = strrchr(buffer, '\\');
if (!c) return 0;
strcpy(c+1, "genres.txt");
if (!GetModuleFileName(NULL, buffer, size))
return 0;
c = strrchr(buffer, '\\');
if (!c) return 0;
strcpy(c+1, "genres.txt");
return 1;
return 1;
}
static void LoadGenres()
{
HANDLE hFile;
DWORD spam;
char *c;
HANDLE hFile;
DWORD spam;
char *c;
if (!GetGenresFileName(buffer, sizeof(buffer))) return;
// load file
hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return;
genresSize = GetFileSize(hFile, 0);
if (!genresSize) return;
genres = (char*)malloc(genresSize+2);
if (!genres) return;
if (!ReadFile(hFile, genres, genresSize, &spam, NULL))
{
free(genres);
genres = NULL;
return;
}
genres[genresSize] = 0;
genres[genresSize+1] = 0;
// replace newlines
genresChanged = 0;
genresCount = 1;
FLAC__ASSERT(0 != genres);
for (c=genres; *c; c++)
{
if (*c == 10)
{
*c = 0;
if (*(c+1))
genresCount++;
else genresSize--;
}
}
if (!GetGenresFileName(buffer, sizeof(buffer))) return;
/* load file */
hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return;
genresSize = GetFileSize(hFile, 0);
if (genresSize && (genres = (char*)malloc(genresSize+2)))
{
if (!ReadFile(hFile, genres, genresSize, &spam, NULL) || spam!=genresSize)
{
free(genres);
genres = NULL;
}
else
{
genres[genresSize] = 0;
genres[genresSize+1] = 0;
/* replace newlines */
genresChanged = FALSE;
genresCount = 1;
CloseHandle(hFile);
for (c=genres; *c; c++)
{
if (*c == 10)
{
*c = 0;
if (*(c+1))
genresCount++;
else genresSize--;
}
}
}
}
CloseHandle(hFile);
}
static void SaveGenres(HWND hlist)
{
HANDLE hFile;
DWORD spam;
int i, count, len;
HANDLE hFile;
DWORD spam;
int i, count, len;
if (!GetGenresFileName(buffer, sizeof(buffer))) return;
// write file
hFile = CreateFile(buffer, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return;
if (!GetGenresFileName(buffer, sizeof(buffer))) return;
/* write file */
hFile = CreateFile(buffer, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return;
count = SendMessage(hlist, CB_GETCOUNT, 0, 0);
for (i=0; i<count; i++)
{
SendMessage(hlist, CB_GETLBTEXT, i, (LPARAM)buffer);
len = strlen(buffer);
if (i != count-1)
{
buffer[len] = 10;
len++;
}
WriteFile(hFile, buffer, len, &spam, NULL);
}
count = SendMessage(hlist, CB_GETCOUNT, 0, 0);
for (i=0; i<count; i++)
{
SendMessage(hlist, CB_GETLBTEXT, i, (LPARAM)buffer);
len = strlen(buffer);
if (i != count-1)
{
buffer[len] = 10;
len++;
}
WriteFile(hFile, buffer, len, &spam, NULL);
}
CloseHandle(hFile);
CloseHandle(hFile);
}
#define SetText(x,y) SetDlgItemText(hwnd, x, y)
#define GetText(x,y) (GetDlgItemText(hwnd, x, buffer, sizeof(buffer)), y = buffer[0] ? strdup(buffer) : 0)
static BOOL InitInfobox(HWND hwnd, const char *file)
static void AddGenre(HWND hwnd, const char *genre)
{
LOCALDATA *data = LocalAlloc(LPTR, sizeof(LOCALDATA));
HWND hgen = GetDlgItem(hwnd, IDC_GENRE);
if (SendMessage(hgen, CB_FINDSTRINGEXACT, -1, (LPARAM)genre) == CB_ERR)
{
genresChanged = TRUE;
SendMessage(hgen, CB_ADDSTRING, 0, (LPARAM)genre);
}
}
static void InitGenres(HWND hwnd)
{
HWND hgen = GetDlgItem(hwnd, IDC_GENRE);
char *c;
/* set text length limit to 64 chars */
SendMessage(hgen, CB_LIMITTEXT, 64, 0);
/* try to load genres */
if (!genres)
LoadGenres(hgen);
/* add the to list */
if (genres)
{
SendMessage(hgen, CB_INITSTORAGE, genresCount, genresSize);
for (c = genres; *c; c += strlen(c)+1)
SendMessage(hgen, CB_ADDSTRING, 0, (LPARAM)c);
}
}
static void DeinitGenres(HWND hwnd, BOOL final)
{
if (genresChanged && hwnd)
{
SaveGenres(GetDlgItem(hwnd, IDC_GENRE));
genresChanged = FALSE;
final = TRUE;
}
if (final)
{
free(genres);
genres = 0;
}
}
/*
* Infobox helpers
*/
#define SetText(x,y) WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, FLAC_plugin__canonical_get(&data->tag, y), -1, buffer, sizeof(buffer), NULL, NULL); \
SetDlgItemText(hwnd, x, buffer)
#define GetText(x,y) GetDlgItemText(hwnd, x, buffer, sizeof(buffer)); \
if (*buffer) FLAC_plugin__canonical_set_ansi(&data->tag, y, buffer); \
else FLAC_plugin__canonical_remove_all(&data->tag, y)
#define SetTextW(x,y) SetDlgItemTextW(hwnd, x, FLAC_plugin__canonical_get(&data->tag, y))
#define GetTextW(x,y) GetDlgItemTextW(hwnd, x, (WCHAR*)buffer, sizeof(buffer)/2); \
if (*(WCHAR*)buffer) FLAC_plugin__canonical_set(&data->tag, y, (WCHAR*)buffer); \
else FLAC_plugin__canonical_remove_all(&data->tag, y)
static BOOL InitInfoboxInfo(HWND hwnd, const char *file)
{
LOCALDATA *data = LocalAlloc(LPTR, sizeof(LOCALDATA));
FLAC__StreamMetadata streaminfo;
FLAC_Plugin__CanonicalTag tag;
DWORD filesize, length, bps, ratio;
DWORD length, bps, ratio, rg;
LONGLONG filesize;
SetWindowLong(hwnd, GWL_USERDATA, (LONG)data);
// file name
strncpy(data->filename, file, sizeof(data->filename));
SetDlgItemText(hwnd, IDC_NAME, file);
// stream data
filesize = FileSize(file);
if (!filesize) return FALSE;
SetWindowLong(hwnd, GWL_USERDATA, (LONG)data);
/* file name */
strncpy(data->filename, file, sizeof(data->filename));
SetDlgItemText(hwnd, IDC_NAME, file);
/* stream data and vorbis comment */
filesize = FileSize(file);
if (!filesize) return FALSE;
if (!FLAC__metadata_get_streaminfo(file, &streaminfo))
return FALSE;
return FALSE;
ReadTags(file, &data->tag, false);
length = (DWORD)(streaminfo.data.stream_info.total_samples / streaminfo.data.stream_info.sample_rate);
bps = (DWORD)(filesize / (125*streaminfo.data.stream_info.total_samples/streaminfo.data.stream_info.sample_rate));
ratio = bps*1000000 / (streaminfo.data.stream_info.sample_rate*streaminfo.data.stream_info.channels*streaminfo.data.stream_info.bits_per_sample);
length = (DWORD)(streaminfo.data.stream_info.total_samples / streaminfo.data.stream_info.sample_rate);
bps = (DWORD)(filesize / (125*streaminfo.data.stream_info.total_samples/streaminfo.data.stream_info.sample_rate));
ratio = bps*1000000 / (streaminfo.data.stream_info.sample_rate*streaminfo.data.stream_info.channels*streaminfo.data.stream_info.bits_per_sample);
rg = FLAC_plugin__canonical_get(&data->tag, L"REPLAYGAIN_TRACK_GAIN") ? 1 : 0;
rg |= FLAC_plugin__canonical_get(&data->tag, L"REPLAYGAIN_ALBUM_GAIN") ? 2 : 0;
sprintf(buffer, "Sample rate: %d Hz\nChannels: %d\nBits per sample: %d\nMin block size: %d\nMax block size: %d\n"
"File size: %d bytes\nTotal samples: %I64d\nLength: %d:%02d\nAvg. bitrate: %d\nCompression ratio: %d.%d%%\n",
streaminfo.data.stream_info.sample_rate, streaminfo.data.stream_info.channels, streaminfo.data.stream_info.bits_per_sample,
streaminfo.data.stream_info.min_blocksize, streaminfo.data.stream_info.max_blocksize, filesize, streaminfo.data.stream_info.total_samples,
length/60, length%60, bps, ratio/10, ratio%10);
//todo: replaygain
sprintf(buffer, "Sample rate: %d Hz\nChannels: %d\nBits per sample: %d\nMin block size: %d\nMax block size: %d\n"
"File size: %I64d bytes\nTotal samples: %I64d\nLength: %d:%02d\nAvg. bitrate: %d\nCompression ratio: %d.%d%%\n"
"ReplayGain: %s\n",
streaminfo.data.stream_info.sample_rate, streaminfo.data.stream_info.channels, streaminfo.data.stream_info.bits_per_sample,
streaminfo.data.stream_info.min_blocksize, streaminfo.data.stream_info.max_blocksize, filesize, streaminfo.data.stream_info.total_samples,
length/60, length%60, bps, ratio/10, ratio%10,
rg==3 ? "track gain\nReplayGain: album gain" : rg==2 ? "album gain" : rg==1 ? "track gain" : "not present");
SetDlgItemText(hwnd, IDC_INFO, buffer);
// tag
FLAC_plugin__canonical_tag_init(&tag);
FLAC_plugin__canonical_tag_get_combined(file, &tag);
SetDlgItemText(hwnd, IDC_INFO, buffer);
/* tag */
if (isNT)
{
SetTextW(IDC_TITLE, L"TITLE");
SetTextW(IDC_ARTIST, L"ARTIST");
SetTextW(IDC_ALBUM, L"ALBUM");
SetTextW(IDC_COMMENT, L"DESCRIPTION");
SetTextW(IDC_YEAR, L"DATE");
SetTextW(IDC_TRACK, L"TRACKNUMBER");
SetTextW(IDC_GENRE, L"GENRE");
}
else
{
SetText(IDC_TITLE, L"TITLE");
SetText(IDC_ARTIST, L"ARTIST");
SetText(IDC_ALBUM, L"ALBUM");
SetText(IDC_COMMENT, L"DESCRIPTION");
SetText(IDC_YEAR, L"DATE");
SetText(IDC_TRACK, L"TRACKNUMBER");
SetText(IDC_GENRE, L"GENRE");
}
SetText(IDC_TITLE, tag.title);
SetText(IDC_ARTIST, tag.performer ? tag.performer : tag.composer);
SetText(IDC_ALBUM, tag.album);
SetText(IDC_COMMENT, tag.comment);
SetText(IDC_YEAR, tag.year_recorded ? tag.year_recorded : tag.year_performed);
SetText(IDC_TRACK, tag.track_number);
SetText(IDC_GENRE, tag.genre);
FLAC_plugin__canonical_tag_clear(&tag);
return TRUE;
return TRUE;
}
static void __inline SetTag(HWND hwnd, const char *filename, FLAC_Plugin__CanonicalTag *tag)
{
strcpy(buffer, infoTitle);
strcpy(buffer, infoTitle);
if (FLAC_plugin__vorbiscomment_set(filename, tag))
strcat(buffer, " [Updated]");
else strcat(buffer, " [Failed]");
strcat(buffer, " [Updated]");
else strcat(buffer, " [Failed]");
SetWindowText(hwnd, buffer);
SetWindowText(hwnd, buffer);
}
static void UpdateTag(HWND hwnd)
{
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
FLAC_Plugin__CanonicalTag tag;
FLAC_plugin__canonical_tag_init(&tag);
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
// get fields
GetText(IDC_TITLE, tag.title);
GetText(IDC_ARTIST, tag.composer);
GetText(IDC_ALBUM, tag.album);
GetText(IDC_COMMENT, tag.comment);
GetText(IDC_YEAR, tag.year_recorded);
GetText(IDC_TRACK, tag.track_number);
GetText(IDC_GENRE, tag.genre);
/* get fields */
if (isNT)
{
GetTextW(IDC_TITLE, L"TITLE");
GetTextW(IDC_ARTIST, L"ARTIST");
GetTextW(IDC_ALBUM, L"ALBUM");
GetTextW(IDC_COMMENT, L"DESCRIPTION");
GetTextW(IDC_YEAR, L"DATE");
GetTextW(IDC_TRACK, L"TRACKNUMBER");
GetTextW(IDC_GENRE, L"GENRE");
// update genres list
if (tag.genre)
{
HWND hgen = GetDlgItem(hwnd, IDC_GENRE);
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, FLAC_plugin__canonical_get(&data->tag, L"GENRE"), -1, buffer, sizeof(buffer), NULL, NULL);
}
else
{
GetText(IDC_TITLE, L"TITLE");
GetText(IDC_ARTIST, L"ARTIST");
GetText(IDC_ALBUM, L"ALBUM");
GetText(IDC_COMMENT, L"DESCRIPTION");
GetText(IDC_YEAR, L"DATE");
GetText(IDC_TRACK, L"TRACKNUMBER");
GetText(IDC_GENRE, L"GENRE");
}
if (SendMessage(hgen, CB_FINDSTRINGEXACT, -1, (LPARAM)tag.genre) == CB_ERR)
{
genresChanged = 1;
SendMessage(hgen, CB_ADDSTRING, 0, (LPARAM)tag.genre);
}
}
/* update genres list (buffer should contain genre) */
if (buffer[0]) AddGenre(hwnd, buffer);
// write tag
SetTag(hwnd, data->filename, &tag);
FLAC_plugin__canonical_tag_clear(&tag);
/* write tag */
SetTag(hwnd, data->filename, &data->tag);
}
static void RemoveTag(HWND hwnd)
{
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
FLAC_Plugin__CanonicalTag tag;
FLAC_plugin__canonical_tag_init(&tag);
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
FLAC_plugin__canonical_tag_clear(&data->tag);
SetText(IDC_TITLE, "");
SetText(IDC_ARTIST, "");
SetText(IDC_ALBUM, "");
SetText(IDC_COMMENT, "");
SetText(IDC_YEAR, "");
SetText(IDC_TRACK, "");
SetText(IDC_GENRE, "");
SetDlgItemText(hwnd, IDC_TITLE, "");
SetDlgItemText(hwnd, IDC_ARTIST, "");
SetDlgItemText(hwnd, IDC_ALBUM, "");
SetDlgItemText(hwnd, IDC_COMMENT, "");
SetDlgItemText(hwnd, IDC_YEAR, "");
SetDlgItemText(hwnd, IDC_TRACK, "");
SetDlgItemText(hwnd, IDC_GENRE, "");
SetTag(hwnd, data->filename, &tag);
SetTag(hwnd, data->filename, &data->tag);
}
static INT_PTR CALLBACK InfoProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
// init
case WM_INITDIALOG:
SetWindowText(hwnd, infoTitle);
// init genres list
{
HWND hgen = GetDlgItem(hwnd, IDC_GENRE);
char *c;
switch (msg)
{
/* init */
case WM_INITDIALOG:
SetWindowText(hwnd, infoTitle);
InitGenres(hwnd);
/* init fields */
if (!InitInfoboxInfo(hwnd, (const char*)lParam))
PostMessage(hwnd, WM_CLOSE, 0, 0);
return TRUE;
/* destroy */
case WM_DESTROY:
{
LOCALDATA *data = (LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA);
FLAC_plugin__canonical_tag_clear(&data->tag);
LocalFree(data);
DeinitGenres(hwnd, FALSE);
}
break;
/* commands */
case WM_COMMAND:
switch (LOWORD(wParam))
{
/* ok/cancel */
case IDOK:
case IDCANCEL:
EndDialog(hwnd, LOWORD(wParam));
return TRUE;
/* save */
case IDC_UPDATE:
UpdateTag(hwnd);
break;
/* remove */
case IDC_REMOVE:
RemoveTag(hwnd);
break;
}
break;
}
// set text length limit to 64 chars
SendMessage(hgen, CB_LIMITTEXT, 64, 0);
// try to load genres
if (!genres) LoadGenres(hgen);
// add the to list
if (genres)
{
SendMessage(hgen, CB_INITSTORAGE, genresCount, genresSize);
for (c = genres; *c; c += strlen(c)+1)
SendMessage(hgen, CB_ADDSTRING, 0, (LPARAM)c);
}
}
// init fields
if (!InitInfobox(hwnd, (const char*)lParam))
PostMessage(hwnd, WM_CLOSE, 0, 0);
return TRUE;
// destroy
case WM_DESTROY:
if (genresChanged)
{
SaveGenres(GetDlgItem(hwnd, IDC_GENRE));
free(genres);
genres = 0;
}
LocalFree((LOCALDATA*)GetWindowLong(hwnd, GWL_USERDATA));
break;
// commands
case WM_COMMAND:
switch (LOWORD(wParam))
{
// ok/cancel
case IDOK:
case IDCANCEL:
EndDialog(hwnd, LOWORD(wParam));
return TRUE;
// save
case IDC_UPDATE:
UpdateTag(hwnd);
break;
// remove
case IDC_REMOVE:
RemoveTag(hwnd);
break;
}
break;
}
return 0;
return 0;
}
/*
* Helpers
*/
ULONGLONG FileSize(const char *fileName)
{
LARGE_INTEGER res;
HANDLE hFile = CreateFile(fileName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return 0;
res.LowPart = GetFileSize(hFile, &res.HighPart);
CloseHandle(hFile);
return res.QuadPart;
}
static __inline char *GetFileName(const char *fullname)
{
const char *c = fullname + strlen(fullname) - 1;
while (c > fullname)
{
if (*c=='\\' || *c=='/')
{
c++;
break;
}
c--;
}
return (char*)c;
}
void ReadTags(const char *fileName, FLAC_Plugin__CanonicalTag *tag, BOOL forDisplay)
{
FLAC_plugin__canonical_tag_init(tag);
FLAC_plugin__vorbiscomment_get(fileName, tag, forDisplay ? flac_cfg.title.sep : NULL);
if (flac_cfg.title.read_v1)
FLAC_plugin__canonical_tag_add_id3v1(fileName, tag);
/* add file name */
if (forDisplay)
{
char *c;
FLAC_plugin__canonical_set_ansi(tag, L"filepath", fileName);
strcpy(buffer, GetFileName(fileName));
if (c = strrchr(buffer, '.')) *c = 0;
FLAC_plugin__canonical_set_ansi(tag, L"filename", buffer);
}
}
/*
* Front-end
*/
void InitInfobox()
{
isNT = !(GetVersion() & 0x80000000);
}
void DeinitInfobox()
{
DeinitGenres(NULL, true);
}
void DoInfoBox(HINSTANCE inst, HWND hwnd, const char *filename)
{
DialogBoxParam(inst, MAKEINTRESOURCE(IDD_INFOBOX), hwnd, InfoProc, (LONG)filename);
DialogBoxParam(inst, MAKEINTRESOURCE(IDD_INFOBOX), hwnd, InfoProc, (LONG)filename);
}

View File

@@ -1,5 +1,28 @@
//
// prototypes
//
/* in_flac - Winamp2 FLAC input plugin
* Copyright (C) 2002,2003,2004 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* prototypes
*/
ULONGLONG FileSize(const char *fileName);
void ReadTags(const char *fileName, FLAC_Plugin__CanonicalTag *tag, BOOL forDisplay);
void InitInfobox();
void DeinitInfobox();
void DoInfoBox(HINSTANCE inst, HWND hwnd, const char *filename);

View File

@@ -0,0 +1,292 @@
/* in_flac - Winamp2 FLAC input plugin
* Copyright (C) 2000,2001,2002,2003,2004 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include "playback.h"
#include "share/grabbag.h"
static FLAC__int32 reservoir_[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS][FLAC__MAX_BLOCK_SIZE * 2/*for overflow*/];
static FLAC__int32 *reservoir__[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS] = { reservoir_[0], reservoir_[1] }; /*@@@ kind of a hard-coded hack */
static unsigned wide_samples_in_reservoir_;
static output_config_t cfg; /* local copy */
static unsigned bh_index_last_w, bh_index_last_o, written_time_last;
static FLAC__int64 decode_position, decode_position_last;
/*
* callbacks
*/
static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
{
file_info_struct *file_info = (file_info_struct*)client_data;
const unsigned channels = file_info->channels, wide_samples = frame->header.blocksize;
unsigned channel;
(void)decoder;
if (file_info->abort_flag)
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
for (channel = 0; channel < channels; channel++)
memcpy(&reservoir_[channel][wide_samples_in_reservoir_], buffer[channel], sizeof(buffer[0][0]) * wide_samples);
wide_samples_in_reservoir_ += wide_samples;
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
static void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
file_info_struct *file_info = (file_info_struct*)client_data;
(void)decoder;
if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
{
FLAC__ASSERT(metadata->data.stream_info.total_samples < 0x100000000); /* this plugin can only handle < 4 gigasamples */
file_info->total_samples = (unsigned)(metadata->data.stream_info.total_samples&0xfffffffful);
file_info->bits_per_sample = metadata->data.stream_info.bits_per_sample;
file_info->channels = metadata->data.stream_info.channels;
file_info->sample_rate = metadata->data.stream_info.sample_rate;
if (file_info->bits_per_sample!=8 && file_info->bits_per_sample!=16 && file_info->bits_per_sample!=24)
{
FLAC_plugin__show_error("This plugin can only handle 8/16/24-bit samples.");
file_info->abort_flag = true;
return;
}
file_info->length_in_msec = file_info->total_samples * 10 / (file_info->sample_rate / 100);
}
else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
{
double gain, peak;
if (grabbag__replaygain_load_from_vorbiscomment(metadata, cfg.replaygain.album_mode, &gain, &peak))
{
file_info->has_replaygain = true;
file_info->replay_scale = grabbag__replaygain_compute_scale_factor(peak, gain, (double)cfg.replaygain.preamp, !cfg.replaygain.hard_limit);
}
}
}
static void error_callback(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
file_info_struct *file_info = (file_info_struct*)client_data;
(void)decoder;
if (cfg.misk.stop_err || status!=FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC)
file_info->abort_flag = true;
}
/*
* init/delete
*/
FLAC__bool FLAC_plugin__decoder_init(FLAC__FileDecoder *decoder, const char *filename, FLAC__int64 filesize, file_info_struct *file_info, output_config_t *config)
{
FLAC__ASSERT(decoder);
FLAC_plugin__decoder_finish(decoder);
/* init decoder */
FLAC__file_decoder_set_md5_checking(decoder, false);
FLAC__file_decoder_set_filename(decoder, filename);
FLAC__file_decoder_set_metadata_ignore_all(decoder);
FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback);
FLAC__file_decoder_set_write_callback(decoder, write_callback);
FLAC__file_decoder_set_error_callback(decoder, error_callback);
FLAC__file_decoder_set_client_data(decoder, file_info);
if (FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK)
{
FLAC_plugin__show_error("Error while initializing decoder (%s).", FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
return false;
}
/* process */
cfg = *config;
wide_samples_in_reservoir_ = 0;
file_info->is_playing = false;
file_info->abort_flag = false;
file_info->has_replaygain = false;
if (!FLAC__file_decoder_process_until_end_of_metadata(decoder))
{
FLAC_plugin__show_error("Error while processing metadata (%s).", FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
return false;
}
/* check results */
if (file_info->abort_flag) return false; /* metadata callback already popped up the error dialog */
/* init replaygain */
file_info->output_bits_per_sample = file_info->has_replaygain && cfg.replaygain.enable ?
cfg.resolution.replaygain.bps_out :
cfg.resolution.normal.dither_24_to_16 ? min(file_info->bits_per_sample, 16) : file_info->bits_per_sample;
if (file_info->has_replaygain && cfg.replaygain.enable && cfg.resolution.replaygain.dither)
FLAC__replaygain_synthesis__init_dither_context(&file_info->dither_context, file_info->bits_per_sample, cfg.resolution.replaygain.noise_shaping);
/* more inits */
file_info->eof = false;
file_info->seek_to = -1;
file_info->is_playing = true;
file_info->average_bps = (unsigned)(filesize / (125.*file_info->total_samples/file_info->sample_rate));
bh_index_last_w = 0;
bh_index_last_o = BITRATE_HIST_SIZE;
decode_position = 0;
decode_position_last = 0;
written_time_last = 0;
return true;
}
void FLAC_plugin__decoder_finish(FLAC__FileDecoder *decoder)
{
if (decoder && FLAC__file_decoder_get_state(decoder)!=FLAC__FILE_DECODER_UNINITIALIZED)
FLAC__file_decoder_finish(decoder);
}
void FLAC_plugin__decoder_delete(FLAC__FileDecoder *decoder)
{
if (decoder)
{
FLAC_plugin__decoder_finish(decoder);
FLAC__file_decoder_delete(decoder);
}
}
/*
* decode
*/
int FLAC_plugin__seek(FLAC__FileDecoder *decoder, file_info_struct *file_info)
{
int pos;
const FLAC__uint64 target_sample =
(FLAC__uint64)file_info->total_samples*file_info->seek_to / file_info->length_in_msec;
if (!FLAC__file_decoder_seek_absolute(decoder, target_sample))
return -1;
file_info->seek_to = -1;
file_info->eof = false;
wide_samples_in_reservoir_ = 0;
pos = (int)(target_sample*1000 / file_info->sample_rate);
bh_index_last_o = bh_index_last_w = (pos/BITRATE_HIST_SEGMENT_MSEC) % BITRATE_HIST_SIZE;
if (!FLAC__file_decoder_get_decode_position(decoder, &decode_position))
decode_position = 0;
return pos;
}
unsigned FLAC_plugin__decode(FLAC__FileDecoder *decoder, file_info_struct *file_info, char *sample_buffer)
{
/* fill reservoir */
while (wide_samples_in_reservoir_ < SAMPLES_PER_WRITE)
{
if (FLAC__file_decoder_get_state(decoder) == FLAC__FILE_DECODER_END_OF_FILE)
{
file_info->eof = true;
break;
}
else if (!FLAC__file_decoder_process_single(decoder))
{
FLAC_plugin__show_error("Error while processing frame (%s).", FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder)]);
file_info->eof = true;
break;
}
if (!FLAC__file_decoder_get_decode_position(decoder, &decode_position))
decode_position = 0;
}
/* output samples */
if (wide_samples_in_reservoir_ > 0)
{
const unsigned n = min(wide_samples_in_reservoir_, SAMPLES_PER_WRITE);
const unsigned channels = file_info->channels;
unsigned i;
int bytes;
if (cfg.replaygain.enable && file_info->has_replaygain)
{
bytes = FLAC__replaygain_synthesis__apply_gain(
sample_buffer,
true, /* little_endian_data_out */
file_info->output_bits_per_sample == 8, /* unsigned_data_out */
reservoir__,
n,
channels,
file_info->bits_per_sample,
file_info->output_bits_per_sample,
file_info->replay_scale,
cfg.replaygain.hard_limit,
cfg.resolution.replaygain.dither,
&file_info->dither_context
);
}
else
{
bytes = FLAC__plugin_common__pack_pcm_signed_little_endian(
sample_buffer,
reservoir__,
n,
channels,
file_info->bits_per_sample,
file_info->output_bits_per_sample
);
}
wide_samples_in_reservoir_ -= n;
for (i = 0; i < channels; i++)
memmove(&reservoir_[i][0], &reservoir_[i][n], sizeof(reservoir_[0][0]) * wide_samples_in_reservoir_);
return bytes;
}
else
{
file_info->eof = true;
return 0;
}
}
int FLAC_plugin__get_rate(unsigned written_time, unsigned output_time, file_info_struct *file_info)
{
static int bitrate_history_[BITRATE_HIST_SIZE];
unsigned bh_index_w = (written_time/BITRATE_HIST_SEGMENT_MSEC) % BITRATE_HIST_SIZE;
unsigned bh_index_o = (output_time/BITRATE_HIST_SEGMENT_MSEC) % BITRATE_HIST_SIZE;
/* written bitrate */
if (bh_index_w != bh_index_last_w)
{
bitrate_history_[(bh_index_w + BITRATE_HIST_SIZE-1)%BITRATE_HIST_SIZE] =
decode_position>decode_position_last && written_time > written_time_last ?
(unsigned)(8000*(decode_position - decode_position_last)/(written_time - written_time_last)) :
file_info->average_bps;
bh_index_last_w = bh_index_w;
written_time_last = written_time;
decode_position_last = decode_position;
}
/* output bitrate */
if (bh_index_o!=bh_index_last_o && bh_index_o!=bh_index_last_w)
{
bh_index_last_o = bh_index_o;
return bitrate_history_[bh_index_o];
}
return 0;
}

View File

@@ -0,0 +1,92 @@
/* in_flac - Winamp2 FLAC input plugin
* Copyright (C) 2000,2001,2002,2003,2004 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "FLAC/all.h"
#include "share/replaygain_synthesis.h"
#include "plugin_common/all.h"
/*
* constants
*/
#define SAMPLES_PER_WRITE 576
#define BITRATE_HIST_SEGMENT_MSEC 500
#define BITRATE_HIST_SIZE 64
/*
* common structures
*/
typedef struct {
volatile FLAC__bool is_playing;
volatile FLAC__bool abort_flag;
volatile FLAC__bool eof;
volatile int seek_to;
unsigned total_samples;
unsigned bits_per_sample;
unsigned output_bits_per_sample;
unsigned channels;
unsigned sample_rate;
unsigned length_in_msec;
unsigned average_bps;
FLAC__bool has_replaygain;
double replay_scale;
DitherContext dither_context;
} file_info_struct;
typedef struct {
struct {
FLAC__bool enable;
FLAC__bool album_mode;
int preamp;
FLAC__bool hard_limit;
} replaygain;
struct {
struct {
FLAC__bool dither_24_to_16;
} normal;
struct {
FLAC__bool dither;
int noise_shaping; /* value must be one of NoiseShaping enum, see plugin_common/replaygain_synthesis.h */
int bps_out;
} replaygain;
} resolution;
struct {
FLAC__bool stop_err;
} misk;
} output_config_t;
/*
* protopytes
*/
FLAC__bool FLAC_plugin__decoder_init(FLAC__FileDecoder *decoder, const char *filename, FLAC__int64 filesize, file_info_struct *file_info, output_config_t *config);
void FLAC_plugin__decoder_finish(FLAC__FileDecoder *decoder);
void FLAC_plugin__decoder_delete(FLAC__FileDecoder *decoder);
int FLAC_plugin__seek(FLAC__FileDecoder *decoder, file_info_struct *file_info);
unsigned FLAC_plugin__decode(FLAC__FileDecoder *decoder, file_info_struct *file_info, char *sample_buffer);
int FLAC_plugin__get_rate(unsigned written_time, unsigned output_time, file_info_struct *file_info);
/*
* these should be defined in plug-in
*/
extern void FLAC_plugin__show_error(const char *message,...);

View File

@@ -23,11 +23,17 @@
#define IDC_TITLE 1010
#define IDC_TAGZ_HELP 1011
#define IDC_ARTIST 1011
#define IDC_TAGZ_DEFAULT 1012
#define IDC_SEP 1013
#define IDC_NAME 1014
#define IDC_INFO 1015
#define IDC_GENRE 1017
#define IDC_REMOVE 1020
#define IDC_UPDATE 1021
#define IDC_ID3V1 1030
#define IDC_RESERVE 1032
#define IDC_BPS 1036
#define IDC_ERRORS 1037
// Next default values for new objects
//
@@ -35,7 +41,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 106
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1030
#define _APS_NEXT_CONTROL_VALUE 1037
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -67,7 +67,7 @@ BEGIN
EDITTEXT IDC_ALBUM,43,60,137,12,ES_AUTOHSCROLL
RTEXT "&Comment",IDC_STATIC,8,77,31,8
EDITTEXT IDC_COMMENT,43,75,137,12,ES_AUTOHSCROLL
RTEXT "&Year",IDC_STATIC,8,92,31,8
RTEXT "&Date",IDC_STATIC,8,92,31,8
EDITTEXT IDC_YEAR,43,90,40,12,ES_AUTOHSCROLL
RTEXT "Track &number",IDC_STATIC,90,92,46,8
EDITTEXT IDC_TRACK,141,90,39,12,ES_AUTOHSCROLL
@@ -133,10 +133,23 @@ IDD_CONFIG_GENERAL DIALOG DISCARDABLE 0, 0, 226, 171
STYLE DS_CONTROL | WS_CHILD
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX " Title Formatting ",IDC_STATIC,2,2,220,43
LTEXT "&Title:",IDC_STATIC,8,17,16,8
GROUPBOX " Title Formatting ",IDC_STATIC,2,2,220,58
LTEXT "&Title",IDC_STATIC,8,17,14,8
EDITTEXT IDC_TITLE,27,15,188,12,ES_AUTOHSCROLL
PUSHBUTTON "default",IDC_TAGZ_DEFAULT,156,28,30,10
PUSHBUTTON "help",IDC_TAGZ_HELP,188,28,27,10
LTEXT "Separate tag values &with",IDC_STATIC,8,43,79,8
EDITTEXT IDC_SEP,91,41,27,12,ES_AUTOHSCROLL
CONTROL "Read ID3v&1 tags",IDC_ID3V1,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,147,43,70,10
GROUPBOX " Tag Editor ",IDC_STATIC,2,63,220,30
CONTROL "Reserve space for &VorbisComment",IDC_RESERVE,"Button",
BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,8,76,125,10
GROUPBOX " Misk ",IDC_STATIC,2,96,220,72
CONTROL "&Show average bitrate while playing",IDC_BPS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,8,108,125,10
CONTROL "Stop on &all errors",IDC_ERRORS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,8,120,69,10
END
IDD_CONFIG_OUTPUT DIALOG DISCARDABLE 0, 0, 224, 171
@@ -159,11 +172,11 @@ BEGIN
CONTROL "&Dither 24bps to 16bps",IDC_DITHER,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,16,84,85,10
GROUPBOX " With ReplayGain ",IDC_STATIC,7,104,209,47
CONTROL "E&nable dithering",IDC_DITHERRG,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,16,134,67,10
LTEXT "&Output bit depth",IDC_STATIC,16,119,52,8
COMBOBOX IDC_TO,71,116,39,43,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
CONTROL "E&nable dithering",IDC_DITHERRG,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,16,134,67,10
LTEXT "Noise &shaping",IDC_STATIC,113,135,46,8
COMBOBOX IDC_SHAPE,164,132,46,48,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP

View File

@@ -125,7 +125,7 @@ static char roman_num[]=
};
static int is_roman(T_CHAR * ptr)//could be more smart i think
static int is_roman(T_CHAR * ptr)/* could be more smart i think */
{
if (ptr[0]==']' && ptr[1]=='[' && separator(ptr[2])) return 1;
while(!separator(*ptr))
@@ -164,7 +164,7 @@ MAKEFUNC(If)
if (n_src!=3) return false;
out.AddString(src[found_src[0] ? 1 : 2]);
return true;
return true;
}
MAKEFUNC(If2)
@@ -172,7 +172,7 @@ MAKEFUNC(If2)
if (n_src!=2) return false;
out.AddString(src[found_src[0] ? 0 : 1]);
return true;
return true;
}
@@ -181,7 +181,7 @@ MAKEFUNC(Iflonger)
if (n_src!=4) return false;
out.AddString(src[(int)t_strlen(src[0])>t_atoi(src[1]) ? 2 : 3]);
return true;
return true;
}
MAKEFUNC(Ifgreater)
@@ -189,7 +189,7 @@ MAKEFUNC(Ifgreater)
if (n_src!=4) return false;
out.AddString(src[t_atoi(src[0])>t_atoi(src[1]) ? 2 : 3]);
return true;
return true;
}
MAKEFUNC(Upper)
@@ -201,7 +201,7 @@ MAKEFUNC(Upper)
while(*s)
out.AddChar(toupper(*(s++)));
return true;
return true;
}
MAKEFUNC(Lower)
@@ -213,7 +213,7 @@ MAKEFUNC(Lower)
while(*s)
out.AddChar(tolower(*(s++)));
return true;
return true;
}
MAKEFUNC(Pad)
@@ -222,18 +222,18 @@ MAKEFUNC(Pad)
T_CHAR *fill=_TX(" ");
if (n_src==3 && src[2][0])
fill = src[2];
fill = src[2];
int num = t_atoi(src[1]);
T_CHAR *p = src[0];
while (*p) { out.AddChar(*(p++)); num--; }
while (*p) { out.AddChar(*(p++)); num--; }
UINT fl = t_strlen(fill);
while (num>0)
out.AddChar(fill[(--num)%fl]);
out.AddChar(fill[(--num)%fl]);
return true;
return true;
}
MAKEFUNC(Cut)
@@ -245,7 +245,7 @@ MAKEFUNC(Cut)
while (*p && num>0) {out.AddChar(*(p++));num--;}
return true;
return true;
}
MAKEFUNC(PadCut)
@@ -254,7 +254,7 @@ MAKEFUNC(PadCut)
T_CHAR *fill = _TX(" ");
if (n_src==3 && src[2][0])
fill = src[2];
fill = src[2];
int num = t_atoi(src[1]);
T_CHAR *p = src[0];
@@ -263,13 +263,13 @@ MAKEFUNC(PadCut)
UINT fl=t_strlen(fill);
while (num>0)
out.AddChar(fill[(--num)%fl]);
out.AddChar(fill[(--num)%fl]);
return true;
return true;
}
// abbr(string)
// abbr(string,len)
/* abbr(string) */
/* abbr(string,len) */
MAKEFUNC(Abbr)
{
if (n_src==0 || n_src>2) return false;
@@ -301,7 +301,7 @@ MAKEFUNC(Abbr)
meta++;
}
return true;
return true;
}
@@ -324,7 +324,7 @@ MAKEFUNC(Caps)
out.AddChar(c);
}
return true;
return true;
}
MAKEFUNC(Caps2)
@@ -344,7 +344,7 @@ MAKEFUNC(Caps2)
out.AddChar(c);
}
return true;
return true;
}
MAKEFUNC(Longest)
@@ -359,7 +359,7 @@ MAKEFUNC(Longest)
}
if (ptr) out.AddString(ptr);
return true;
return true;
}
MAKEFUNC(Shortest)
@@ -374,7 +374,7 @@ MAKEFUNC(Shortest)
}
if (ptr) out.AddString(ptr);
return true;
return true;
}
MAKEFUNC(Num)
@@ -387,20 +387,20 @@ MAKEFUNC(Num)
sprintf(tmp,tmp1,t_atoi(src[0]));
out.AddString(tmp);
return true;
return true;
}
MAKEFUNC(Hex)
{
if (n_src!=2) return false;
T_CHAR tmp[16];
T_CHAR tmp[16];
T_CHAR tmp1[16];
sprintf(tmp1,_TX("%%0%ux"),t_atoi(src[1]));
sprintf(tmp,tmp1,t_atoi(src[0]));
out.AddString(tmp);
return true;
return true;
}
MAKEFUNC(StrChr)
@@ -412,10 +412,10 @@ MAKEFUNC(StrChr)
while (*p && *p!=s) p++;
if (*p==s)
out.AddInt(1+p-src[0]);
out.AddInt(1+p-src[0]);
else out.AddChar('0');
return true;
return true;
}
MAKEFUNC(StrRChr)
@@ -432,10 +432,10 @@ MAKEFUNC(StrRChr)
}
if (p1)
out.AddInt(1+p1-src[0]);
out.AddInt(1+p1-src[0]);
else out.AddChar('0');
return true;
return true;
}
MAKEFUNC(StrStr)
@@ -445,14 +445,14 @@ MAKEFUNC(StrStr)
T_CHAR * p = t_strstr(src[0],src[1]);
if (p)
out.AddInt(1+p-src[0]);
out.AddInt(1+p-src[0]);
else out.AddChar('0');
return true;
return true;
}
// substr(string, index)
// substr(string, index, length)
/* substr(string, index) */
/* substr(string, index, length) */
MAKEFUNC(SubStr)
{
if (n_src<2 || n_src>3) return false;
@@ -472,15 +472,15 @@ MAKEFUNC(SubStr)
out.AddChar(src[0][n1++]);
}
return true;
return true;
}
MAKEFUNC(Len)
{
if (n_src!=1) return false;
out.AddInt(t_strlen(src[0]));
return true;
out.AddInt(t_strlen(src[0]));
return true;
}
MAKEFUNC(Add)
@@ -493,7 +493,7 @@ MAKEFUNC(Add)
out.AddInt(s);
return true;
return true;
}
MAKEFUNC(Sub)
@@ -508,7 +508,7 @@ MAKEFUNC(Sub)
out.AddInt(s);
return true;
return true;
}
MAKEFUNC(Mul)
@@ -521,7 +521,7 @@ MAKEFUNC(Mul)
out.AddInt(s);
return true;
return true;
}
MAKEFUNC(Div)
@@ -540,7 +540,7 @@ MAKEFUNC(Div)
out.AddInt(s);
return true;
return true;
}
MAKEFUNC(Mod)
@@ -559,7 +559,7 @@ MAKEFUNC(Mod)
out.AddInt(s);
return true;
return true;
}
MAKEFUNC(Max)
@@ -576,7 +576,7 @@ MAKEFUNC(Max)
}
out.AddInt(m);
return true;
return true;
}
MAKEFUNC(Min)
@@ -593,10 +593,10 @@ MAKEFUNC(Min)
}
out.AddInt(m);
return true;
return true;
}
// replace(string, what_to_replace, replacement)
/* replace(string, what_to_replace, replacement) */
MAKEFUNC(Replace)
{
if (n_src!=3) return false;
@@ -616,7 +616,7 @@ MAKEFUNC(Replace)
else out.AddChar(*p++);
}
return true;
return true;
}
struct
@@ -671,11 +671,11 @@ private:
int found;
void Error(T_CHAR *e=0)
{
str.Reset();
str.AddString(e ? e : _TX("[SYNTAX ERROR IN FORMATTING STRING]"));
found++; // force displaying
}
{
str.Reset();
str.AddString(e ? e : _TX("[SYNTAX ERROR IN FORMATTING STRING]"));
found++; /* force displaying */
}
T_CHAR * _FMT(T_CHAR * s,UINT *f=0)
{
@@ -739,7 +739,7 @@ private:
*s1=0;
const T_CHAR * tag=f(spec,fp);
*s1='%';
//if (!tag) tag=tag_unknown;
/*if (!tag) tag=tag_unknown; */
if (tag && tag[0])
{
found++;
@@ -784,25 +784,25 @@ private:
for (n=0; n<TABSIZE(FUNCS); n++)
if (!t_stricmp(spec, FUNCS[n].name))
break;
break;
*s1='(';
if (n != TABSIZE(FUNCS))
{
if (!FUNCS[n].func(nt, temp, temp_f, str))
{
Error(_TX("[INVALID $"));
str.AddString(FUNCS[n].name);
str.AddString(_TX(" SYNTAX]"));
return;
}
{
Error(_TX("[INVALID $"));
str.AddString(FUNCS[n].name);
str.AddString(_TX(" SYNTAX]"));
return;
}
}
else
{
Error(_TX("[UNKNOWN FUNCTION]"));
return;
}
{
Error(_TX("[UNKNOWN FUNCTION]"));
return;
}
for(n=0;n<nt;n++) free(temp[n]);
spec=s2+1;
@@ -897,8 +897,6 @@ T_CHAR * tagz_format_r(const T_CHAR* spec,TAGFUNC f,TAGFREEFUNC ff,void * fp)
return FMT(spec,f,ff,fp);
}
//char tagz_manual[]="TODO: WTFM";
const char tagz_manual[]="Syntax reference: \n"
"\n"
"* %tagname% - inserts field named <tagname>, eg. \"%artist%\"\n"

View File

@@ -14,7 +14,7 @@ typedef unsigned short T_CHAR;
#define T_CHAR char
#endif
typedef const T_CHAR* (*TAGFUNC)(const T_CHAR *tag,void *p); // return 0 if not found
typedef const T_CHAR* (*TAGFUNC)(const T_CHAR *tag,void *p); /* return 0 if not found */
typedef void (*TAGFREEFUNC)(const T_CHAR *tag,void *p);