📄 foo_faac.cpp
字号:
if ( !stricmp (pName, "TITLE") ) {
MP4SetMetadataName ( MP4hFile, val );
}
else if ( !stricmp (pName, "ARTIST") ) {
MP4SetMetadataArtist ( MP4hFile, val );
}
else if ( !stricmp (pName, "WRITER") ) {
MP4SetMetadataWriter ( MP4hFile, val );
}
else if ( !stricmp (pName, "ALBUM") ) {
MP4SetMetadataAlbum ( MP4hFile, val );
}
else if ( !stricmp (pName, "YEAR") || !stricmp (pName, "DATE") ) {
MP4SetMetadataYear ( MP4hFile, val );
}
else if ( !stricmp (pName, "COMMENT") ) {
MP4SetMetadataComment ( MP4hFile, val );
}
else if ( !stricmp (pName, "GENRE") ) {
MP4SetMetadataGenre ( MP4hFile, val );
}
else if ( !stricmp (pName, "TRACKNUMBER") ) {
unsigned __int16 trkn = atoi ( val ), tot = 0;
MP4SetMetadataTrack ( MP4hFile, trkn, tot );
}
else if ( !stricmp (pName, "DISKNUMBER") || !stricmp (pName, "DISC") ) {
unsigned __int16 disk = atoi ( val ), tot = 0;
MP4SetMetadataDisk ( MP4hFile, disk, tot );
}
else if ( !stricmp (pName, "COMPILATION") ) {
unsigned __int8 cpil = atoi ( val );
MP4SetMetadataCompilation ( MP4hFile, cpil );
}
else if ( !stricmp (pName, "TEMPO") ) {
unsigned __int16 tempo = atoi ( val );
MP4SetMetadataTempo ( MP4hFile, tempo );
} else {
MP4SetMetadataFreeForm ( MP4hFile, pName, (unsigned __int8*)val, strlen(val) );
}
}
return 1;
}
}
int *mkChanMap ( int channels, int center, int lf )
{
if ( !center && !lf ) return 0;
if ( channels < 3 ) return 0;
if ( lf > 0 ) {
lf--;
} else {
lf = channels - 1; // default AAC position
}
if ( center > 0 ) {
center--;
} else {
center = 0; // default AAC position
}
int *map = (int *)calloc ( channels, sizeof(map[0]) );
int outpos = 0;
if ( (center >= 0) && (center < channels) ) map[outpos++] = center;
int inpos = 0;
for ( ; outpos < (channels - 1); inpos++ ) {
if ( inpos == center ) continue;
if ( inpos == lf ) continue;
map[outpos++] = inpos;
}
if ( outpos < channels ) {
if ( (lf >= 0) && (lf < channels) ) {
map[outpos] = lf;
} else {
map[outpos] = inpos;
}
}
return map;
}
void chan_remap ( int *buf, unsigned int channels, unsigned int blocks, int *map )
{
int *tmp = (int *)alloca ( channels * sizeof(int) );
for ( unsigned int i = 0; i < blocks; i++ ) {
memcpy ( tmp, buf + i * channels, sizeof(int) * channels );
for ( unsigned int chn = 0; chn < channels; chn++ ) {
buf[i * channels + chn] = tmp[map[chn]];
}
}
}
// MP4 I/O callbacks
static unsigned __int32 open_cb ( const char *pName, const char *mode, void *userData ) { return 1; }
static void close_cb ( void *userData ) { return; }
static unsigned __int32 read_cb ( void *pBuffer, unsigned int nBytesToRead, void *userData )
{
reader *r = (reader *)userData;
return r->read ( pBuffer, nBytesToRead );
}
static unsigned __int32 write_cb ( void *pBuffer, unsigned int nBytesToWrite, void *userData )
{
reader *r = (reader *)userData;
return r->write ( pBuffer, nBytesToWrite );
}
static __int64 getpos_cb ( void *userData )
{
reader *r = (reader *)userData;
return r->get_position();
}
static __int32 setpos_cb ( unsigned __int32 pos, void *userData )
{
reader *r = (reader *)userData;
return !r->seek ( pos );
}
static __int64 filesize_cb ( void *userData )
{
reader *r = (reader *)userData;
return r->get_length();
}
};
// -------------------------------------
typedef struct {
int mp4;
char name[4];
} format_list_t;
static format_list_t format_list[] = {
{ FF_MP4, "MP4" },
{ FF_M4A, "M4A" },
{ FF_AAC, "AAC" },
};
typedef struct {
int profile;
char name[6];
} profile_list_t;
static profile_list_t profile_list[] = {
{ LOW, "LC" },
{ MAIN, "Main" },
{ LTP, "LTP" },
};
typedef struct {
int cutoff;
char name[10];
} cutoff_list_t;
static cutoff_list_t cutoff_list[] = {
{ -1, "Automatic" },
{ 0, "Full" },
{ 20000, "20000" },
{ 19000, "19000" },
{ 18000, "18000" },
{ 17000, "17000" },
{ 16000, "16000" },
{ 15000, "15000" },
{ 14000, "14000" },
{ 13000, "13000" },
{ 12000, "12000" },
{ 11000, "11000" },
{ 10000, "10000" },
};
#define QQ_MIN 10
#define QQ_MAX 500
#define AB_MIN 8
#define AB_MAX 384
class config_faac : public config {
static void update ( HWND wnd )
{
int i;
HWND wnd_format = GetDlgItem ( wnd, IDC_FORMAT );
HWND wnd_profile = GetDlgItem ( wnd, IDC_PROFILE );
HWND wnd_cutoff = GetDlgItem ( wnd, IDC_CUTOFF );
for ( i = 0; i < sizeof(format_list)/sizeof(*format_list); i++ ) {
if ( (cfg_mp4container == format_list[i].mp4) ) {
uSendMessage ( wnd_format, CB_SETCURSEL, i, 0 );
break;
}
}
for ( i = 0; i < sizeof(profile_list)/sizeof(*profile_list); i++ ) {
if ( cfg_objecttype == profile_list[i].profile ) {
uSendMessage ( wnd_profile, CB_SETCURSEL, i, 0 );
break;
}
}
bool cutoff_found = false;
for ( i = 0; i < sizeof(cutoff_list)/sizeof(*cutoff_list); i++ ) {
if ( cfg_cutoff == cutoff_list[i].cutoff ) {
uSendMessage ( wnd_cutoff, CB_SETCURSEL, i, 0 );
cutoff_found = true;
break;
}
}
if ( !cutoff_found ) uSetDlgItemText ( wnd, IDC_CUTOFF, string_printf ("%i", (int)cfg_cutoff) );
uSendDlgItemMessage ( wnd, IDC_QUANTQUAL_SLIDER, TBM_SETPOS, 1, cfg_quantqual );
uSetDlgItemText ( wnd, IDC_QUANTQUAL_EDIT, string_printf ("%i", (int)cfg_quantqual) );
uSendDlgItemMessage ( wnd, IDC_AVGBRATE_SLIDER, TBM_SETPOS, 1, cfg_avgbrate );
uSetDlgItemText ( wnd, IDC_AVGBRATE_EDIT, string_printf ("%i", (int)cfg_avgbrate) );
CheckDlgButton ( wnd, IDC_USE_QQ, cfg_use_qq );
CheckDlgButton ( wnd, IDC_USE_AB, cfg_use_ab );
CheckDlgButton ( wnd, IDC_MIDSIDE, cfg_midside );
CheckDlgButton ( wnd, IDC_TNS, cfg_tns );
}
static BOOL CALLBACK ConfigProc ( HWND wnd, UINT msg, WPARAM wp, LPARAM lp )
{
HWND wnd_format = GetDlgItem ( wnd, IDC_FORMAT );
HWND wnd_profile = GetDlgItem ( wnd, IDC_PROFILE );
HWND wnd_cutoff = GetDlgItem ( wnd, IDC_CUTOFF );
switch ( msg ) {
case WM_INITDIALOG:
{
int i;
for ( i = 0; i < sizeof(format_list)/sizeof(*format_list); i++ ) {
uSendMessageText ( wnd_format, CB_ADDSTRING, 0, format_list[i].name );
}
for ( i = 0; i < sizeof(profile_list)/sizeof(*profile_list); i++ ) {
uSendMessageText ( wnd_profile, CB_ADDSTRING, 0, profile_list[i].name );
}
for ( i = 0; i < sizeof(cutoff_list)/sizeof(*cutoff_list); i++ ) {
uSendMessageText ( wnd_cutoff, CB_ADDSTRING, 0, cutoff_list[i].name );
}
uSendDlgItemMessage ( wnd, IDC_QUANTQUAL_SLIDER, TBM_SETRANGE, 0, MAKELONG(QQ_MIN, QQ_MAX) );
uSendDlgItemMessage ( wnd, IDC_AVGBRATE_SLIDER, TBM_SETRANGE, 0, MAKELONG(AB_MIN, AB_MAX) );
update ( wnd );
}
return TRUE;
case WM_COMMAND:
switch ( wp ) {
case IDC_FORMAT | (CBN_SELCHANGE<<16):
{
int t = (int)uSendMessage ( wnd_format, CB_GETCURSEL, 0, 0 );
if ( t >= 0 ) cfg_mp4container = format_list[t].mp4;
}
break;
case IDC_PROFILE | (CBN_SELCHANGE<<16):
{
int t = (int)uSendMessage ( wnd_profile, CB_GETCURSEL, 0, 0 );
if ( t >= 0 ) cfg_objecttype = profile_list[t].profile;
}
break;
case IDC_QUANTQUAL_EDIT | (EN_KILLFOCUS<<16):
{
cfg_quantqual = GetDlgItemInt ( wnd, IDC_QUANTQUAL_EDIT, 0, 0 );
if ( cfg_quantqual < QQ_MIN || cfg_quantqual > QQ_MAX ) {
if ( cfg_quantqual < QQ_MIN ) {
cfg_quantqual = QQ_MIN;
} else {
cfg_quantqual = QQ_MAX;
}
uSetDlgItemText ( wnd, IDC_QUANTQUAL_EDIT, string_printf ("%i", (int)cfg_quantqual) );
}
uSendDlgItemMessage ( wnd, IDC_QUANTQUAL_SLIDER, TBM_SETPOS, 1, cfg_quantqual );
}
break;
case IDC_AVGBRATE_EDIT | (EN_KILLFOCUS<<16):
{
cfg_avgbrate = GetDlgItemInt ( wnd, IDC_AVGBRATE_EDIT, 0, 0 );
if ( cfg_avgbrate < AB_MIN || cfg_quantqual > AB_MAX ) {
if ( cfg_avgbrate< AB_MIN ) {
cfg_avgbrate = AB_MIN;
} else {
cfg_avgbrate = AB_MAX;
}
uSetDlgItemText ( wnd, IDC_AVGBRATE_EDIT, string_printf ("%i", (int)cfg_avgbrate) );
}
uSendDlgItemMessage ( wnd, IDC_AVGBRATE_SLIDER, TBM_SETPOS, 1, cfg_avgbrate );
}
break;
case IDC_CUTOFF | (CBN_SELCHANGE<<16):
{
int t = (int)uSendMessage ( wnd_cutoff, CB_GETCURSEL, 0, 0 );
if ( t >= 0 ) cfg_cutoff = cutoff_list[t].cutoff;
}
break;
case IDC_CUTOFF | (CBN_KILLFOCUS<<16):
{
int t = (int)uSendMessage ( wnd_cutoff, CB_GETCURSEL, 0, 0 );
if ( t < 0 ) {
cfg_cutoff = GetDlgItemInt ( wnd, IDC_CUTOFF, 0, 0 );
if ( cfg_cutoff > 0 && cfg_cutoff < 100 ) {
cfg_cutoff = 100;
uSetDlgItemText ( wnd, IDC_CUTOFF, string_printf ("%i", (int)cfg_cutoff) );
}
else if ( cfg_cutoff <= 0 ) {
uSendMessage ( wnd_cutoff, CB_SETCURSEL, 0, 0 );
cfg_cutoff = cutoff_list[0].cutoff;
}
}
}
break;
case IDC_MIDSIDE:
{
cfg_midside = !cfg_midside;
}
break;
case IDC_TNS:
{
cfg_tns = !cfg_tns;
}
break;
case IDC_USE_QQ:
{
cfg_use_qq = !cfg_use_qq;
}
break;
case IDC_USE_AB:
{
cfg_use_ab = !cfg_use_ab;
}
break;
case IDC_DEFAULTS:
{
cfg_objecttype = FF_DEFAULT_OBJECTTYPE;
cfg_midside = FF_DEFAULT_MIDSIDE;
cfg_tns = FF_DEFAULT_TNS;
cfg_avgbrate = FF_DEFAULT_AVGBRATE;
cfg_quantqual = FF_DEFAULT_QUANTQUAL;
cfg_cutoff = FF_DEFAULT_CUTOFF;
cfg_use_qq = FF_DEFAULT_USE_QQ;
cfg_use_ab = FF_DEFAULT_USE_AB;
update ( wnd );
}
break;
}
break;
case WM_HSCROLL:
switch ( uGetWindowLong((HWND)lp, GWL_ID) ) {
case IDC_QUANTQUAL_SLIDER:
cfg_quantqual = uSendMessage ( (HWND)lp, TBM_GETPOS, 0, 0 );
uSetDlgItemText ( wnd, IDC_QUANTQUAL_EDIT, string_printf ("%i", (int)cfg_quantqual) );
break;
case IDC_AVGBRATE_SLIDER:
cfg_avgbrate = uSendMessage ( (HWND)lp, TBM_GETPOS, 0, 0 );
uSetDlgItemText ( wnd, IDC_AVGBRATE_EDIT, string_printf ("%i", (int)cfg_avgbrate) );
break;
}
break;
}
return FALSE;
}
virtual HWND create ( HWND parent ) {
return uCreateDialog ( IDD_CONFIG, parent, ConfigProc );
}
virtual const char *get_name() { return "FAAC encoder"; }
virtual const char *get_parent_name() { return "Diskwriter"; }
};
static service_factory_t<diskwriter, diskwriter_faac> foo_faac;
static service_factory_single_t<config, config_faac> foo_faac_cfg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -