123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 |
- #include "../Agave/Language/api_language.h"
- #include "main.h"
- #include <math.h>
- #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;n<N_EXTS;n++)
- {
- if (is_def[n]) ret|=1<<n;
- }
- return ret;
- }
- cfg_int cfg_ext_mask("ext_mask",get_def_exts());
- static char d_smf[128];
- static char d_clo[128];
- static char d_cmp[128];
- int ext_descs[N_EXTS]={STRING_FILES_SMF,STRING_FILES_SMF,STRING_FILES_SMF,STRING_FILES_SMF,STRING_FILES_CLONE,STRING_FILES_CLONE,STRING_FILES_CLONE,STRING_FILES_CLONE,STRING_FILES_CLONE,STRING_FILES_CLONE,STRING_FILES_CLONE,STRING_FILES_CLONE,STRING_FILES_COMPRESSED,STRING_FILES_COMPRESSED};
- int MIDI_core::FileTypes_GetNum() {return N_EXTS;}
- const char * MIDI_core::FileTypes_GetExtension(int n) {return exts[n];}
- char * MIDI_core::FileTypes_GetDescription(int n) {
- char* s = d_smf;
- if(ext_descs[n] == STRING_FILES_SMF) {
- if(!d_smf[0]) {
- WASABI_API_LNGSTRING_BUF(ext_descs[n],d_smf,128);
- }
- s = d_smf;
- }
- else if(ext_descs[n] == STRING_FILES_CLONE) {
- if(!d_clo[0]) {
- WASABI_API_LNGSTRING_BUF(ext_descs[n],d_clo,128);
- }
- s = d_clo;
- }
- else if(ext_descs[n] == STRING_FILES_COMPRESSED) {
- if(!d_cmp[0]) {
- WASABI_API_LNGSTRING_BUF(ext_descs[n],d_cmp,128);
- }
- s = d_cmp;
- }
- return s;
- }
- static int isourext(const char* ext)
- {
- UINT n;
- for(n=0;n<N_EXTS;n++)
- {
- if ((cfg_ext_mask&(1<<n)) && !_stricmp(ext,exts[n])) return 1;
- }
- return 0;
- }
- int MIDI_core::IsOurFile(const char *fn)
- {
- const char* p=strrchr(fn,'.');
- if (p)
- {
- if (isourext(p+1)) return 1;
- }
- return 0;
- }
- extern UINT volmode_detect();
- static BOOL CALLBACK KarProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp);
- int MIDI_core::Init()
- {
- theFile=0;
- data_src=0;
- plr=0;
- eof=0;
- mix_dev=0;mix_idx=0;
- kwnd=0;
- kmap=0;
- kmap_size=0;kmap_ptr=0;
- kmap_data=0;
- format_srate=0;format_nch=0;format_bps=0;
- device=MIDI_driver::find_device(cfg_driver,cfg_device);
- if (!device) return 0;
- use_out=device->has_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(dev<n_devz)
- {
- mixerGetID((HMIXEROBJ)dev,&id,MIXER_OBJECTF_MIXER);
- ZeroMemory(&ml,sizeof(ml));
- ml.cbStruct=sizeof(ml);
- ml.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
- mixerGetLineInfo((HMIXEROBJ)id,&ml,MIXER_GETLINEINFOF_COMPONENTTYPE|MIXER_OBJECTF_MIXER);
- if (idx<ml.cConnections)
- {
- found=1;
- break;
- }
- idx-=ml.cConnections;
- dev++;
- }
- if (found)
- {
- mix_dev=id;
- mix_idx=idx;
- }
- else
- {
- volmod=0;
- }
- }
- return 1;
- }
- CStream * sampling_create(int srate,int nch,int bps);
- cfg_int cfg_lyrics("lyrics",1);
- int MIDI_core::OpenFile(MIDI_file * file)
- {
- #ifdef USE_LOG
- log_write("MIDI_core::Open()");
- #endif
- if (!file) return 0;
- format_srate=device->has_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<RECT> 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(ptr<kmap_size && kmap[ptr].time<time)
- {
- if (!kmap[ptr].foo) set=&kmap[ptr];
- ptr++;
- }
- kmap_ptr=ptr;
- sync.leave();
- if (set)
- {
- SendDlgItemMessage(wnd,IDC_BLAH,EM_SETSEL,set->start,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;
|