#include "../Agave/Language/api_language.h" #include "main.h" #include #include "resource.h" #include "../Winamp/in2.h" #include "../Winamp/wa_ipc.h" extern In_Module mod; void get_temp_file(char* fn) { static char tmp_path[MAX_PATH]; if (!tmp_path[0]) GetTempPathA(MAX_PATH,tmp_path); static DWORD num; if (num==0) num=GetTickCount(); wsprintfA(fn,"%sasdf%x.tmp",tmp_path,num++); } void file2title(const char* f,string& t) { const char* p1=strrchr(f,'\\'),*p2=strrchr(f,':'),*p3=strrchr(f,'/'); if (p2>p1) p1=p2; if (p3>p1) p1=p3; if (p1) p1++; else p1=(char*)f; t=p1; p1=strrchr(t,'.'); if (p1) t.truncate(p1-(const char*)t); } static char* exts[]={"MID","MIDI","RMI","KAR","HMP","HMI","XMI","MSS","MUS","CMF","GMD","MIDS","MIZ","HMZ"}; #define N_EXTS tabsize(exts) static char is_def[N_EXTS]={1,1,1,1,0,0,0,0,0,0,0,0,1,0}; static int get_def_exts() { int ret=0; int n; for(n=0;nhas_output() || (cfg_smp && cfg_sampout); use_smp=cfg_smp && !device->has_output(); if (cfg_volmode>2) volmod=cfg_volmode-1; else if (cfg_volmode==2) volmod = device->volctrl_happy() ? 1 : volmode_detect()+2; else volmod=cfg_volmode; if (volmod>1) { UINT idx=volmod-2; UINT id=0; UINT n_devz=mixerGetNumDevs(); UINT dev=0; BOOL found=0; MIXERLINE ml; while(devhas_freq() ? cfg_freq : 44100; format_bps=16; format_nch=2; theFile=file->AddRef(); #ifdef USE_LOG log_write("file loaded"); #endif plr=0; if (use_smp) { #ifdef USE_LOG log_write("starting sampling"); #endif format_srate=cfg_wavein_sr; format_bps=cfg_wavein_bps; format_nch=cfg_wavein_ch; data_src=sampling_create(format_srate,format_nch,format_bps); } plr=device->create(); if (plr) { #ifdef USE_LOG if (data_src) log_write("got PCM data source"); log_write("playback started"); #endif if (cfg_lyrics) { kmap=kmap_create(theFile,1,&kmap_size,&kmap_data); if (kmap) { kwnd=WASABI_API_CREATEDIALOGPARAMW(IDD_LYRICS,MIDI_callback::GetMainWindow(),KarProc,0); free(kmap_data); kmap_data=0;//not needed anymore, used only on initdialog to setdlgitemtext } } return 1; } else { if (data_src) {delete data_src;data_src=0;} theFile->Free(); theFile=0; return 0; } } int MIDI_core::GetSamples(void *sample_buffer, int bytes, char *killswitch) { #ifdef USE_LOG log_write("GetSamples"); #endif if (data_src) { return data_src->ReadData(sample_buffer,bytes,(bool*)killswitch); } else return 0; } void MIDI_core::update_vol() { MIXERLINE ml; ZeroMemory(&ml,sizeof(ml)); ml.cbStruct=sizeof(ml); ml.dwSource=mix_idx; mixerGetLineInfo((HMIXEROBJ)mix_dev,&ml,MIXER_GETLINEINFOF_SOURCE|MIXER_OBJECTF_MIXER); MIXERLINECONTROLS cs; MIXERCONTROL c; ZeroMemory(&cs,sizeof(cs)); cs.cbStruct=sizeof(cs); cs.cControls=1; cs.dwLineID=ml.dwLineID; cs.dwControlType=MIXERCONTROL_CONTROLTYPE_VOLUME; cs.cbmxctrl=sizeof(c); cs.pamxctrl=&c; ZeroMemory(&c,sizeof(c)); c.cbStruct=sizeof(c); if (!mixerGetLineControls((HMIXEROBJ)mix_dev,&cs,MIXER_OBJECTF_MIXER|MIXER_GETLINECONTROLSF_ONEBYTYPE)) { DWORD val; if (cfg_logvol) { double _vol=volume>0 ? 20*log10((double)volume/255.0) : -60.0;//in negative db _vol=_vol/60.0+1; if (_vol<0) _vol=0; val=c.Bounds.dwMinimum + (int)( _vol * (double)(c.Bounds.dwMaximum-c.Bounds.dwMinimum) ); } else val=c.Bounds.dwMinimum + volume * (c.Bounds.dwMaximum-c.Bounds.dwMinimum) / 255; if (ml.cChannels==1) { MIXERCONTROLDETAILS_UNSIGNED ds={val}; MIXERCONTROLDETAILS d; d.cbStruct=sizeof(d); d.dwControlID=c.dwControlID; d.cChannels=1; d.cMultipleItems=0; d.cbDetails=sizeof(ds); d.paDetails=&ds; mixerSetControlDetails((HMIXEROBJ)mix_dev,&d,MIXER_SETCONTROLDETAILSF_VALUE|MIXER_OBJECTF_MIXER); } else if (ml.cChannels<16) { MIXERCONTROLDETAILS_UNSIGNED ds[16]; UINT n; for(n=0;n<16;n++) ds[n].dwValue=val; if (pan<0) { ds[1].dwValue=ds[1].dwValue*(128+pan)>>7; } else { ds[0].dwValue=ds[0].dwValue*(128-pan)>>7; } MIXERCONTROLDETAILS d; d.cbStruct=sizeof(d); d.dwControlID=c.dwControlID; d.cChannels=ml.cChannels; d.cMultipleItems=0; d.cbDetails=sizeof(ds[0]); d.paDetails=&ds; mixerSetControlDetails((HMIXEROBJ)mix_dev,&d,MIXER_SETCONTROLDETAILSF_VALUE|MIXER_OBJECTF_MIXER); } } /* ZeroMemory(&cs,sizeof(cs)); cs.cbStruct=sizeof(cs); cs.cControls=1; cs.dwLineID=ml.dwLineID; cs.dwControlType=MIXERCONTROL_CONTROLTYPE_PAN; cs.cbmxctrl=sizeof(c); cs.pamxctrl=&c; ZeroMemory(&c,sizeof(c)); c.cbStruct=sizeof(c); if (!mixerGetLineControls((HMIXEROBJ)mix_dev,&cs,MIXER_OBJECTF_MIXER|MIXER_GETLINECONTROLSF_ONEBYTYPE)) { MIXERCONTROLDETAILS_SIGNED ds={c.Bounds.lMinimum + (pan+128) * (c.Bounds.lMaximum-c.Bounds.lMinimum) / 255}; MIXERCONTROLDETAILS d; d.cbStruct=sizeof(d); d.dwControlID=c.dwControlID; d.cbDetails=sizeof(ds); d.cChannels=ml.cChannels; d.cMultipleItems=c.cMultipleItems; d.paDetails=&ds; mixerSetControlDetails((HMIXEROBJ)mix_dev,&d,MIXER_SETCONTROLDETAILSF_VALUE|MIXER_OBJECTF_MIXER); }*/ } int MIDI_core::SetVolume(int _volume) { volume=_volume; if (volmod==0) return 0; else { if (volmod==1) { if ((use_out && !use_smp) || !plr) { return 0; } else { return plr->setvol(player_getVol()); } } update_vol(); return 1; } } int MIDI_core::SetPan(int _pan) { pan=_pan; if (volmod==0) return 0; else { if (volmod==1) { if (plr) return plr->setpan(player_getPan()); else return 0; } else { update_vol(); return 1; } } } int MIDI_core::SetPosition(int pos) { if (!plr) return 0; if (!plr->settime(pos)) return 0; sync.enter(); kmap_ptr=0; LeaveCriticalSection(&sync); if (data_src) data_src->Flush(); return 1; } void MIDI_core::Pause(int pause) { if (plr) { if (pause) plr->pause(); else plr->unpause(); } if (data_src) data_src->Pause(pause); } int MIDI_core::GetPosition(void) { int i=0; if (plr) { i=plr->gettime(); if (i<0) i=0; } return i; } int MIDI_core::GetLength(void) { if (theFile) return theFile->len; else return -1; } void MIDI_core::Close() { #ifdef USE_LOG log_write("shutting down MIDI_core"); #endif if (plr) {delete plr;plr=0;} if (data_src) {delete data_src;data_src=0;} if (kwnd) {DestroyWindow(kwnd);kwnd=0;} if (kmap) {free(kmap);kmap=0;} if (theFile) {theFile->Free();theFile=0;} } void MIDI_core::Eof() { eof=1; if (data_src) data_src->Eof(); else MIDI_callback::NotifyEOF(); } static char INI_FILE[MAX_PATH]; void MIDI_core::GlobalInit() { #ifdef USE_LOG log_start(); log_write("initializing"); log_write(NAME); #endif char *p; if (mod.hMainWindow && (p = (char *)SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GETINIFILE)) && p!= (char *)1) { strcpy(INI_FILE, p); } else { GetModuleFileNameA(NULL,INI_FILE,sizeof(INI_FILE)); p = INI_FILE + strlen(INI_FILE); while (p >= INI_FILE && *p != '.') p--; strcpy(++p,"ini"); } cfg_var::config_read(INI_FILE,"in_midi"); } void MIDI_core::GlobalQuit() { MIDI_driver::shutdown(); log_quit(); } void MIDI_core::WriteConfig() { cfg_var::config_write(INI_FILE,"in_midi"); } void MIDI_core::MM_error(DWORD code) { string temp; if (!mciGetErrorStringA(code,string_buffer_a(temp,256),256)) { temp=WASABI_API_LNGSTRING(STRING_UNKNOWN_MMSYSTEM); } MIDI_callback::Error(temp); } static void fix_size(HWND wnd) { RECT r; GetClientRect(wnd,&r); SetWindowPos(GetDlgItem(wnd,IDC_BLAH),0,0,0,r.right,r.bottom,SWP_NOZORDER|SWP_NOACTIVATE); } static cfg_struct_t cfg_lyrics_pos("lyrics_pos",-1); static void SetWindowRect(HWND w,RECT* r) { SetWindowPos(w,0,r->left,r->top,r->right-r->left,r->bottom-r->top,SWP_NOZORDER); } static cfg_int cfg_lyrics_min("lyrics_min",0),cfg_lyrics_max("lyrics_max",0); BOOL CALLBACK MIDI_core::KarProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp) { switch(msg) { case WM_INITDIALOG: SetDlgItemTextA(wnd,IDC_BLAH,MIDI_core::kmap_data); if (cfg_lyrics_pos.get_val().left!=-1) { int sx=GetSystemMetrics(SM_CXSCREEN),sy=GetSystemMetrics(SM_CYSCREEN); if (cfg_lyrics_pos.get_val().right>sx) { cfg_lyrics_pos.get_val().left-=cfg_lyrics_pos.get_val().right-sx; cfg_lyrics_pos.get_val().right=sx; } if (cfg_lyrics_pos.get_val().bottom>sy) { cfg_lyrics_pos.get_val().top-=cfg_lyrics_pos.get_val().bottom-sy; cfg_lyrics_pos.get_val().bottom=sy; } if (cfg_lyrics_pos.get_val().left<0) { cfg_lyrics_pos.get_val().right-=cfg_lyrics_pos.get_val().left; cfg_lyrics_pos.get_val().left=0; } if (cfg_lyrics_pos.get_val().top<0) { cfg_lyrics_pos.get_val().bottom-=cfg_lyrics_pos.get_val().top; cfg_lyrics_pos.get_val().top=0; } SetWindowRect(wnd,&cfg_lyrics_pos.get_val()); } if (cfg_lyrics_min) { ShowWindow(wnd,SW_MINIMIZE); } else if (cfg_lyrics_max) { ShowWindow(wnd,SW_MAXIMIZE); } fix_size(wnd); SetTimer(wnd,1,100,0); return 1; case WM_TIMER: { sync.enter(); UINT time=GetPosition(); KAR_ENTRY * set=0; UINT ptr=kmap_ptr; while(ptrstart,set->end); } } break; case WM_DESTROY: KillTimer(wnd,1); kwnd=0; GetWindowRect(wnd,&cfg_lyrics_pos.get_val()); cfg_lyrics_max=!!IsZoomed(wnd); cfg_lyrics_min=!!IsIconic(wnd); break; case WM_CLOSE: cfg_lyrics=0; if (!((int)cfg_bugged & BUGGED_BLAH)) { char title[32] = {0}; cfg_bugged = (int)cfg_bugged | BUGGED_BLAH; MessageBoxA(wnd,WASABI_API_LNGSTRING(IDS_TO_ENABLE_LYRICS_DISPLAY), WASABI_API_LNGSTRING_BUF(IDS_INFORMATION,title,32),MB_ICONINFORMATION); } DestroyWindow(wnd); break; case WM_SIZE: fix_size(wnd); break; } return 0; } //MIDI_core static crap bool MIDI_core::use_out; MIDI_file* MIDI_core::theFile; CStream* MIDI_core::data_src; player_base* MIDI_core::plr; int MIDI_core::format_srate,MIDI_core::format_nch,MIDI_core::format_bps; int MIDI_core::volume=255,MIDI_core::pan=0; bool MIDI_core::eof; UINT MIDI_core::volmod; UINT MIDI_core::mix_dev,MIDI_core::mix_idx; MIDI_device * MIDI_core::device; bool MIDI_core::use_smp; HWND MIDI_core::kwnd; KAR_ENTRY* MIDI_core::kmap; UINT MIDI_core::kmap_size,MIDI_core::kmap_ptr; char * MIDI_core::kmap_data; critical_section MIDI_core::sync;