From bd11eaf356ecd63caec1742d7b70e47e8de92e08 Mon Sep 17 00:00:00 2001 From: CleverMouse Date: Fri, 4 Feb 2011 16:38:56 +0000 Subject: [PATCH] media/ac97snd: playlist support from Asper git-svn-id: svn://kolibrios.org@1842 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/media/ac97snd/ac97snd/ac97snd.vcproj | 2 + programs/media/ac97snd/ac97snd/ac97wav.c | 793 +++++++++++++++--- programs/media/ac97snd/ac97snd/ac97wav.h | 1 + programs/media/ac97snd/kolibri.h | 8 + 4 files changed, 699 insertions(+), 105 deletions(-) diff --git a/programs/media/ac97snd/ac97snd/ac97snd.vcproj b/programs/media/ac97snd/ac97snd/ac97snd.vcproj index c3f6d72d15..6d00e578a8 100644 --- a/programs/media/ac97snd/ac97snd/ac97snd.vcproj +++ b/programs/media/ac97snd/ac97snd/ac97snd.vcproj @@ -125,6 +125,8 @@ /> 0) + currFirstShowed--; + ShowPLContent(pl_buff); + break; + } + currSelected--; + ShowPLContent(pl_buff); + break; + case 0x50: //Down + if (currSelected+currFirstShowed > pl_items_number-2) break; + if (currSelected==PL_MAX_SHOWN_ITEMS-1) + { + //if (currFirstShowed -10000) + { l_vol-=100; + r_vol-=100; + SetVolume(hBuff,l_vol,r_vol); + }; + break; + case 0x53: + if(pan > -10000) + { pan -=100; + SetPan(hBuff,pan); + }; + break; + case 0x51: + if(pan < 10000) + { pan +=100; + SetPan(hBuff,pan); + }; + break; + } + }; + }; + break; + + case EV_BUTTON: + button=get_button_id(); + if (button==1) + { + PLStatus=0x00; + exit(); + } + for (i=0;i=192) + { + if (ch>=240) ch-=16; + else ch-=64; + } + else + { + if (ch==168) ch = 240; + if (ch==184) ch = 241; + if (ch==185) ch = 252; + if ((ch==147) || (ch==148) || (ch==171) || (ch==187)) ch = 34; + if ((ch==150) || (ch==151)) ch = 45; + } + st[i]=ch; + } +} + +int GetFileNameFromPL(const char *plbuff, int index, char *name) +{ + int count=0,i=0,j=0; + char ch; + + do{ + ch=plbuff[i]; + if (ch!='#' && i && plbuff[i-1]=='\n') + count++; + if (count-1==index) + { + if (j>MAX_TEXT_WIDTH || ch=='\n') + { + name[j-1]='\0'; + break; + } + if (ch=='\\') ch='/'; + name[j++]=ch; + } + else if (count-1>index) break; + i++; + }while (ch); + if (!ch) return 0; + return j; +} + +int CountFileNamesInPL(const char *plbuff) +{ + int count=0,i=0; + char ch; + + do{ + ch=plbuff[i]; + if (ch!='#' && i && plbuff[i-1]=='\n') + count++; + i++; + }while (ch); + if (count) count--; + return count; +} + +int ShowPLContent(char *filebuffer) +{ + char st[MAX_TEXT_WIDTH+10]="", tmp[MAX_TEXT_WIDTH+1]=""; + unsigned int len=8,i; + DWORD text_color; + + draw_bar(7,24,285,PLI_BUTTON_HEIGHT*(PL_MAX_SHOWN_ITEMS+2), main_ic); + draw_bar(7,24+currSelected*(PLI_BUTTON_HEIGHT+1),285,PLI_BUTTON_HEIGHT, selected_ic); + for (i=0; i MAX_TEXT_WIDTH) + len = MAX_TEXT_WIDTH; + write_text(11,i*(PLI_BUTTON_HEIGHT+1)+27,text_color, st, len); + } + return 1; +} +//Asper_____________________Play List code end_____________________________ + +void update_dinamic_content() //Asper + { int len; /* uFMOD integration */ + draw_bar(7,41,286,11,main_wc); + + draw_bar(7,55,286,11,main_wc); + len = strlen(filename); /* uFMOD integration */ + if(len > 47) len = 47; /* uFMOD integration */ + write_text(11,57,0x00FF20|FONT0, filename, len); /* uFMOD integration */ +} + +void draw_window() +{ BeginDraw(); - DrawWindow(100,100,299,72,0x404040,3,0,0,0); + DrawWindow(100,100,299,main_wh,main_wc,4,0,0,0); //Asper+ - make_button(7,24,45,13, 0x10|BT_NORMAL,0x808080); - make_button(56,24,45,13, 0x11|BT_NORMAL,0x808080); - make_button(104,24,45,13, 0x12|BT_NORMAL,0x808080); - make_button(152,24,45,13, 0x13|BT_NORMAL,0x808080); - make_button(200,24,45,13, 0x14|BT_NORMAL,0x808080); - make_button(248,24,45,13, 0x15|BT_NORMAL,0x808080); + make_button(7,24,45,13, 0x10|BT_NORMAL,main_bc); + make_button(56,24,45,13, 0x11|BT_NORMAL,main_bc); + make_button(104,24,45,13, 0x12|BT_NORMAL,main_bc); + make_button(152,24,45,13, 0x13|BT_NORMAL,main_bc); + make_button(200,24,45,13, 0x14|BT_NORMAL,main_bc); + make_button(248,24,45,13, 0x15|BT_NORMAL,main_bc); - make_button(7,41,286,11, 0x30|BT_HIDE|BT_NOFRAME,0x404040); - draw_bar(7,41,286,11,0x404040); + make_button(268,70,25,13, 0x16|BT_NORMAL,main_bc); //Asper+ PL button - draw_bar(7,55,286,11,0x404040); - len = strlen(filename); /* uFMOD integration */ - if(len > 47) len = 47; /* uFMOD integration */ - write_text(11,57,0x00FF20|FONT0, filename, len); /* uFMOD integration */ + make_button(7,41,286,11, 0x30|BT_HIDE|BT_NOFRAME,main_wc); + update_dinamic_content(); write_text(8,8,FONT0, header, sizeof(header)-1); /* uFMOD integration */ - write_text(12,28,0x404040|FONT0,buttons_text,sizeof(buttons_wav)-1); /* uFMOD integration */ + write_text(12,28,main_wc|FONT0,buttons_text,sizeof(buttons_wav)-1); /* uFMOD integration */ write_text(11,27,0xA0FFA0|FONT0,buttons_text,sizeof(buttons_wav)-1); /* uFMOD integration */ + write_text(276,74,main_wc|FONT0,button_PL,sizeof(button_PL)-1); //Asper+ PL button text + write_text(275,73,0xA0FFA0|FONT0,button_PL,sizeof(button_PL)-1); //Asper+ EndDraw(); }; @@ -111,10 +441,10 @@ void draw_progress_bar() x = (DWORD)(287.0f * (float)(rd.filepos-rd.strremain)/(float)fileinfo.size); /* uFMOD integration */ if(x==0) return; draw_bar(7,41,x,11,0xA0A0A0); - draw_bar(x+7,41,287-x,11,0x404040); + draw_bar(x+7,41,287-x,11,main_wc); }; -void debug_out_str(char* str) +void debug_out_str(const char* str) { while (*str != 0) { @@ -123,74 +453,117 @@ void debug_out_str(char* str) } } -int main(int argc, char *argv[]) //int argc, char *argv[]) +int LoadPL(char *fname) +{ + DWORD fmt; + DWORD r_bytes; + int retval; + int i; +// char st[100]=""; + + char *pch; + + r_bytes=0; + pch=strrchr(fname, '/'); + if (pch) + i=pch-fname+1; + else + i=strlen(fname); + + _strncpy (pl_path, fname, i); + pl_path[i]='\0'; + + if (!pl_buff) + pl_buff = UserAlloc(0x40000); + retval=read_file (fname,pl_buff,0,0x40000,&r_bytes); + + if ( retval && (r_bytes==0)) + return 0; + + Win2Dos(pl_buff, r_bytes); + pl_items_number=CountFileNamesInPL(pl_buff); +/* + debug_out_str("\n\rPlay List files number = "); + itoa(pl_items_number, st, 10); + debug_out_str(st); +*/ + fmt = test_m3u(pl_buff); + + if(!fmt) + { + debug_out_str("\n\rInvalid M3U file"); + return 0; + } + debug_out_str("\n\rValid M3U file"); + currSelected=currFirstShowed=0; + currActive=-1; + return 1; +} + +int LoadFile(char *fname) { DWORD fmt; DWORD r_bytes; int retval; int err; - int ver; unsigned char *ttl, *cur; /* uFMOD integration */ - - fname = argv[1]; + debug_out_str("\n\rPlay file "); debug_out_str(fname); debug_out_str("\n\r"); - - InitHeap(1024*1024); + if(get_fileinfo(fname, &fileinfo)==FILE_NOT_FOUND) - { debug_out_str("\n\rfile not found\n\r"); + { debug_out_str("\n\rfile not found\n\r"); return 0; - }; - - if(err = InitSound(&ver)) - { - debug_out_str("Sound service not installed\n\r"); - return 0; } - - if( (SOUND_VERSION>(ver&0xFFFF)) || - (SOUND_VERSION<(ver >> 16))) - { - debug_out_str("Sound service version mismatch\n\r"); - return 0; - } - - testbuff = UserAlloc(4096); - - get_fileinfo(fname, &fileinfo); + r_bytes=0; + strcpy(filename, strrchr(fname,'/')+1); + if( !(fileext = strrchr(filename,'.'))) + return 0; + + if(!_stricmp(fileext,".m3u")) + { + LoadPL(fname); + status=ST_TRACK; + return 1; + } + + if (!testbuff) + testbuff = UserAlloc(4096); + retval=read_file (fname,testbuff,0,2048,&r_bytes); - if ( retval && (r_bytes==0)) - return 0; - - inpbuf = UserAlloc(0x10000); - touch(inpbuf, 0x10000); - + if ( retval && (r_bytes==0)) + return 0; + + if (!inpbuf) + { + inpbuf = UserAlloc(0x10000); + touch(inpbuf, 0x10000); + } create_reader(&rd, inpbuf, 0x10000); init_reader(&rd,fname); - - filename = strrchr(fname,'/')+1; - if( !(fileext = strrchr(filename,'.'))) - return 0; - + if(!_stricmp(fileext,".mp3")) - { + { fmt = test_mp3(testbuff); if(!fmt) { - debug_out_str("\n\rInvalid MP3 file"); + debug_out_str("\n\rInvalid MP3 file"); return 0; }; - snd_play = &play_mp3; - outremain = 0x40000; - outbuf = UserAlloc(outremain); - touch(outbuf, outremain); - make_decode_tables(32767); - init_layer2(); - init_layer3(32); + snd_play = &play_mp3; + outremain = 0x40000; + if (!outbuf) + { + outbuf = UserAlloc(outremain); + touch(outbuf, outremain); + } + make_decode_tables(32767); + init_layer2(); + init_layer3(32); fr.single = -1; - goto play; + goto play; }; if(!_stricmp(fileext,".xm")) @@ -220,55 +593,101 @@ int main(int argc, char *argv[]) //int argc, char *argv[]) if(!_stricmp(fileext, ".wav")) { - fmt = test_wav((WAVEHEADER*)testbuff); + fmt = test_wav((WAVEHEADER*)testbuff); if(fmt) { snd_play = &play_wave; set_reader(&rd, 44); outbuf = UserAlloc(32*1024); touch(outbuf, 32768); - goto play; + goto play; } debug_out_str("\n\rInvalid WAV file"); return 0; }; - debug_out_str("\n\rUsupported file"); + debug_out_str("\n\rUnsupported file"); return 0; play: status = ST_PLAY; + SetFormat(hBuff, fmt); + SetVolume(hBuff,l_vol,r_vol); + GetVolume(hBuff,&l_vol,&r_vol); + + return 1; +} + +int main(int argc, char *argv[]) +{ + int err, ver; + int i; + char ipc_msg[2]="\0\0"; + + strcpy (full_filename, argv[1]); + pl_items_number=0; + + InitHeap(1024*1024); - if (err = CreateBuffer(fmt,0, &hBuff)) + if(err = InitSound(&ver)) + { + debug_out_str("Sound service not installed\n\r"); + return 0; + } + + if( (SOUND_VERSION>(ver&0xFFFF)) || + (SOUND_VERSION<(ver >> 16))) + { + debug_out_str("Sound service version mismatch\n\r"); + return 0; + } + + if (err = CreateBuffer(PCM_2_16_48, 0, &hBuff)) { debug_out_str("create buffer return error\n\r"); - ; return 0; + return 0; } - - SetVolume(hBuff,l_vol,r_vol); - GetVolume(hBuff,&l_vol,&r_vol); - - create_thread(thread_proc, 0, 4096); + + if (!LoadFile(full_filename)) + return 0; + tid=create_thread(thread_proc, 0, 4096); while(1) { delay(10); switch(status) - { case ST_PLAY: - snd_play(); - continue; + { case ST_TRACK: + StopBuffer(hBuff); + if (LoadTrack(++currActive)) + { + if (LoadFile(full_filename)) + status = ST_PLAY; + } + else status = ST_STOP; - case ST_STOP: - StopBuffer(hBuff); - status = ST_DONE; - continue; + //Update ac97snd and PL windows + i=currActive-currFirstShowed; + if (i>PL_MAX_SHOWN_ITEMS-1) + currFirstShowed = currActive - PL_MAX_SHOWN_ITEMS/2; + ipc_send_msg(tid, ipc_msg); + ipc_send_msg(pl_tid, ipc_msg); + continue; + + case ST_PLAY: + snd_play(); + continue; - case ST_EXIT: - uFMOD_StopSong(); /* uFMOD integration */ - StopBuffer(hBuff); - DestroyBuffer(hBuff); - return 0; - }; + case ST_STOP: + StopBuffer(hBuff); + status = ST_DONE; + continue; + + case ST_EXIT: + uFMOD_StopSong(); /* uFMOD integration */ + StopBuffer(hBuff); + DestroyBuffer(hBuff); + return 0; + }; }; return 0; }; @@ -280,6 +699,12 @@ void touch(char *buf, int size) a = buf[i]; }; +DWORD test_m3u(char *buf) //Asper+ +{ + char *sign="#EXTM3U"; + return _strncmp(buf, sign, 7); +} + DWORD test_mp3(char *buf) { unsigned long hdr; WAVEHEADER whdr; @@ -370,8 +795,8 @@ void play_mp3() WaveOut(hBuff,outPtr,4096); if(status!=ST_PLAY) - { if(status != ST_EXIT) - status = ST_STOP; + { if ((status != ST_EXIT) && (status != ST_STOP)) + status = ST_TRACK; return; }; totalout-=4096; @@ -385,8 +810,8 @@ void play_mp3() outPtr = outbuf+totalout; } - if(status != ST_EXIT) - status = ST_STOP; + if ((status != ST_EXIT) && (status != ST_STOP)) + status = ST_TRACK; }; void play_wave() @@ -407,8 +832,8 @@ void play_wave() break; }; - if(status != ST_EXIT) - status = ST_STOP; + if ((status != ST_EXIT) && (status != ST_STOP)) + status = ST_TRACK; }; void play_xm(){ /* uFMOD integration */ @@ -416,7 +841,7 @@ void play_xm(){ /* uFMOD integration */ uFMOD_WaveOut(hBuff); /* uFMOD integration */ delay(8); /* uFMOD integration */ } /* uFMOD integration */ - if(status != ST_EXIT) status = ST_STOP; /* uFMOD integration */ + if ((status != ST_EXIT) && (status != ST_STOP)) status = ST_TRACK; /* uFMOD integration */ } /* uFMOD integration */ void snd_stop() @@ -429,6 +854,10 @@ void _stdcall thread_proc(void *param) int pos; int key; DWORD offset; + char ipc_buff[16]; + + set_event_mask(0x47); //Asper + IPC event + ipc_init(ipc_buff, 16); _asm { @@ -441,18 +870,23 @@ void _stdcall thread_proc(void *param) draw_window(); while(1) - { if(status==ST_PLAY) + { + if(status==ST_PLAY) { draw_progress_bar(); - evnt = wait_for_event(80); + evnt = wait_for_event(80); } else - evnt = wait_for_event_infinite(); + evnt = wait_for_event_infinite(); + +#ifdef DOCKABLE_WINDOW + GetThreadInfo(thread_info, -1); +#endif switch(evnt) { case EV_REDRAW: - draw_window(); - break; + draw_window(); + break; case EV_KEY: if(!get_key(&key)) @@ -468,7 +902,7 @@ void _stdcall thread_proc(void *param) case 0x01: //Esc status = ST_EXIT; exit(); - break; + break; case 0x47: //Home if(l_vol < 0) @@ -515,8 +949,13 @@ void _stdcall thread_proc(void *param) case 0x11: status = ST_STOP; break; -// case 0x12: -// case 0x13: + case 0x12: + currActive-=2; + status = ST_TRACK; + break; + case 0x13: + status = ST_TRACK; + break; case 0x14: if(l_vol > -10000) { @@ -534,6 +973,21 @@ void _stdcall thread_proc(void *param) }; break; + case 0x16: //Asper+ PL button action + switch (PLStatus) + { case 0x00: //PL not started. + pl_tid=create_thread(pl_thread_proc, 0, 4096); + PLStatus=0x12; + break; + case 0x01: //PL started, but hidden. + PLStatus=0x12; + break; + case 0x02: //PL started and showed. + PLStatus=0x11; + break; + } + break; + case 0x30: if(status==ST_DONE) break; @@ -543,6 +997,13 @@ void _stdcall thread_proc(void *param) draw_progress_bar(); break; }; + break; + + case EV_IPC: + *ipc_buff='\0'; + update_dinamic_content(); + break; + }; }; }; @@ -598,6 +1059,128 @@ void EndDraw() }; }; +//Asper+_______start KolibriOS sys functions___________________ +void ResizeReplaceWindow (DWORD x, DWORD y, DWORD w, DWORD h) //Asper+ +{ + _asm + { + mov eax, 67 + mov ebx, [x] + mov ecx, [y] + mov edx, [w] + mov esi, [h] + int 0x40 + }; +} + +#ifdef DOCKABLE_WINDOW +void GetThreadInfo (char *info, int slot) //Asper+ +{ + _asm + { + mov eax, 9 + mov ebx, [info] + mov ecx, [slot] + int 0x40 + } +} +#endif + +void set_event_mask(int mask) +{ + _asm + { + mov eax, 40 + mov ebx, [mask] + int 0x40 + } +} + +void ipc_init(char *buf, int bufsize) +{ + _asm + { + mov eax, 60 + mov ebx, 1 + mov ecx, [buf] + mov edx, [bufsize] + int 0x40 + } +} + +int ipc_send_msg(int PID, char *msg) +{ + int len = strlen(msg); + int retval; + _asm + { + mov eax, 60 + mov ebx, 2 + mov ecx, [PID] + mov edx, [msg] + mov esi, [len] + int 0x40 + mov [retval], eax + } +} +//Asper+_______end KolibriOS sys functions___________________ + +//Asper+_______start strings routines___________________ +int _strncmp(char *src, char *dst, DWORD n) +{ + _asm{ + mov esi, src + mov edi, dst + mov ecx, n + } + l1: + _asm{ + cmpsb + jne err + loop l1 + } + return 1; + err: + return 0; +} + +int _strncpy (char *dst, char *src, int n) +{ + int i; + for (i=0; i