123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888 |
- #include "main.h"
- #include "seq.h"
- #include <math.h>
- #include "resource.h"
- // {76B6A32D-99A9-4d51-B1F5-DAD3F47FE75D}
- static const GUID midiout_guid =
- { 0x76b6a32d, 0x99a9, 0x4d51, { 0xb1, 0xf5, 0xda, 0xd3, 0xf4, 0x7f, 0xe7, 0x5d } };
- // {7F00BC9C-AEA3-472a-BBB9-D74ABD4FCA58}
- static const GUID midiout_driver_guid =
- { 0x7f00bc9c, 0xaea3, 0x472a, { 0xbb, 0xb9, 0xd7, 0x4a, 0xbd, 0x4f, 0xca, 0x58 } };
- static MMRESULT midiOutOpen_wrap(HMIDIOUT * hMo,int id)
- {
- try {
- return midiOutOpen(hMo,(UINT)id,0,0,CALLBACK_NULL);
- }
- catch(...)
- {
- return -1;
- }
- }
- class MIDI_device_midiout : public MIDI_device
- {
- private:
- GUID guid;
- UINT id;
- DWORD flags;
- UINT type;
- virtual player_base * create();
- virtual GUID get_guid() {return guid;}
- virtual bool is_default() {return id==(UINT)(-1);}
- virtual bool volctrl_happy() {return (type==7) && (flags & MIDICAPS_VOLUME);}
- public:
- MIDI_device_midiout(UINT p_id,DWORD p_flags,UINT p_type,const wchar_t * p_name,const wchar_t * p_info)
- {
- id=p_id;
- guid = midiout_guid;
- *(DWORD*)&guid+=id;
- flags = p_flags;
- type = p_type;
- set_name(p_name);
- set_info(p_info);
- }
- inline DWORD get_flags() {return flags;}
- inline DWORD get_id() {return id;}
- };
- static void midiout_sysex(HMIDIOUT hMo,BYTE* p,UINT len)
- {
- MIDIHDR h;
- ZeroMemory(&h,sizeof(h));
- h.dwBytesRecorded=h.dwBufferLength=len;
- h.lpData=(char*)p;
- if (FAILED(midiOutPrepareHeader(hMo,&h,sizeof(h)))) {
- #ifdef USE_LOG
- log_write("unable to send sysex");
- #endif
- return;
- }
- if (SUCCEEDED(midiOutLongMsg(hMo,&h,sizeof(h))))
- {
- while(!(h.dwFlags&MHDR_DONE)) MIDI_callback::Idle();
- }
- midiOutUnprepareHeader(hMo,&h,sizeof(h));
- //log_write("sysex sent OK");
- }
- void midiout_sysex(HMIDIOUT hMo,BYTE* p,UINT len);
- static void sysex_startup_midiout(UINT m_id)
- {
- if (need_sysex_start())
- {
- // MessageBox(GetActiveWindow(),"blah",0,0);
- HMIDIOUT hMo;
- MMRESULT r=midiOutOpen_wrap(&hMo,m_id);
- if (!r)
- {
- sysex_startup((SYSEXFUNC)midiout_sysex,hMo);
- midiOutClose(hMo);
- }
- }
- }
- class midiout_volctrl
- {
- private:
- HMIDIOUT hMo;
- int vol,pan;
- void _setvol();
- static UINT map_vol(UINT volume,UINT scale);
- public:
- void volctrl_init(HMIDIOUT,MIDI_device_midiout*);
- int volctrl_setvol(int);
- int volctrl_setpan(int);
- };
- class player_midiout : public seq_base, private midiout_volctrl
- {
- public:
- virtual ~player_midiout();
- virtual int setvol(int i) {return volctrl_setvol(i);};
- virtual int setpan(int i) {return volctrl_setpan(i);};
- player_midiout(MIDI_device_midiout * p_dev)
- {
- dev=p_dev;
- hMo=0;
- }
-
- int play();
- private:
- MIDI_device_midiout * dev;
- HMIDIOUT hMo;
- virtual void seq_shortmsg(DWORD msg) {midiOutShortMsg(hMo,msg);}
- virtual void seq_sysex(BYTE* ptr,UINT len) {midiout_sysex(hMo,ptr,len);}
- virtual int seq_play_start();
- virtual void seq_play_stop();
- };
- int player_midiout::seq_play_start()
- {
- return 1;
- }
- void player_midiout::seq_play_stop()
- {
- if (hMo)
- {
- #ifdef USE_LOG
- log_write("midiOutClose");
- #endif
- DWORD r=midiOutClose(hMo);
- if (r==MIDIERR_STILLPLAYING)
- {
- log_write("still playing (?), calling midiOutReset");
- midiOutReset(hMo);
- r=midiOutClose(hMo);
- }
- #ifdef USE_LOG
- if (r) log_write("warning: unable to close midiOut");
- else log_write("midiOut closed OK");
- #endif
- }
- hMo=0;
- }
- int player_midiout::play()
- {
- DWORD r=midiOutOpen_wrap(&hMo,dev->get_id());
- if (r)
- {
- if (r!=-1) MIDI_core::MM_error(r);
- return 0;
- }
- volctrl_init(hMo,dev);
-
- if (!seq_cmd_start(0))
- {
- midiOutClose(hMo);
- hMo=0;
- return 0;
- }
- return 1;
- }
- player_midiout::~player_midiout()
- {
- #ifdef USE_LOG
- log_write("shutting down midiOut");
- #endif
- seq_cmd_stop();
- }
- class MIDI_driver_midiout : MIDI_driver
- {
- virtual void do_init()
- {
- MIDIOUTCAPSW caps;
- UINT n_mo_dev=midiOutGetNumDevs()+1;
- UINT n;
- for(n=0;n<n_mo_dev;n++)
- {
- midiOutGetDevCapsW(n-1,&caps,sizeof(MIDIOUTCAPSW));
- //d.id = TYPE_MIDIOUT | n;
- //d.name=(char*)_strdup(caps.szPname);
- string_w info;
- {
- wchar_t moo[128], *t=0;
- switch(caps.wTechnology)
- {
- case MOD_FMSYNTH:
- t=WASABI_API_LNGSTRINGW_BUF(STRING_MOCAPS_FM,moo,128);
- break;
- case MOD_MAPPER:
- t=WASABI_API_LNGSTRINGW_BUF(STRING_MOCAPS_MAPPER,moo,128);
- break;
- case MOD_MIDIPORT:
- t=WASABI_API_LNGSTRINGW_BUF(STRING_MOCAPS_HWPORT,moo,128);
- break;
- case MOD_SQSYNTH:
- t=WASABI_API_LNGSTRINGW_BUF(STRING_MOCAPS_SQUARE,moo,128);
- break;
- case MOD_SYNTH:
- t=WASABI_API_LNGSTRINGW_BUF(STRING_MOCAPS_SYNTH,moo,128);
- break;
- case 6:
- t=WASABI_API_LNGSTRINGW_BUF(STRING_MOCAPS_WAVETABLE,moo,128);
- break;
- case 7:
- t=WASABI_API_LNGSTRINGW_BUF(STRING_DMCAPS_SOFTSYNTH,moo,128);
- break;
- default:
- wsprintfW(moo,WASABI_API_LNGSTRINGW(STRING_UNKNOWN),caps.wTechnology);
- t=moo;
- break;
- }
- if (t)
- {
- info+=WASABI_API_LNGSTRINGW(STRING_DEVICE_TYPE);
- info+=t;
- info+=L"\x0d\x0a";
- }
- if (caps.dwSupport & MIDICAPS_STREAM)
- {
- info+=WASABI_API_LNGSTRINGW(STRING_DIRECT_MIDISTREAM);
- info+=L"\x0d\x0a";
- }
- }
- add_device(new MIDI_device_midiout(n-1,caps.dwSupport,caps.wTechnology,caps.szPname,info));
- }
- }
- virtual const wchar_t * get_name() {return L"midiOut";}
- virtual bool is_default() {return 1;}
- virtual GUID get_guid() {return midiout_driver_guid;}
- };
- static MIDI_driver_midiout midi_driver_midiout;
- #define WM_SEEK (WM_USER+4)
- #define GET_TIME timeGetTime()
- int IS_SPEC_C(int x);
- #define BUF_MAX 0x1000//0x3C00
- #define BUF_MAX_F (BUF_MAX+0x40)
- #define N_BUFS 4
- #define BUF_MASK (N_BUFS-1)
- typedef struct
- {
- MIDIHDR h;
- DWORD data[BUF_MAX_F];
- } MIDIBUF;
- class player_midistream : public player_base, private midiout_volctrl
- {
- public:
- int gettime();
- int settime(int);
- void pause();
- void unpause();
- virtual int setvol(int i) {return volctrl_setvol(i);};
- virtual int setpan(int i) {return volctrl_setpan(i);};
- int play();
- player_midistream(MIDI_device_midiout *);
- ~player_midistream();
- private:
- UINT renderbuf(MIDIHDR* buf,DWORD ts,UINT start,UINT end);
- UINT renderbuf_seek(UINT start,UINT end);
- void renderbuf_wait(MIDIHDR* buf,UINT len);
- DWORD pos4time(DWORD t);
- MIDI_device_midiout * dev;
- UINT m_id;
- UINT c_loop;
- CSysexMap* smap;
- HMIDISTRM hMo;
- UINT n_events;
- MIDI_EVENT* events;
- DWORD tm_ofs,p_time;
- UINT loop_start,total_len;
- MIDIBUF hdrs[N_BUFS];
- MIDIBUF seekbuf;
- UINT cur_buf;
- UINT in_mm,n_free;
- DWORD ct,cp;
- bool got_eof,paused,quitting;
- UINT seek_to;
-
- HWND wnd;
- DWORD trd_id;
- void do_bufs();
- void buf_done(MIDIHDR*);
- static LRESULT WINAPI midiOutProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp);
- };
- /*
- static void _sysex(player_midistream* pl,BYTE* p,UINT len)
- {//assumes thread to be OK
- HMIDISTRM hMo=pl->hMo;
- MIDIHDR h;
- ZeroMemory(&h,sizeof(h));
- h.dwUser=1;
- DWORD l=12+len;
- if (l&3) l=(l+4)&~3;
- DWORD* ev=(DWORD*)alloca(l);
- ev[0]=ev[1]=0;
- ev[2]=MEVT_F_LONG|len;
- memcpy(ev+3,p,len);
- h.dwBytesRecorded=h.dwBufferLength=l;
- h.lpData=(char*)ev;
- if (FAILED(midiOutPrepareHeader((HMIDIOUT)hMo,&h,sizeof(h)))) return;
- if (FAILED(midiStreamOut(hMo,&h,sizeof(h))))
- {
- midiOutUnprepareHeader((HMIDIOUT)hMo,&h,sizeof(h));
- return;
- }
- pl->in_mm++;
- do_messages(pl->wnd,(bool*)&h.dwUser);
- log_write("sysex sent OK");
- }*/
- DWORD player_midistream::pos4time(DWORD t)
- {
- DWORD r=0;
- while(r<n_events && events[r].tm<t) r++;
- return r;
- }
- static cfg_int cfg_midistream_quick_seek("midistream_quick_seek",0);
- void player_midistream::do_bufs()
- {
- if (seek_to!=-1)
- {
- UINT sp=pos4time(ct=seek_to);
- if (!cfg_midistream_quick_seek)
- {
- UINT st=cp;
- if (sp<cp) st=0;
- if (renderbuf_seek(st,sp)!=-1)
- {
- if (!midiOutPrepareHeader((HMIDIOUT)hMo,&seekbuf.h,sizeof(MIDIHDR)))
- {
- if (!midiStreamOut(hMo,&seekbuf.h,sizeof(MIDIHDR)))
- {
- in_mm++;
- }
- else midiOutUnprepareHeader((HMIDIOUT)hMo,&seekbuf.h,sizeof(MIDIHDR));
- }
- }
- }
- cp=sp;
- seek_to=-1;
- }
- while(n_free && !got_eof)
- {
- MIDIHDR* hdr=&hdrs[cur_buf].h;
- cp=renderbuf(hdr,ct,cp,-1);
- if (cp==-1)
- {
- if (loop_start!=-1 && c_loop>1)
- {
- c_loop--;
- cp=pos4time(ct=loop_start);
- continue;
- }
- else
- {
- got_eof=1;
- if (cfg_eof_delay)
- {
- renderbuf_wait(hdr,cfg_eof_delay);
- }
- else break;
-
- }
- }
- if (midiOutPrepareHeader((HMIDIOUT)hMo,hdr,sizeof(MIDIHDR)))
- {
- got_eof=1;
- break;
- }
- if (midiStreamOut(hMo,hdr,sizeof(MIDIHDR)))
- {
- got_eof=1;
- break;
- }
- cur_buf=(cur_buf+1)&BUF_MASK;
- in_mm++;
- n_free--;
- if (!got_eof)
- ct=cp ? events[cp-1].tm : 0;
- }
- }
- UINT player_midistream::renderbuf(MIDIHDR* buf,DWORD ts,UINT start,UINT end)
- {
- UINT n=start;
- UINT p=0;
- DWORD* pEv=(DWORD*)buf->lpData;
- UINT c_t=ts;
- while(n<end && n<n_events && p<(BUF_MAX-3))
- {
- int dt=events[n].tm-c_t;
- if (dt<0) dt=0;
- pEv[p++]=dt;
- c_t+=dt;
- pEv[p++]=0;
- if (events[n].ev&0x80000000)
- {
- SYSEX_ENTRY* se=&smap->events[events[n].ev&0x7FFFFFFF];
- if (p+(se->len>>2)>=BUF_MAX)
- {
- p-=2;
- break;
- }
- pEv[p++]=MEVT_F_LONG|se->len;
- DWORD d=se->len>>2;
- if (se->len&3)
- {
- pEv[p+(d++)]=0;
- }
- memcpy(pEv+p,smap->data+se->ofs,se->len);
- p+=d;
- }
- else
- {
- pEv[p++]=events[n].ev;
- }
- n++;
- }
- if (p==0)
- return -1;
- buf->dwBufferLength=p<<2;
- buf->dwBytesRecorded=p<<2;
- buf->dwFlags=0;
- return n;
- }
- void player_midistream::renderbuf_wait(MIDIHDR* buf,UINT len)
- {
- UINT p=0;
- DWORD* pEv=(DWORD*)buf->lpData;
- pEv[p++]=len<<3;
- pEv[p++]=0;
- pEv[p++]=MEVT_NOP<<24;
- buf->dwBufferLength=p<<2;
- buf->dwBytesRecorded=p<<2;
- buf->dwFlags=0;
- }
- UINT player_midistream::renderbuf_seek(UINT start,UINT end)
- {
- BYTE ins_tab[16] = {0};
- memset(ins_tab,-1,sizeof(ins_tab));
- BYTE ctrl_tab[16][128] = {0};
- memset(ctrl_tab,-1,sizeof(ctrl_tab));
- UINT n=start;
- DWORD* pEv=(DWORD*)seekbuf.h.lpData;
- while(n<end)
- {
- DWORD ec=events[n].ev;
- if (ec&0x80000000) {n++;continue;}
- UINT ch,cd;
-
- ch=ec&0xF;
- cd=ec&0xF0;
- if (cd==0xB0) ctrl_tab[ch][(ec>>8)&0x7F]=(BYTE)(ec>>16);
- else if (cd==0xC0) ins_tab[ch]=(BYTE)(ec>>8);
- n++;
- }
- UINT c;
- UINT p=0;
- for(c=0;c<16;c++)
- {
- for(n=0;n<128;n++)
- {
- if (!(ctrl_tab[c][n]&0x80))
- {
- pEv[p++]=0;
- pEv[p++]=0;
- pEv[p++]=0xB0|c|(n<<8)|(ctrl_tab[c][n]<<16);
- }
- if (p>=BUF_MAX)
- goto q;
- }
- if (!(ins_tab[c]&0x80))
- {
- pEv[p++]=0;
- pEv[p++]=0;
- pEv[p++]=0xC0|c|(ins_tab[c]<<8);
- }
- if (p>=BUF_MAX)
- goto q;
- }
- q:
- if (p==0) return -1;
-
- seekbuf.h.dwBufferLength=p<<2;
- seekbuf.h.dwBytesRecorded=p<<2;
- seekbuf.h.dwFlags=0;
- return n;
- }
- void player_midistream::buf_done(MIDIHDR* h)
- {
- in_mm--;
- midiOutUnprepareHeader((HMIDIOUT)hMo,h,sizeof(MIDIHDR));
- if (h->dwUser)
- {
- h->dwUser=0;
- return;
- }
- if (h==&seekbuf.h) return;
- n_free++;
- if (quitting) return;
- if (!in_mm && got_eof)
- MIDI_core::Eof();
- else if (!got_eof)
- {
- do_bufs();
- }
- }
- LRESULT WINAPI player_midistream::midiOutProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
- {
- if (msg==MM_MOM_DONE)
- {
- player_midistream* p=(player_midistream*)GetWindowLong(wnd,0);
- if (p) p->buf_done((MIDIHDR*)lp);
- }
- else if (msg==WM_SEEK)
- {
- player_midistream* p=(player_midistream*)GetWindowLong(wnd,0);
- if (p) p->settime(lp);
- }
- return DefWindowProc(wnd,msg,wp,lp);
- }
- player_midistream::player_midistream(MIDI_device_midiout * p_dev)
- {
- dev=p_dev;
- m_id=0;
- c_loop=0;
- smap=0;
- hMo=0;
- n_events=0;
- events=0;
- tm_ofs=0;p_time=0;
- loop_start=0;
- total_len=0;
- memset(&hdrs,0,sizeof(hdrs));
- memset(&seekbuf,0,sizeof(seekbuf));
- cur_buf=0;
- in_mm=0;n_free=0;
- ct=0;cp=0;
- got_eof=0;
- paused=0;
- quitting=0;
- seek_to=0;
-
- wnd=0;
- trd_id=0;
- static ATOM cb_class;
- if (!cb_class) cb_class=do_callback_class(midiOutProc);
- wnd=create_callback_wnd(cb_class,this);
- c_loop=cfg_loop_infinite ? -1 : cfg_loop_count;
- }
- player_base* MIDI_device_midiout::create()
- {
- if (cfg_playback_mode)
- {
- player_midiout *p=new player_midiout(this);
- if (p)
- {
- if (!p->play()) {delete p;p=0;}
- }
- return p;
- }
- else
- {
- player_midistream *p=new player_midistream(this);
- if (p)
- {
- if (!p->play()) {delete p;p=0;}
- }
- return p;
- }
- }
- //extern bool cfg_alt_sysex;
- int player_midistream::play()
- {
- trd_id=GetCurrentThreadId();
- UINT n;
- for(n=0;n<N_BUFS;n++)
- {
- hdrs[n].h.lpData=(char*)hdrs[n].data;
- }
- seekbuf.h.lpData=(char*)seekbuf.data;
-
- //bool alt_sysex=cfg_alt_sysex;
- //if (alt_sysex)
- {
- sysex_startup_midiout(dev->get_id());
- }
- #ifdef USE_LOG
- log_write("starting midiOut / streamed");
- #endif
- {
- UINT id=dev->get_id();
- DWORD err=midiStreamOpen(&hMo,&id,1,(DWORD)wnd,0,CALLBACK_WINDOW);
- if (err)
- {
- MIDI_core::MM_error(err);
- return 0;
- }
- MIDIPROPTIMEDIV td;
- td.cbStruct=sizeof(td);
- td.dwTimeDiv=1*8;//tix / q
- err=midiStreamProperty(hMo,(BYTE*)&td,MIDIPROP_SET|MIDIPROP_TIMEDIV);
- if (err)
- {
- midiStreamClose(hMo);
- MIDI_core::MM_error(err);
- return 0;
- }
- MIDIPROPTEMPO tempo;
- tempo.cbStruct=sizeof(tempo);
- tempo.dwTempo=1000;//ns / q
- err=midiStreamProperty(hMo,(BYTE*)&tempo,MIDIPROP_SET|MIDIPROP_TEMPO);
- if (err)
- {
- midiStreamClose(hMo);
- MIDI_core::MM_error(err);
- return 0;
- }
- }
-
- events=do_table(MIDI_core::getFile(),8,&n_events,&loop_start,0);
- if (!events)
- {
- midiStreamClose(hMo);
- hMo=0;
- return 0;
- }
- total_len=events[n_events-1].tm>>3;
- if (!cfg_nosysex && MIDI_core::getFile()->smap && MIDI_core::getFile()->smap->pos)
- {
- smap=MIDI_core::getFile()->smap;
- }
- else smap=0;
- paused=0;
- volctrl_init((HMIDIOUT)hMo,dev);
- midiStreamPause(hMo);
- //sysex_startup((SYSEXFUNC)midiout_sysex,hMo);
- seek_to=-1;
- tm_ofs=GET_TIME;
- cur_buf=0;
- in_mm=0;
- n_free=N_BUFS;
- ct=cp=0;
- do_bufs();
- #ifdef USE_LOG
- log_write("started OK");
- #endif
- midiStreamRestart(hMo);
- return 1;
- }
- player_midistream::~player_midistream()
- {
- // bool alt_sysex=cfg_alt_sysex;
- #ifdef USE_LOG
- log_write("shutting down midistream");
- #endif
- if (hMo)
- {
- //ASSERT(trd_id!=GetCurrentThreadId());
- quitting=1;
- #ifdef USE_LOG
- log_write("midiStreamStop");
- #endif
- midiStreamStop(hMo);
-
- // do_messages(wnd,(bool*)&in_mm);
- if (n_free!=N_BUFS)
- {
- UINT n;
- for(n=0;n<N_BUFS;n++)
- {
- if (hdrs[n].h.dwFlags&MHDR_PREPARED)
- {
- midiOutUnprepareHeader((HMIDIOUT)hMo,&hdrs[n].h,sizeof(MIDIHDR));
- in_mm--;
- n_free++;
- }
- }
- }
- #ifdef HUNT_LEAKS
- if (n_free!=N_BUFS) Warning("Not all buffers collected.");
- #endif
- #ifdef USE_LOG
- log_write("midiStreamClose");
- #endif
- midiStreamClose(hMo);
- //if (midiStreamClose(hMo)) Warning(STRING_MIDISTREAM_WARNING);
- }
- if (events) free(events);
- if (wnd) DestroyWindow(wnd);
- #ifdef USE_LOG
- log_write("midistream shut down");
- #endif
- }
- int player_midistream::gettime()
- {
- DWORD ret;
- if (paused) ret=p_time;
- else if (!tm_ofs) ret=0;
- else
- {
- ret=GET_TIME-tm_ofs;
- if (loop_start!=-1 && ret>total_len)
- {
- UINT _ls=loop_start>>3;
- ret=(ret-_ls)%(total_len-_ls)+_ls;
- }
- }
- return ret;
- }
- int player_midistream::settime(int tm)
- {
- if (!paused)
- {
- if (trd_id==GetCurrentThreadId())
- {
- seek_to=tm<<3;
- got_eof=0;
- tm_ofs=GET_TIME-tm;
- midiStreamStop(hMo);
- midiStreamPause(hMo);
- quitting=1;
- do_messages(wnd,(bool*)&in_mm);
- quitting=0;
- do_bufs();
- midiStreamRestart(hMo);
- }
- else PostMessage(wnd,WM_SEEK,0,tm);
- }
- else
- {
- p_time=tm;
- }
- return 1;
- }
- void player_midistream::pause()
- {
- p_time=GET_TIME-tm_ofs;
- paused=1;
- midiStreamPause(hMo);
- }
- void player_midistream::unpause()
- {
- tm_ofs=GET_TIME-p_time;
- paused=0;
- if (seek_to!=-1)
- {
- midiStreamStop(hMo);
- midiStreamPause(hMo);
- if (trd_id==GetCurrentThreadId())
- {
- quitting=1;
- do_messages(wnd,(bool*)&in_mm);
- quitting=0;
- do_bufs();
- }
- }
- midiStreamRestart(hMo);
- }
- UINT midiout_volctrl::map_vol(UINT volume,UINT scale)
- {
- double _vol=volume>0 ? 20*log10((double)volume/(double)scale) : -60.0;//in negative db
- _vol=_vol/60.0+1;
- if (_vol<0) _vol=0;
- return (UINT)(_vol*(double)scale);
- }
- void midiout_volctrl::_setvol()
- {
- DWORD _vol=257*vol;
- DWORD vol1=_vol,vol2=_vol;
- if (pan!=666)
- {
- if (pan<0)
- {
- vol2=(vol2*(128+pan))>>7;
- }
- else if (pan>0)
- {
- vol1=(vol1*(128-pan))>>7;
- }
- }
- if (cfg_logvol)
- {
- vol1=map_vol(vol1,0xFFFF);
- vol2=map_vol(vol2,0xFFFF);
- }
- midiOutSetVolume((HMIDIOUT)hMo,(vol2<<16)|vol1);
- }
- void midiout_volctrl::volctrl_init(HMIDIOUT _hMo,MIDI_device_midiout * dev)
- {
- hMo=_hMo;
- pan=(dev->get_flags()&MIDICAPS_LRVOLUME) ? MIDI_core::player_getPan() : 666;
- vol=(dev->get_flags()&MIDICAPS_VOLUME) ? MIDI_core::player_getVol() : 666;
- _setvol();
- }
- int midiout_volctrl::volctrl_setvol(int _vol)
- {
- if (vol!=666)
- {
- vol=_vol;
- _setvol();
- return 1;
- }
- else return 0;
- }
- int midiout_volctrl::volctrl_setpan(int _pan)
- {
- if (pan!=666)
- {
- pan=_pan;
- _setvol();
- return 1;
- }
- else return 0;
- }
|