#include "main.h" #include #include #include "resource.h" #include "../winamp/wa_ipc.h" #include "../pfc/string_unicode.h" static HWND g_theConfig; static struct { HWND wnd; int id; UINT l_id; } child_dlgs[]={ {0,IDD_CONFIG1,IDS_PREFS_DEVICE}, {0,IDD_CONFIG8,IDS_PREFS_DISPLAY}, {0,IDD_CONFIG2,IDS_PREFS_SAMPLING}, {0,IDD_CONFIG3,IDS_PREFS_DIRECTMUSIC}, {0,IDD_CONFIG4,IDS_PREFS_MISC}, {0,IDD_CONFIG7,IDS_PREFS_FILE_TYPES}, {0,IDD_CONFIG5,IDS_PREFS_FILES}, {0,IDD_CONFIG6,IDS_PREFS_HARDWARE_SETUP}, }; enum { IDC_CONFIG1,IDC_CONFIG8,IDC_CONFIG2,IDC_CONFIG3,IDC_CONFIG4,IDC_CONFIG7,IDC_CONFIG5,IDC_CONFIG6 }; static const char CFG_NAME[]="IN_MIDI"; #define FILE_BLAH MessageBoxA(wnd,WASABI_API_LNGSTRING(IDS_UNABLE_TO_LOAD_FILE),0,MB_ICONERROR) int loop_txt[3]={STRING_LOOP1,STRING_LOOP2,STRING_LOOP3}; #define MAKEID(X,Y) ( ( (DWORD)(X)<<16) | (DWORD)(Y)) //MAKEID(DLG_ID,CTRL_ID) extern cfg_int cfg_seq_showpanel; extern cfg_int cfg_lyrics; cfg_int cfg_smp("smp",0),cfg_reverb("reverb",0),cfg_chorus("chorus",0),cfg_dls_active("dls_active",0); cfg_int cfg_sampout("sampout",0); cfg_int cfg_hardware_reset("hardware_reset",0); cfg_int cfg_gm_reset("gm_reset",0),cfg_gm_reset1("gm_reset1",0); cfg_int cfg_gs_reset("gs_reset",0),cfg_gs_reset1("gs_reset1",0); cfg_int cfg_nosysex("nosysex",0); cfg_int cfg_dm_keep_port("dm_keep_port",0); cfg_int cfg_recover_tracks("recover_tracks",1); cfg_int cfg_rmi_def("rmi_def",0); cfg_int cfg_logvol("logvol",1); cfg_int cfg_ff7loopz("ff7loopz",1); cfg_int cfg_samp_revert("samp_revert",1); cfg_int cfg_hack_xg_drums("hack_xg_drums",0),cfg_hack_dls_instruments("hack_dls_instruments",1),cfg_hack_dls_drums("hack_dls_drums",1); static const WORD sr_tab[]={8000,11025,16000,22050,24000,32000,44100,48000}; cfg_int cfg_cur_tab("cur_tab",0); cfg_int cfg_volmode("volmode",2); //0 - no volume, 1 - default, 2,3,4 ... - mixers cfg_string cfg_extra_exts("extra_exts",""); cfg_int cfg_freq("freq",22050); cfg_int cfg_eof_delay("eof_delay",0); cfg_string cfg_dls_file("dls_file",""); cfg_int cfg_bugged("bugged",0); cfg_int cfg_loop_type("loop_type",0),cfg_loop_count("loop_count",1),cfg_loop_infinite("loop_infinite",0); cfg_int cfg_wavein_dev("wavein_dev",-1),cfg_wavein_sr("wavein_sr",44100),cfg_wavein_ch("wavein_ch",2),cfg_wavein_bps("wavein_bps",16),cfg_wavein_src("wavein_src",0); cfg_int cfg_playback_mode("playback_mode",0); static UINT vm_retval=-666; cfg_struct_t cfg_driver("driver",0),cfg_device("device",0); UINT volmode_detect() { if (vm_retval!=-666) return vm_retval; UINT dev; UINT id; UINT n_devz=mixerGetNumDevs(); UINT pos=0; for(dev=0;dev=tabsize(child_dlgs)) return 0; return child_dlgs[id].wnd; } static HWND __getdlgitem(UINT id) { HWND w=cfgGetTab(id>>16); if (!w) return 0; return GetDlgItem(w,id&0xFFFF); } #define _GetDlgItem(w,id) __getdlgitem(id) #define _GetDlgItemText(p,id,tx,l) GetWindowText(__getdlgitem(id),tx,l) #define _SetDlgItemText(p,id,tx) SetWindowText(__getdlgitem(id),tx) #define _SetDlgItemTextW(p,id,tx) SetWindowTextW(__getdlgitem(id),tx) #define _GetDlgItemInt(a,b,c,d) __getdlgitemint(b) #define _SetDlgItemInt(a,b,c,d) __setdlgitemint(b,c) #define _SendDlgItemMessage(a,b,c,d,e) SendMessage(_GetDlgItem(a,b),c,d,e) static void __setdlgitemint(UINT id,UINT val) { char buf[32] = {0}; _itoa(val,buf,10); SetWindowTextA(__getdlgitem(id),buf); } static int __getdlgitemint(UINT id) { char buf[32] = {0}; GetWindowTextA(__getdlgitem(id),buf,32); return atoi(buf); } static BOOL CALLBACK cfgVisStatusProc(HWND wnd,LPARAM param) { if (GetWindowLong(wnd,GWL_ID)==IDC_SAMPLING_ENABLED) { EnableWindow(wnd,(param & 2) >> 1); } else { EnableWindow(wnd,param & 1); } return 1; } static MIDI_device * get_device(HWND wnd) { int idx = _SendDlgItemMessage(wnd,_IDC_PORT,CB_GETCURSEL,0,0); if (idx<0) return 0; return (MIDI_device*)_SendDlgItemMessage(wnd,_IDC_PORT,CB_GETITEMDATA,idx,0); } static void cfgVisStatus(HWND wnd) { int samp =_SendDlgItemMessage(wnd,_IDC_SAMPLING_ENABLED,BM_GETCHECK,0,0); int output = 0; int flags = 0; MIDI_device * dev = get_device(wnd); if (dev && dev->has_output()) output = 1; if (output && samp) {samp = 0;_SendDlgItemMessage(wnd,_IDC_SAMPLING_ENABLED,BM_SETCHECK,0,0);} if (!output) { flags|=2; if (samp) flags|=1; else { _SendDlgItemMessage(wnd,_IDC_SAMPLING_DSP,BM_SETCHECK,0,0); _SendDlgItemMessage(wnd,_IDC_SAMPLING_OUTPUT,BM_SETCHECK,0,0); } } EnumChildWindows(cfgGetTab(IDC_CONFIG2),cfgVisStatusProc,flags); } static void cfgVisMix(HWND wnd,int dev) { HWND w=_GetDlgItem(wnd,_IDC_WAVEIN_SRC); SendMessage(w,CB_RESETCONTENT,0,0); SendMessageW(w,CB_ADDSTRING,0,(long)WASABI_API_LNGSTRINGW(STRING_SAMP_SRC_DEFAULT)); SendMessage(w,CB_SETCURSEL,0,0); UINT id=0; if (mixerGetID((HMIXEROBJ)dev,&id,MIXER_OBJECTF_WAVEOUT)) return; MIXERLINE ml; memset(&ml,0,sizeof(ml)); ml.cbStruct=sizeof(ml); ml.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_WAVEIN; if (mixerGetLineInfo((HMIXEROBJ)id,&ml,MIXER_GETLINEINFOF_COMPONENTTYPE|MIXER_OBJECTF_MIXER)) return; MIXERLINECONTROLS cs; MIXERCONTROL c; memset(&cs,0,sizeof(cs)); cs.cbStruct=sizeof(cs); cs.cControls=1; cs.dwLineID=ml.dwLineID; cs.dwControlType=MIXERCONTROL_CONTROLTYPE_MUX; cs.cbmxctrl=sizeof(c); cs.pamxctrl=&c; memset(&c,0,sizeof(c)); c.cbStruct=sizeof(c); if (!mixerGetLineControls((HMIXEROBJ)id,&cs,MIXER_OBJECTF_MIXER|MIXER_GETLINECONTROLSF_ONEBYTYPE)) { MIXERCONTROLDETAILS_LISTTEXT *t = (MIXERCONTROLDETAILS_LISTTEXT*)malloc(sizeof(MIXERCONTROLDETAILS_LISTTEXT)*c.cMultipleItems); MIXERCONTROLDETAILS d; d.cbStruct=sizeof(d); d.dwControlID=c.dwControlID; d.cbDetails=sizeof(*t); d.cChannels=ml.cChannels; d.cMultipleItems=c.cMultipleItems; d.paDetails=t; UINT n; for(n=0;nget_driver()->get_name(); temp+=L"\x0d\x0a"; temp+=dev->get_info(); if (!wcscmp((const wchar_t*)temp + temp.length()-2,L"\x0d\x0a")) temp.truncate(temp.length()-2); _SetDlgItemTextW(wnd,_IDC_DEV_INFO,temp); } } #undef DEV const static struct { UINT id; cfg_int * var; } bWnds[]= { {_IDC_SAMP_REVERT,&cfg_samp_revert}, {_IDC_LOGVOL,&cfg_logvol}, {_IDC_RMI_DEF,&cfg_rmi_def}, {_IDC_HACK_DLS_DRUMS,&cfg_hack_dls_drums}, {_IDC_HACK_DLS_INSTRUMENTS,&cfg_hack_dls_instruments}, {_IDC_HACK_XG_DRUMS,&cfg_hack_xg_drums}, {_IDC_HACKTRACK,&cfg_recover_tracks}, {_IDC_DM_KEEP_PORT,&cfg_dm_keep_port}, {_IDC_SAMPLING_ENABLED,&cfg_smp}, {_IDC_REVERB,&cfg_reverb}, {_IDC_CHORUS,&cfg_chorus}, {_IDC_SAMPLING_OUTPUT,&cfg_sampout}, {_IDC_HACK_NO_SYSEX,&cfg_nosysex}, {_IDC_LYRICS_ENABLED,&cfg_lyrics}, {_IDC_SHOW_PANEL,&cfg_seq_showpanel}, }; #define NUM_BWNDS (sizeof(bWnds)/sizeof(*bWnds)) #define WM_CMDNOTIFY (WM_USER+6) static BOOL WINAPI CfgChildProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp) { if (msg==WM_COMMAND) { #if defined(_WIN64) SendMessage(GetParent(wnd),WM_CMDNOTIFY,wp,MAKEID(GetWindowLong(wnd,DWLP_USER),LOWORD(wp))); #else SendMessage(GetParent(wnd), WM_CMDNOTIFY, wp, MAKEID(GetWindowLong(wnd, DWL_USER), LOWORD(wp))); #endif } return 0; } static bool is_hex(char c) {return (c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F');} static UINT read_hex(char* t) { UINT r=0; while(is_hex(*t)) { r<<=4; if (*t>='0' && *t<='9') r|=*t-'0'; else if (*t>='a' && *t<='f') r|=*t-'a'+10; else r|=*t-'A'+10; t++; } return r; } BYTE* read_sysex_edit(HWND w,UINT *siz)//used in seq.cpp { UINT tl=GetWindowTextLength(w)+2; char* tx=(char*)malloc(tl); if (!tx) return 0; GetWindowTextA(w,tx,tl+2); UINT sl=0; BYTE* tmp=(BYTE*)malloc(tl/2+2); char* t=tx; if (!tmp) { free(tx); return 0; } tmp[sl++]=0xF0; while(t && *t) { while(!is_hex(*t) && *t) t++; if (!*t) break; tmp[sl++]=read_hex(t); while(is_hex(*t)) t++; } tmp[sl++]=0xF7; free(tx); *siz=sl; return tmp; } static BOOL WINAPI SysexProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp) { switch(msg) { case WM_INITDIALOG: #if defined(_WIN64) SetWindowLong(wnd,DWLP_USER,lp); #else SetWindowLong(wnd, DWL_USER, lp); #endif SendDlgItemMessage(wnd,IDC_SPIN1,UDM_SETRANGE,0,MAKELONG(9999,0)); SetDlgItemInt(wnd,IDC_DELAY,edit_sysex_table.get_time(lp),0); edit_sysex_table.print_edit(lp,GetDlgItem(wnd,IDC_EDIT1)); return 1; case WM_COMMAND: switch(wp) { case IDOK: { UINT size; BYTE* data=read_sysex_edit(GetDlgItem(wnd,IDC_EDIT1),&size); if (!data) { EndDialog(wnd,0); break; } #if defined(_WIN64) edit_sysex_table.modify_entry(GetWindowLong(wnd, DWLP_USER), data, size, GetDlgItemInt(wnd, IDC_DELAY, 0, 0)); #else edit_sysex_table.modify_entry(GetWindowLong(wnd, DWL_USER), data, size, GetDlgItemInt(wnd, IDC_DELAY, 0, 0)); #endif free(data); } EndDialog(wnd,1); break; case IDCANCEL: EndDialog(wnd,0); break; } } return 0; } extern int initDefaultDeviceShit(); static BOOL WINAPI CfgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp) { switch(msg) { case WM_INITDIALOG: if (g_theConfig && g_theConfig!=wnd) { ShowWindow(g_theConfig,SW_SHOW); EndDialog(wnd,0); return 0; } initDefaultDeviceShit(); g_theConfig=wnd; { HWND hTab=GetDlgItem(wnd,IDC_TAB); #if defined(_WIN64) SetWindowLong(wnd, DWLP_USER, (long)hTab); #else SetWindowLong(wnd, DWL_USER, (long)hTab); #endif HWND w; UINT n; TC_ITEMW it= { TCIF_TEXT, 0,0, 0, //pszText 0, -1,0 }; for(n=0;ndevice_enumerate(idx_device++)) { string_w temp; temp+=driver->get_name(); temp+=L" / "; temp+=device->get_name(); int idx_combo = SendMessageW(w,CB_ADDSTRING,0,(LPARAM)(const wchar_t*)temp); SendMessage(w,CB_SETITEMDATA,idx_combo,(long)device); if (driver->get_guid() == cfg_driver && device->get_guid() == cfg_device) { SendMessage(w,CB_SETCURSEL,idx_combo,0); ChangePort(wnd,device); } } } } w=_GetDlgItem(wnd,_IDC_WAVEIN); for(n=-1;n<(int)waveInGetNumDevs();n++) { WAVEINCAPS caps; if (waveInGetDevCaps((UINT)n,&caps,sizeof(caps))==MMSYSERR_NOERROR && caps.dwFormats!=0) { int idx=SendMessage(w,CB_ADDSTRING,0,(long)caps.szPname); SendMessage(w,CB_SETITEMDATA,idx,n); if (n==cfg_wavein_dev) SendMessage(w,CB_SETCURSEL,idx,0); } } cfgVisMix(wnd,cfg_wavein_dev); _SendDlgItemMessage(wnd,_IDC_WAVEIN_SRC,CB_SETCURSEL,cfg_wavein_src,0); w=_GetDlgItem(wnd,_IDC_PLAYBACK_METHOD); SendMessageW(w,CB_ADDSTRING,0,(long)WASABI_API_LNGSTRINGW(IDS_STREAMED)); SendMessageW(w,CB_ADDSTRING,0,(long)WASABI_API_LNGSTRINGW(IDS_IMMEDIATE)); SendMessage(w,CB_SETCURSEL,cfg_playback_mode,0); w=_GetDlgItem(wnd,_IDC_SYSEX_LIST); edit_sysex_table = cfg_sysex_table; { char temp[128] = {0}; n=0; while(edit_sysex_table.print_preview(n++,temp)) SendMessage(w,LB_ADDSTRING,0,(long)temp); } w=_GetDlgItem(wnd,_IDC_EXTS_LIST); for(n=0;n>3)-1,0); w=_GetDlgItem(wnd,_IDC_WAVEIN_SR); for(n=0;ncode==TCN_SELCHANGE) { UINT n; HWND hTab=((NMHDR*)lp)->hwndFrom; cfg_cur_tab=SendMessage(hTab,TCM_GETCURSEL,0,0); for(n=0;n>16) { switch(lp) { case _IDC_SYSEX_LIST: if (wp>>16==LBN_DBLCLK) { CfgProc(wnd,WM_CMDNOTIFY,0,_IDC_SYSEX_EDIT); } break; case _IDC_WAVEIN: if (wp>>16==CBN_SELCHANGE) { int d=_SendDlgItemMessage(wnd,_IDC_WAVEIN,CB_GETCURSEL,0,0); if (d>=0) cfgVisMix(wnd,_SendDlgItemMessage(wnd,_IDC_WAVEIN,CB_GETITEMDATA,d,0)); } break; case _IDC_PORT: if (wp>>16==CBN_SELCHANGE) { ChangePort(wnd,get_device(wnd)); } break; } } else { switch(lp) { case _IDC_DLS_CB: { int checked = _SendDlgItemMessage(wnd,_IDC_DLS_CB,BM_GETCHECK,0,0); EnableWindow(_GetDlgItem(wnd,_IDC_DLS),checked); EnableWindow(_GetDlgItem(wnd,_IDC_DLS_B),checked); } break; case _IDC_IMP_F: if (edit_sysex_table.num_entries()>0) { char fn[MAX_PATH] = {0}; if (DoOpenFile(wnd,fn,IDS_SYSEX_DATA,"SYX",0)) { HANDLE f=CreateFileA(fn,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0); if (f!=INVALID_HANDLE_VALUE) { DWORD sz=GetFileSize(f,0); BYTE * temp=(BYTE*)malloc(sz); if (temp) { DWORD br = 0; ReadFile(f,temp,sz,&br,0); edit_sysex_table.add_entry(temp,sz,0); free(temp); } char tmp[128] = {0}; edit_sysex_table.print_preview(edit_sysex_table.num_entries()-1,tmp); _SendDlgItemMessage(wnd,_IDC_SYSEX_LIST,LB_ADDSTRING,0,(long)tmp); CloseHandle(f); } else FILE_BLAH; } } break; case _IDC_IMP_PR: // if (!edit_sysex_table.is_empty()) { char fn[MAX_PATH] = {0}; fn[0]=0; if (DoOpenFile(wnd,fn,IDS_MIDI_HARDWARE_PRESETS,"MHP",0)) { if (!edit_sysex_table.file_read(fn)) { FILE_BLAH; } } } break; case _IDC_EXP_PR: if (!edit_sysex_table.is_empty()) { char fn[MAX_PATH] = {0}; fn[0]=0; if (DoOpenFile(wnd,fn,IDS_MIDI_HARDWARE_PRESETS,"MHP",1)) { if (!edit_sysex_table.file_write(fn)) { FILE_BLAH; } } } break; case _IDC_EXP_F: if (!edit_sysex_table.is_empty()) { UINT ns=_SendDlgItemMessage(wnd,_IDC_SYSEX_LIST,LB_GETCURSEL,0,0); if (ns!=-1) { char fn[MAX_PATH] = {0}; fn[0]=0; if (DoOpenFile(wnd,fn,IDS_SYSEX_DATA,"SYX",1)) { HANDLE f=CreateFileA(fn,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0); if (f!=INVALID_HANDLE_VALUE) { BYTE * data; int size = 0; edit_sysex_table.get_entry(ns,&data,&size,0); DWORD bw = 0; WriteFile(f,data,size,&bw,0); CloseHandle(f); } else FILE_BLAH; } } } break; case _IDC_SYSEX_EDIT: if (!edit_sysex_table.is_empty()) { HWND w=_GetDlgItem(wnd,_IDC_SYSEX_LIST); int n=SendMessage(w,LB_GETCURSEL,0,0); if (n!=-1 && nget_driver()->get_guid(); cfg_device = dev->get_guid(); } } { int t=_SendDlgItemMessage(wnd,_IDC_WAVEIN,CB_GETCURSEL,0,0); if (t<0) cfg_wavein_dev=-1; else cfg_wavein_dev = _SendDlgItemMessage(wnd,_IDC_WAVEIN,CB_GETITEMDATA,t,0); } cfg_wavein_sr=_GetDlgItemInt(wnd,_IDC_WAVEIN_SR,0,0); cfg_wavein_ch=_SendDlgItemMessage(wnd,_IDC_WAVEIN_CH,CB_GETCURSEL,0,0)+1; cfg_wavein_bps=(_SendDlgItemMessage(wnd,_IDC_WAVEIN_BPS,CB_GETCURSEL,0,0)+1)<<3; cfg_loop_type=_SendDlgItemMessage(wnd,_IDC_LOOP,CB_GETCURSEL,0,0); cfg_loop_count=_GetDlgItemInt(wnd,_IDC_LOOP_T,0,0); cfg_loop_infinite=_SendDlgItemMessage(wnd,_IDC_INFINITE,BM_GETCHECK,0,0); { int t=_SendDlgItemMessage(wnd,_IDC_FREQ,CB_GETCURSEL,0,0); if (t<0) cfg_freq=22050; else cfg_freq=11025<