12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064 |
- #include "main.h"
- #include "../Agave/language/api_language.h"
- #include <commdlg.h>
- #include "resource.h"
- DWORD _fastcall rev32(DWORD d) {return _rv(d);}
- void CPipe::WriteData(void* b,UINT s)
- {
- if (closed) return;
- sec.enter();
- if (buf_n+s>buf_s)
- {
- #ifdef USE_LOG
- log_write("buffer overflow");
- #endif
- s=buf_s-buf_n;
- s-=s%align;
- }
- if (s)
- {
- if (buf_wp+s<buf_s)
- {
- memcpy(buf+buf_wp,b,s);
- buf_wp+=s;
- }
- else
- {
- UINT d=buf_s-buf_wp;
- memcpy(buf+buf_wp,b,d);
- memcpy(buf,(BYTE*)b+d,s-d);
- buf_wp=s-d;
- }
- buf_n+=s;
- }
- sec.leave();
- }
- UINT CPipe::ReadData(void* _b,UINT s,bool* ks)
- {
- UINT rv=0;
- BYTE * b=(BYTE*)_b;
- sec.enter();
- while(1)
- {
- UINT d=s;
- if (d>buf_n) d=buf_n;
- if (d)
- {
- if (buf_rp+d<buf_s)
- {
- memcpy(b,buf+buf_rp,d);
- buf_rp+=d;
- }
- else
- {
- UINT d1=buf_s-buf_rp;
- memcpy(b,buf+buf_rp,d1);
- memcpy(b+d1,buf,d-d1);
- buf_rp=d-d1;
- }
- buf_n-=d;
- s-=d;
- rv+=d;
- b+=d;
- }
- if (closed || !s || *ks) break;
- sec.leave();
- MIDI_callback::Idle();
- sec.enter();
- }
- sec.leave();
- return rv;
- }
- #ifdef USE_LOG
- static HANDLE hLog;
- void log_start()
- {
- hLog=CreateFile("c:\\in_midi.log",GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_ALWAYS,0,0);
- SetFilePointer(hLog,0,0,FILE_END);
- log_write("opening log");
- }
- void log_quit() {log_write("closing log");log_write("");log_write("");CloseHandle(hLog);}
- void log_write(char* t)
- {
- DWORD bw;
- WriteFile(hLog,t,strlen(t),&bw,0);
- char _t[2]={13,10};
- WriteFile(hLog,_t,2,&bw,0);
- FlushFileBuffers(hLog);
- }
- #endif
- //tempo map object
- CTempoMap* tmap_create()
- {
- CTempoMap* m=new CTempoMap;
- if (m)
- {
- m->pos=0;
- m->size=0x100;
- m->data=(TMAP_ENTRY*)malloc(m->size*sizeof(TMAP_ENTRY));
- }
- return m;
- }
- void CTempoMap::AddEntry(int _p,int tm)
- {
- if (!data) {pos=size=0;return;}
- if (pos && _p<=data[pos-1].pos) {data[pos-1].tm=tm;return;}
- if (pos==size)
- {
- size*=2;
- data=(TMAP_ENTRY*)realloc(data,size*sizeof(TMAP_ENTRY));
- if (!data) {pos=0;return;}
- }
- data[pos].pos=_p;
- data[pos].tm=tm;
- pos++;
- }
- int ReadSysex(const BYTE* src,int ml)
- {
- int r=1;
- while(r<ml)
- {
- r++;
- if (src[r]==0xF7) return r+1;
- }
- unsigned int d;
- r=1+DecodeDelta(src+1,&d);
- r+=d;
- return r;
- }
- unsigned int DecodeDelta(const BYTE* src,unsigned int* _d, unsigned int limit)
- {
- unsigned int l=0;
- unsigned int d=0;
- BYTE b;
- do
- {
- if (l >= limit)
- {
- *_d=0;
- return l;
- }
- b=src[l++];
- d=(d<<7)|(b&0x7F);
- } while(b&0x80);
- *_d=d;
- return l;
- }
- int EncodeDelta(BYTE* dst,int d)
- {
- if (d==0)
- {
- dst[0]=0;
- return 1;
- }
- else
- {
- int r=0;
- int n=1;
- unsigned int temp=d;
- while (temp >>= 7)
- {
- n++;
- }
- do {
- n--;
- BYTE b=(BYTE)((d>>(7*n))&0x7F);
- if (n) b|=0x80;
- dst[r++]=b;
- } while(n);
- return r;
- }
- }
- int CTempoMap::BuildTrack(grow_buf & out)
- {
- if (!pos) return 0;
- int start=out.get_size();
- //BYTE* trk=(BYTE*)malloc(8+4+pos*10);
- //if (!trk) return 0;
- out.write_dword(_rv('MTrk'));
- out.write_dword(0);//track size
- DWORD ct=0;
- int n;
- BYTE t_event[6]={0xFF,0x51,0x03,0,0,0};
- for(n=0;n<pos;n++)
- {
- DWORD t=data[n].pos;
- gb_write_delta(out,t-ct);
- ct=t;
- t=data[n].tm;
- t_event[3]=(BYTE)(t>>16);
- t_event[4]=(BYTE)(t>>8);
- t_event[5]=(BYTE)(t);
- out.write(t_event,6);
- }
- out.write_dword(0x002FFF00);
- out.write_dword_ptr(rev32(out.get_size()-(start+8)),start+4);
- return 1;
- }
- //sysex map management
- void CSysexMap::AddEvent(const BYTE* e,DWORD s,DWORD t)
- {
- if (!data || !events) return;
- DWORD np=pos+1;
- if (np>=e_size)
- {
- do {
- e_size<<=1;
- } while(np>=e_size);
- events=(SYSEX_ENTRY*)realloc(events,e_size*sizeof(SYSEX_ENTRY));
- if (!events) return;
- }
- DWORD nd=d_pos+s;
- if (nd>=d_size)
- {
- do {
- d_size<<=1;
- } while(nd>=d_size);
- data=(BYTE*)realloc(data,d_size);
- if (!data) return;
- }
- data[d_pos]=0xF0;
- unsigned int x;
- unsigned int sp=DecodeDelta(e+1,&x);
- if (sp >= s)
- return;
- memcpy(data+d_pos+1,e+1+sp,s-1-sp);
- events[pos].pos=t;
- events[pos].ofs=d_pos;
- events[pos].len=s-sp;
- d_pos=nd-sp;
- pos++;
- }
- CSysexMap* smap_create()
- {
- CSysexMap* s=new CSysexMap;
- if (s)
- {
- s->e_size=0x10;
- s->d_size=0x40;
- s->events=(SYSEX_ENTRY*)malloc(sizeof(SYSEX_ENTRY)*s->e_size);
- s->data=(BYTE*)malloc(s->d_size);
- s->d_pos=s->pos=0;
- }
- return s;
- }
- CSysexMap::~CSysexMap()
- {
- if (data) free(data);
- if (events) free(events);
- }
- BYTE d_GMReset[6]={0xF0,0x7E,0x7F,0x09,0x01,0xF7};
- BYTE d_XGReset[9]={0xf0,0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,0xf7};
- BYTE d_GSReset[11]={0xF0,0x41,0x10,0x42,0x12,0x40,0x00,0x7F,0x00,0x41,0xF7};
- CSysexMap* CSysexMap::Translate(MIDI_file * mf)
- {
- CTempoMap* tmap=mf->tmap;
- if (!events || !data || !tmap) return 0;
- CSysexMap* nm=smap_create();
- if (!nm) return 0;
- nm->d_size=d_size;
- nm->d_pos=d_pos;
- nm->data=(BYTE*)realloc(nm->data,nm->d_size);
- if (!nm->data) {delete nm;return 0;}
- memcpy(nm->data,data,d_pos);
- nm->e_size=e_size;
- nm->pos=pos;
- nm->events=(SYSEX_ENTRY*)realloc(nm->events,sizeof(SYSEX_ENTRY)*nm->e_size);
- if (!nm->events) {delete nm;return 0;}
-
- int pos_ms=0;
- int n=0;
- int cur_temp=0;
- int ntm=tmap->pos,t_pos=0;
- int p_t=0;
- int dtx = rev16(*(WORD*)(mf->data+12))*1000;
- int pos_tx=0;
- while(n<pos)
- {
- pos_tx=events[n].pos;
- int d=pos_tx-p_t;
- p_t=pos_tx;
- while(t_pos<ntm && pos_tx+d>=tmap->data[t_pos].pos)
- {
- DWORD d1=tmap->data[t_pos].pos-pos_tx;
- pos_ms+=MulDiv(cur_temp,d1<<8,dtx);
- cur_temp=tmap->data[t_pos].tm;
- t_pos++;
- pos_tx+=d1;
- d-=d1;
- }
- pos_ms+=MulDiv(cur_temp,d<<8,dtx);
- pos_tx+=d;
- nm->events[n].pos=pos_ms>>8;
- nm->events[n].ofs=events[n].ofs;
- nm->events[n].len=events[n].len;
- n++;
- }
- return nm;
- }
- int CSysexMap::BuildTrack(grow_buf & out)
- {
- if (!pos) return 0;
-
- int start=out.get_size();
- out.write_dword(_rv('MTrk'));
- out.write_dword(0);
-
- int ct=0;
- int n;
- for(n=0;n<pos;n++)
- {
- DWORD t=events[n].pos;
- gb_write_delta(out,t-ct);
- ct=t;
- out.write_byte(0xF0);
- gb_write_delta(out,events[n].len-1);
- out.write(data+events[n].ofs+1,events[n].len-1);
- }
- out.write_dword(0x002FFF00);
- out.write_dword_ptr(rev32(out.get_size()-(start+8)),start+4);
- return 1;
- }
- const char* CSysexMap::GetType()
- {
- int ret=0;
- int n;
- for(n=0;n<pos;n++)
- {
- ret=data[events[n].ofs+1];
- if (ret!=0x7E) break;
- }
- switch(ret)
- {
- case 0x7E:
- return "GM";
- case 0x43:
- return "XG";
- case 0x42:
- return "X5";
- case 0x41:
- return "GS";
- }
- return 0;
- }
- void CSysexMap::CleanUp()
- {
- if (!pos) return;
- int n,m;
- for(n=0;n<pos-1;n++)
- {
- for(m=n+1;m<pos;m++)
- {
- if (events[n].pos>events[m].pos)
- {
- SYSEX_ENTRY t=events[n];
- events[n]=events[m];
- events[m]=t;
- }
- }
- }
- }
- char* BuildFilterString(UINT res_id, char* ext, int* len)
- {
- static char filterStr[256];
- char *f = filterStr;
- ZeroMemory(filterStr,256);
- *len = 0;
- WASABI_API_LNGSTRING_BUF(res_id,filterStr,256);
- f += (*len = lstrlenA(filterStr) + 1);
- lstrcatA(f,"*.");
- f += 2;
- lstrcatA(f,ext);
- *(f + lstrlenA(ext)+1) = 0;
- *len += lstrlenA(ext)+3;
- return filterStr;
- }
- BOOL DoOpenFile(HWND w,char* fn,UINT res_id, char* ext,BOOL save)
- {
- int len = 0;
- OPENFILENAMEA ofn = {sizeof(ofn),0};
- ofn.hwndOwner=w;
- ofn.lpstrFilter=BuildFilterString(res_id,ext,&len);
- ofn.lpstrFile=fn;
- ofn.nMaxFile=MAX_PATH;
- ofn.lpstrDefExt=ext;
- if (save)
- {
- ofn.Flags=OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY;
- return GetSaveFileNameA(&ofn);
- }
- else
- {
- ofn.Flags=OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY;
- return GetOpenFileNameA(&ofn);
- }
- }
- BOOL DoSaveFile(HWND w, char* fn, char* filt, char* ext)
- {
- OPENFILENAMEA ofn;
- ZeroMemory(&ofn,sizeof(ofn));
- ofn.lStructSize=sizeof(ofn);
- ofn.hwndOwner=w;
- ofn.lpstrFilter=filt;
- ofn.lpstrFile=fn;
- ofn.nMaxFile=MAX_PATH;
- ofn.lpstrDefExt=ext;
- ofn.Flags=OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY;
- return GetOpenFileNameA(&ofn);
- }
- typedef void (*SYSEXFUNC)(void*,BYTE*,UINT);
- #define rsysex(X) f(i,X,sizeof(X))
- #define _sysex(X,Y) f(i,X,Y)
- bool need_sysex_start()
- {
- return cfg_hardware_reset>0
- || cfg_sysex_table.num_entries()>0
- ;
- }
- void sysex_startup(SYSEXFUNC f,void* i)
- {
- if (cfg_hardware_reset>0)
- {
- switch(cfg_hardware_reset)
- {
- case 1:rsysex(d_GMReset);break;
- case 2:rsysex(d_GSReset);break;
- case 3:rsysex(d_XGReset);break;
- }
- MIDI_callback::Idle(200);
- }
- if (cfg_sysex_table.num_entries()>0)
- {
- int idx=0;
- BYTE * data;
- int size,time;
- while(cfg_sysex_table.get_entry(idx++,&data,&size,&time))
- {
- _sysex(data,size);
- MIDI_callback::Idle(time);
- }
- }
- }
- MIDI_EVENT* do_table(MIDI_file * mf,UINT prec,UINT * size,UINT* _lstart,DWORD cflags)
- {
- BYTE * data_ptr = 0;
- int data_size = 0;
- if (!DoCleanUp(mf,CLEAN_1TRACK|CLEAN_NOSYSEX|CLEAN_NOTEMPO|cflags,(void**)&data_ptr,&data_size)) return 0;
- if (data_size<=0x0e) {free(data_ptr);return 0;}
- UINT ts;
- BYTE* track;
- UINT ntm;
- track=data_ptr+8+6+8;
- ts=rev32(*(DWORD*)(track-4));
- CTempoMap* tmap=mf->tmap;
- UINT n=0;
- UINT pt=0;
- ntm=tmap->pos;
- CSysexMap* smap;
- if (!cfg_nosysex && mf->smap && mf->smap->pos)
- {
- smap=mf->smap;
- }
- else smap=0;
- n=0;
- DWORD pos=0;
- DWORD pos_ms=0;
- DWORD t_pos=0;
- DWORD cur_temp=0;
- UINT dtx=(UINT)rev16(*(WORD*)(data_ptr+8+4))*1000/prec;
- grow_buf boo;
- int ns=0;
- UINT track_pos=0,smap_pos=0;
- UINT loop_start=-1;
- {
- unsigned int _d;
- n+=DecodeDelta(track+n,&_d);
- track_pos+=_d;
- }
- if (smap)
- {
- smap_pos=smap->events[0].pos;
- }
- else smap_pos=-1;
- while(1)
- {
- DWORD ev=0;
- DWORD d=0;
- {
- if (n >= (data_size-26))
- break;
- if (track_pos<smap_pos)
- {
- d=track_pos-pos;
- ev=(*(DWORD*)(track+n))&0xFFFFFF;
- if ((ev&0xF0)==0xF0)
- {
- track_pos=-1;
- continue;
- }
- if ((ev&0xF0)==0xC0 || (ev&0xF0)==0xD0)
- {
- ev&=0xFFFF;n+=2;
- }
- else
- {
- n+=3;
- }
- if ((ev&0xFF00F0)==0x90)
- {
- ev=(ev&0xFF0F)|0x7F0080;
- }
- unsigned int _d;
- n+=DecodeDelta(track+n,&_d);
- track_pos+=_d;
- if (n >= (data_size-26))
- break;
- }
- else if (smap_pos!=-1)
- {
- d=smap_pos-pos;
- ev=0x80000000|ns;
- ns++;
- if (ns==smap->pos)
- smap_pos=-1;
- else
- smap_pos=smap->events[ns].pos;
- }
- }
- if (!ev) break;
- while(t_pos<ntm && pos+d>=(UINT)tmap->data[t_pos].pos)
- {
- DWORD d1=tmap->data[t_pos].pos-pos;
- if (loop_start==-1 && (UINT)mf->loopstart_t<=pos+d1) loop_start=pos_ms+MulDiv(cur_temp,pos+d1-mf->loopstart_t,dtx);
- pos_ms+=MulDiv(cur_temp,d1,dtx);
- cur_temp=tmap->data[t_pos].tm;
- t_pos++;
- pos+=d1;
- d-=d1;
- }
- if (loop_start==-1 && (UINT)mf->loopstart_t<=pos+d) loop_start=pos_ms+MulDiv(cur_temp,d,dtx);
- pos_ms+=MulDiv(cur_temp,d,dtx);
- pos+=d;
- {
- MIDI_EVENT me={pos_ms,ev};
- boo.write(&me,sizeof(me));
- }
- }
-
- free(data_ptr);
- UINT sz=boo.get_size();
- MIDI_EVENT* ret=(MIDI_EVENT*)boo.finish();
- if (ret)
- {
- *size=sz>>3;//sz/sizeof(MIDI_EVENT);
- if (cfg_loop_type==2 && loop_start==-1) loop_start=0;
- else if (cfg_loop_type==0) loop_start=-1;
- if (_lstart) *_lstart=loop_start;
- }
- return ret;
- }
- void gb_write_delta(grow_buf & gb,DWORD d)
- {
- BYTE tmp[8] = {0};
- gb.write(tmp,EncodeDelta(tmp,d));
- }
- void do_messages(HWND w,bool* b)
- {
- MSG msg;
- while(b && *b)
- {
- BOOL b=GetMessage(&msg,w,0,0);
- if (b==-1 || !b) break;
- DispatchMessage(&msg);
- }
- }
- static wchar_t cb_class[]=TEXT("CallbackWndClass0");
- ATOM do_callback_class(WNDPROC p)
- {
- cb_class[sizeof(cb_class)-2]++;
- WNDCLASS wc=
- {
- 0,p,0,4,MIDI_callback::GetInstance(),0,0,0,0,cb_class
- };
- return RegisterClassW(&wc);
- }
- HWND create_callback_wnd(ATOM cl,void* p)
- {
- HWND w=CreateWindowA((char*)cl,0,0,0,0,0,0,MIDI_callback::GetMainWindow(),0,MIDI_callback::GetInstance(),0);
- if (w) SetWindowLong(w,0,(long)p);
- return w;
- }
- CTempoMap* tmap_merge(CTempoMap* m1,CTempoMap* m2)
- {
- int p1=0,p2=0;
- CTempoMap * ret=0;
- if (m1 && m2 && m1->data && m2->data)
- {
- ret=tmap_create();
- if (ret)
- {
- while(p1<m1->pos && p2<m2->pos)
- {
- if (m1->data[p1].pos<=m2->data[p2].pos)
- {
- ret->AddEntry(m1->data[p1].pos,m1->data[p1].tm);
- p1++;
- }
- else
- {
- ret->AddEntry(m2->data[p2].pos,m2->data[p2].tm);
- p2++;
- }
- }
- while(p1<m1->pos)
- {
- ret->AddEntry(m1->data[p1].pos,m1->data[p1].tm);
- p1++;
- }
- while(p2<m2->pos)
- {
- ret->AddEntry(m2->data[p2].pos,m2->data[p2].tm);
- p2++;
- }
- }
- }
- if (m1) delete m1;
- if (m2) delete m2;
- return ret;
- }
- KAR_ENTRY * kmap_create(MIDI_file* mf,UINT prec,UINT * num,char** text)
- {
- if (!mf->kar_track) return 0;
- grow_buf b_data,b_map;
- KAR_ENTRY te;
- BYTE *track=(BYTE*)mf->data+mf->kar_track+8;
- BYTE *track_end = track+rev32(*(DWORD*)(mf->data+mf->kar_track+4));
- int time=0;
- int ptr=0;
- BYTE lc=0;
- while(track<track_end)
- {
- unsigned int d;
- track+=DecodeDelta(track,&d);
- time+=d;
- if (*track==0xFF) //meta
- {
- BYTE type=track[1];
- track+=2;
- track+=DecodeDelta(track,&d);
- char * ptr=(char*)track;
- track+=d;
- if ((type==0x5 || type==0x1) && d && *ptr!='@') //lyrics
- {
- te.time=time;
- te.foo=1;
- unsigned int n;
- te.start=b_data.get_size();
- for(n=0;n<d;n++)
- {
- switch(ptr[n])
- {
- // case '@':
- case '\\':
- case '/':
- case 0x0D:
- b_data.write("\x0d\x0a",2);
- break;
- case 0x0A:
- break;
- default:
- te.foo=0;
- b_data.write_byte(ptr[n]);
- break;
- }
- }
- te.end=b_data.get_size();
- if (te.start<te.end) b_map.write(&te,sizeof(te));
- }
- }
- else if (*track==0xF0)
- {
- track++;
- track+=DecodeDelta(track,&d);
- track+=d;
- }
- else if ((*track&0xF0)==0xF0)
- {
- track++;//hack
- }
- else
- {
- if (*track&0x80) lc=*(track++)&0xF0;
- if (lc==0 || lc==0xC0 || lc==0xD0) track++;
- else track+=2;
- }
- }
- int map_siz = b_map.get_size();
- KAR_ENTRY * map=(KAR_ENTRY*)b_map.finish();
- map_siz/=sizeof(KAR_ENTRY);
- if (num) *num=map_siz;
-
- if (text)
- {
- b_data.write_byte(0);
- *text=(char*)b_data.finish();
- }
- else b_data.reset();
- if (map)
- {
- int n;
- time=0;
-
- CTempoMap* tmap=mf->tmap;
- int pos_ms=0;
- int t_pos=0;
- int cur_temp=0;
- int dtx=(UINT)rev16(*(WORD*)(mf->data+8+4))*1000/prec;
- for(n=0;n<map_siz;n++)
- {
- int d=0;
- d=map[n].time-time;
-
- while(t_pos<tmap->pos && time+d>=tmap->data[t_pos].pos)
- {
- DWORD d1=tmap->data[t_pos].pos-time;
- pos_ms+=MulDiv(cur_temp,d1,dtx);
- cur_temp=tmap->data[t_pos].tm;
- t_pos++;
- time+=d1;
- d-=d1;
- }
- pos_ms+=MulDiv(cur_temp,d,dtx);
- time+=d;
- map[n].time=pos_ms;
- }
- }
- return map;
- }
- int sysex_table::num_entries() const
- {
- int num=0;
- entry * ptr=entries;
- while(ptr) {ptr=ptr->next;num++;}
- return num;
- }
- int sysex_table::get_entry(int idx,BYTE ** p_data,int * p_size,int * p_time) const
- {
- entry * ptr=entries;
- while(ptr && idx>0) {ptr=ptr->next;idx--;}
- if (!ptr) return 0;
- if (p_data) *p_data = ptr->data;
- if (p_size) *p_size = ptr->size;
- if (p_time) *p_time = ptr->time;
- return 1;
- }
- void sysex_table::insert_entry(int idx,BYTE * data,int size,int time)
- {
- entry ** ptr = &entries;
- while(idx>0 && *ptr)
- {
- ptr = &(*ptr)->next;
- idx--;
- }
- entry * insert = new entry;
- insert->data = (BYTE*)malloc(size);
- memcpy(insert->data,data,size);
- insert->size = size;
- insert->time = time;
- insert->next = *ptr;
- *ptr = insert;
- }
- int sysex_table::remove_entry(int idx)
- {
- entry ** ptr = &entries;
- while(idx>0 && *ptr)
- {
- ptr = &(*ptr)->next;
- idx--;
- }
- if (!*ptr) return 0;
- entry * remove = *ptr;
- *ptr=remove->next;
- free(remove->data);
- delete remove;
- return 1;
- }
- int sysex_table::file_write(const char* file) const
- {
- HANDLE f=CreateFileA(file,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0);
- if (f==INVALID_HANDLE_VALUE) return 0;
-
- int size;
- void * ptr = memblock_write(&size);
- DWORD bw = 0;
- WriteFile(f,ptr,size,&bw,0);
- free(ptr);
- CloseHandle(f);
- return 1;
- }
- void * sysex_table::memblock_write(int * size) const
- {
- grow_buf wb;
- entry * ptr;
- //MAGIC:DWORD , NUM: DWORD,DATA_SIZE:DWORD, offsets, sleep,data
- DWORD temp;
- temp=MHP_MAGIC;
- wb.write(&temp,4);
- temp=num_entries();
- wb.write(&temp,4);
- temp=0;
- for(ptr=entries;ptr;ptr=ptr->next) temp+=ptr->size;
- wb.write(&temp,4);
- temp=0;
- for(ptr=entries;ptr;ptr=ptr->next)
- {
- wb.write(&temp,4);
- temp+=ptr->size;
- }
- for(ptr=entries;ptr;ptr=ptr->next)
- {
- temp = ptr->time;
- wb.write(&temp,4);
- }
- for(ptr=entries;ptr;ptr=ptr->next)
- {
- wb.write(ptr->data,ptr->size);
- }
- if (size) *size = wb.get_size();
- return wb.finish();
- }
- int sysex_table::memblock_read(const void * block,int size)
- {
- entry * ptr;
- const BYTE * src = (const BYTE*)block;
- DWORD temp,total_size,total_num;
-
- if (*(DWORD*)src!=MHP_MAGIC) return 0;
- src+=4;
- temp=total_num=*(DWORD*)src;
- src+=4;
- if (total_num>0xFFFF) return 0;
- reset();
- while(temp>0)
- {
- ptr=new entry;
- ptr->next=entries;
- entries = ptr;
- temp--;
- }
- total_size=*(DWORD*)src;
- UINT n;
- for(n=0,ptr=entries;ptr;ptr=ptr->next,n++)
- {
- //offset : 12 + 4 * n;
- //time : 12 + 4 * total_num + 4 * n;
- //data : 12 + 8 * total_num + offset
- DWORD offset,time,offset2;
- src = (const BYTE*)block + 12 + 4*n;
- offset=*(DWORD*)src;
- if (n!=total_num-1) offset2=*(DWORD*)(src+4);
- else offset2=total_size;
- ptr->size = offset2-offset;
- src = (const BYTE*)block + 12 + 4*total_num + 4*n;
- time = *(DWORD*)src;
- ptr->data = (BYTE*)malloc(offset2);
- src = (const BYTE*)block + 12 + 8*total_num + offset;
- memcpy(ptr->data,src,ptr->size);
- ptr->time = time;
- }
-
- return 1;
- }
- int sysex_table::file_read(const char* file)
- {
-
- HANDLE f=CreateFileA(file,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
- if (f==INVALID_HANDLE_VALUE) return 0;
- int size = GetFileSize(f,0);
- void * temp = malloc(size);
- DWORD br = 0;
- ReadFile(f,temp,size,&br,0);
- CloseHandle(f);
- int rv = memblock_read(temp,size);
- free(temp);
- return rv;
- }
- int sysex_table::print_preview(int idx,char * out) const
- {
- BYTE* data;
- int size,time;
- if (!get_entry(idx,&data,&size,&time)) return 0;
- int size2=size;
- if (size2>10) size2=10;
- wsprintfA(out,WASABI_API_LNGSTRING(STRING_MS_FMT),time);
- while(out && *out) out++;
- int n;
- for(n=0;n<size2;n++)
- {
- wsprintfA(out," %02X",data[n]);
- out+=3;
- }
- if (size!=size2)
- {
- strcpy(out,"...");
- }
- return 1;
- }
- void sysex_table::print_edit(int idx,HWND wnd) const
- {
- BYTE* data;
- int size,time;
- if (!get_entry(idx,&data,&size,&time)) {SetWindowTextA(wnd,"");return;}
- if (size<=2) {SetWindowTextA(wnd,"");return;}
- char *temp = (char*)malloc(3*size);
- char *ptr = temp;
- int n;
- for(n=1;n<size-1;n++)
- {
- wsprintfA(ptr,"%02X ",data[n]);
- ptr+=3;
- }
- ptr[-1]=0;
- SetWindowTextA(wnd,temp);
- free(temp);
- }
- void sysex_table::copy(const sysex_table & src)
- {
- reset();
- int idx=0;
- BYTE * data;
- int size,time;
- while(src.get_entry(idx++,&data,&size,&time))//ASS SLOW
- insert_entry(idx,data,size,time);
- }
- //special sysex table cfg_var hack
- class cfg_var_sysex : private cfg_var
- {
- private:
- sysex_table * tab;
- virtual void read(HKEY hk)
- {
- int size=reg_get_struct_size(hk);
- if (size>0)
- {
- void * temp = malloc(size);
- if (temp)
- {
- reg_read_struct(hk,temp,size);
- tab->memblock_read(temp,size);
- free(temp);
- }
- }
- }
- virtual void write(HKEY hk)
- {
- void * data;
- int size;
- data = tab->memblock_write(&size);
- if (data) reg_write_struct(hk,data,size);
-
- }
- virtual void reset() {tab->reset();}
- public:
- cfg_var_sysex(const char * name,sysex_table * p_tab) : cfg_var(name) {tab=p_tab;}
- };
- static cfg_var_sysex thevar("sysex_table",&cfg_sysex_table);
|