Advertisement
Guest User

Br3tt

a guest
Oct 21st, 2010
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ===========================================================================================================
  3. Lyriks 1.1 (build 20101021.1315) - a WSH lyrics module by Br3tt
  4. - This WSH script get lyrics from TAG first then from local file in Music folder then in foobar2000\lyrics\ and finally it displays them (scrolling+sync)
  5. - It handles TXT and LRC format (sync handled), but not the LRC Enhanced format (translated to simple LRC format)
  6. - exotics timestamps are now handled (like [9:99], [99:99.999], [9:99.999], [99:99:999] ...)
  7. - filenames supported are : <%artist%> -<%title%>.lrc (or .txt)  AND <%artist%> - <%title%>.lrc (or .txt)
  8. - Comments, Blank lines (no timestamp) and Info lines (ar:, ti, ...) are ignored.
  9. - Manual Scrolling possible with the mousewheel (double click on the panel to re-center on the active line)
  10. - Requirements :
  11.   1) foobar2000
  12.   2) WSH Panel Mod component
  13.   3) this script!
  14.   4) Optional: a lyrics grabber (i.e: Lyric Show Panel by hidding the panel, foo_lyricsDB, ...)
  15. - Some settings are available by using the panel Properties (right click on WSH panel -> Properties)
  16. - This script don't make any changes to your files and write nothing on your system, except the creation of the folder foobar2000/lyrics if not found
  17. ===========================================================================================================
  18. */
  19.  
  20. // Text formatting function
  21. // {{
  22. function StringFormat() {
  23.     var h_align = 0, v_align = 0, trimming = 0, flags = 0;
  24.     switch (arguments.length)
  25.     {
  26.         // fall-thru
  27.         case 4:
  28.             flags = arguments[3];
  29.         case 3:
  30.             trimming = arguments[2];
  31.         case 2:
  32.             v_align = arguments[1];
  33.         case 1:
  34.             h_align = arguments[0];
  35.             break;
  36.         default:
  37.             return 0;
  38.     }
  39.     return ((h_align << 28) | (v_align << 24) | (trimming << 20) | flags);
  40. }
  41. StringAlignment = {
  42.     Near: 0,
  43.     Centre: 1,
  44.     Far: 2
  45. };
  46. var lt_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Near);
  47. var ct_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Near);
  48. var rt_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Near);
  49. var lc_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Centre);
  50. var cc_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Centre);
  51. var rc_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Centre);
  52. var lb_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Far);
  53. var cb_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Far);
  54. var rb_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Far);
  55. // }}
  56.  
  57. // Use with GdiDrawText()
  58. // {{
  59. var DT_LEFT = 0x00000000;
  60. var DT_RIGHT = 0x00000002;
  61. var DT_TOP = 0x00000000;
  62. var DT_CENTER = 0x00000001;
  63. var DT_VCENTER = 0x00000004;
  64. var DT_WORDBREAK = 0x00000010;
  65. var DT_CALCRECT = 0x00000400;
  66. var DT_NOPREFIX = 0x00000800;
  67. var DT_END_ELLIPSIS = 0x00008000;
  68. // }}
  69.  
  70. //{{
  71. // IO Mode
  72. var ForReading = 1;
  73. var ForWriting = 2;
  74. var ForAppending = 8;
  75. //}}
  76.  
  77. //{{
  78. // Paths
  79. var lyrics_dir1 =  fb.FoobarPath + "lyrics\\";
  80. var lyrics_dir2 = fb.Titleformat("$replace($replace(%path%,%filename_ext%,),\,\\)");
  81. //}}
  82.  
  83. //{{
  84. // new objects
  85. sentence = function () {
  86.     this.type = null;
  87.     this.timer = 0;
  88.     this.text = "";
  89.     this.total_lines = 0;
  90.     this.ante_lines = 0;
  91. }
  92. //}}
  93.  
  94. function RGBA(r, g, b, a) {
  95.     return ((a << 24) | (r << 16) | (g << 8) | (b));
  96. }
  97.  
  98. // ================================================/ TF
  99. var len = fb.Titleformat("%length%");
  100. var elap = fb.TitleFormat("%playback_time%");
  101. var remain = fb.TitleFormat("%playback_time_remaining%");
  102. var len_seconds = fb.Titleformat("%length_seconds%");
  103. var elap_seconds = fb.TitleFormat("%playback_time_seconds%");
  104. var remain_seconds = fb.Titleformat("%playback_time_remaining_seconds%");
  105. var artist = fb.Titleformat("$replace(%artist%,'/','_')");
  106. var title = fb.Titleformat("%title%");
  107. var lyrics = fb.TitleFormat("[$if2(%LYRICS%,$if2(%LYRIC%,$if2(%UNSYNCED LYRICS%,%UNSYNCED LYRIC%)))]");
  108.  
  109. // ================================================/ Declarations
  110. var g_font = gdi.Font("segoe ui", 12, 0);
  111. var g_playtimer;
  112. var g_metadb;
  113. var ww = 0, wh = 0;
  114.  
  115. var PLAYTIMER_VALUE = window.GetProperty("Timer value in ms [10;100]", 10);
  116. var LINE_HEIGHT = window.GetProperty("Line height [20;30]", 24);
  117. var TEXT_SHADOW = window.GetProperty("Text shadow (true/false)", true);
  118. var PLAIN_COLOR_BG = window.GetProperty("Plain colour background (true/false)", false);
  119. var DITHER = window.GetProperty("Top & Botom dither (true/false)", true);
  120. var H_PADDING = window.GetProperty("Horizontal padding [0;20]", 20);
  121. var TXT_ALIGN = window.GetProperty("Text alignment (left/center/right)", "center");
  122. var LIGHT_BG = window.GetProperty("Light background", true);
  123. var DEBUG = false;
  124. var DEFAULT_OFFSET = 29;
  125.  
  126. var g_fso = new ActiveXObject("Scripting.FileSystemObject");
  127. var g_file = null;
  128. var g_tab = Array();
  129. var g_scroll=0;
  130. var g_lyrics_path;
  131. var g_lyrics_filename;
  132. var g_lyrics_status;
  133. var focus=0;
  134. var focus_next=0;
  135. var g_plainbg_colour;
  136. var g_ovbg_normalcolour;
  137. var g_ovbg_lineseparatorcolour;
  138. var g_ovbg_highlightcolour;
  139. var g_txt_normalcolour;
  140. var g_txt_highlightcolour;
  141. var g_txt_shadowcolour;
  142. var centiemes = 0;
  143. var g_is_scrolling = false;
  144. var g_multi_balise = false;
  145. var g_balise_total;
  146. var g_balise_char_offset = 10;
  147. var g_tab_length;
  148. var g_txt_align;
  149.  
  150. var midpoint;
  151. var pos;
  152.  
  153. // START
  154. function on_size() {
  155.     var k;
  156.     ww = window.Width;
  157.     wh = window.Height;
  158.    
  159.     g_metadb = fb.IsPlaying ? fb.GetNowPlaying() : false;
  160.      
  161.     // exit test on useless calls made (wsh tweak)
  162.     if(!ww && !wh) return true;
  163.    
  164.     midpoint = wh / 2 - LINE_HEIGHT / 2;
  165.  
  166.     // colour definitions
  167.     g_plainbg_colour = RGBA(140, 200, 250, 255);
  168.     g_ovbg_normalcolour = RGBA(000, 000, 000, 130);
  169.     g_ovbg_lineseparatorcolour = RGBA(000, 000, 000, 100);
  170.     g_ovbg_highlightcolour = RGBA(020, 100, 240, 130);
  171.     g_txt_normalcolour = RGBA(200, 200, 210, 255);
  172.     g_txt_highlightcolour = RGBA(255, 255, 255, 255);
  173.     g_txt_shadowcolour = RGBA(000, 000, 000, 150);
  174.    
  175.     g_playtimer && window.KillTimer(g_playtimer);
  176.  
  177.     if(fb.IsPlaying||fb.IsPaused) {
  178.         g_scroll=0;
  179.         g_is_scrolling = false;
  180.         get_lyrics();
  181.         change_focus();
  182.         k = g_tab[focus].ante_lines * LINE_HEIGHT;
  183.         if(g_lyrics_status>0) {
  184.             pos = midpoint - k;
  185.             g_playtimer = window.CreateTimerInterval(PLAYTIMER_VALUE);
  186.         } else {
  187.             delta = (g_tab[g_tab.length-1].ante_lines + g_tab[g_tab.length-1].total_lines);
  188.             pos = (wh / 2) - (delta * LINE_HEIGHT / 2);
  189.         }
  190.     }
  191. }
  192.  
  193. function on_paint(gr) {
  194.     PLAIN_COLOR_BG && gr.FillSolidRect(0, 0, ww, wh, g_plainbg_colour);
  195.     if(fb.IsPlaying||fb.IsPaused) {
  196.         show_lyrics(gr, g_tab, pos);
  197.         DEBUG && gr.GdiDrawText(g_lyrics_status.toString(), g_font, g_normalcolour, 5, 5, ww, LINE_HEIGHT, DT_TOP | DT_LEFT | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
  198.     }
  199.     DITHER && gr.FillGradRect(0, 0, ww, 11, 90, g_txt_shadowcolour, RGBA(0,0,0,0));
  200.     DITHER && gr.FillGradRect(0, wh-11, ww, 11, 270, g_txt_shadowcolour, RGBA(0,0,0,0));
  201.    
  202.     DITHER && gr.FillGradRect(0, 0, ww, 1, 90, g_txt_shadowcolour, RGBA(0,0,0,0));
  203.     DITHER && gr.FillGradRect(0, wh-2, ww, 1, 90, RGBA(0,0,0,0), g_txt_shadowcolour);
  204. }
  205.  
  206. function on_mouse_lbtn_dblclk(x, y, mask) {
  207.     on_size();
  208. }
  209.  
  210. function on_mouse_leave() {
  211.     window.Repaint();
  212. }
  213.  
  214. function on_playback_time(time) {
  215.     // at each new seconde, centiemes is reset to 0 (Increment on timer every 100ms)
  216.     centiemes = 0;
  217.     if(g_lyrics_status==0) {
  218.         if(elap_seconds.Eval()==3) {
  219.             on_size();
  220.         }
  221.         window.Repaint();
  222.     }
  223. }
  224.  
  225. function on_playback_new_track(info) {
  226.     g_metadb = fb.IsPlaying ? fb.GetNowPlaying() : false;
  227.     g_playtimer && window.KillTimer(g_playtimer);
  228.     pos=0;
  229.     g_scroll = 0;
  230.     g_is_scrolling = false;
  231.     get_lyrics();
  232.     change_focus();
  233.     if(g_lyrics_status>0) {
  234.         g_playtimer = window.CreateTimerInterval(PLAYTIMER_VALUE);
  235.     }
  236. }
  237.  
  238. function on_playback_seek(time) {
  239.     var k;
  240.     if(g_lyrics_status>0) {
  241.         g_scroll = 0;
  242.         g_is_scrolling = false;
  243.         change_focus();
  244.         k = g_tab[focus].ante_lines * LINE_HEIGHT;
  245.         pos = midpoint - k;
  246.         window.Repaint();
  247.     }
  248. }
  249.  
  250. function on_playback_stop(reason) {
  251.     g_metadb = fb.IsPlaying ? fb.GetNowPlaying() : false;
  252.     g_playtimer && window.KillTimer(g_playtimer);
  253.     if(reason==0) {
  254.         // Stop
  255.         window.Repaint();
  256.     }
  257. }
  258.  
  259. function on_mouse_wheel(delta) {
  260.     if(g_lyrics_status>0) {
  261.         if(delta>0) {
  262.             pos = (pos>=midpoint)?pos:pos + LINE_HEIGHT;
  263.         } else {
  264.             pos = (pos<=(wh/2 - g_tab_length*LINE_HEIGHT))?pos:pos - LINE_HEIGHT;
  265.         }
  266.         window.Repaint();
  267.     }
  268. }
  269.  
  270. function on_timer(id) {
  271.    
  272.     var t1 = elap_seconds.Eval() * 100 + centiemes;
  273.     var t2 = len_seconds.Eval() * 100;
  274.     var p1, p2;
  275.    
  276.     if(t1>t2-100) {
  277.         g_playtimer && window.KillTimer(g_playtimer);
  278.     }
  279.  
  280.     if(g_playtimer) {
  281.         if(g_playtimer.ID == id) {
  282.             if(!g_is_scrolling && t1>=g_tab[focus_next].timer) {
  283.                 p1 = g_tab[focus].ante_lines*LINE_HEIGHT;
  284.                 p2 = g_tab[focus_next].ante_lines*LINE_HEIGHT;
  285.                 g_scroll = p2 - p1;
  286.                 change_focus();
  287.                 g_is_scrolling = true;
  288.             }
  289.             if (g_scroll>0) {
  290.                 pos -= 1;
  291.                 g_scroll -= 1;
  292.                 window.Repaint();
  293.             } else {
  294.                 g_is_scrolling = false;
  295.             }
  296.             centiemes = (centiemes>98)?0:(centiemes+1);
  297.         }
  298.     }
  299.  
  300. }
  301.  
  302. function show_lyrics(gr, tab, posy) {
  303.     var i, k;
  304.     var text_colour;
  305.    
  306.     gr.SetTextRenderingHint(5);
  307.    
  308.     // decoding text alignment (from Properties)
  309.     switch(TXT_ALIGN.toUpperCase()) {
  310.         case "LEFT":
  311.             g_txt_align = lc_stringformat;
  312.             break;
  313.         case "CENTER":
  314.             g_txt_align = cc_stringformat;
  315.             break;
  316.         case "RIGHT":
  317.             g_txt_align = rc_stringformat;
  318.             break;
  319.         default:
  320.             g_txt_align = cc_stringformat;
  321.     }
  322.  
  323.     if(g_lyrics_status>0) {
  324.         if(posy>=0) {
  325.             LIGHT_BG && gr.FillSolidRect(0, Math.floor(posy - wh/2), ww, Math.floor(wh/2), g_ovbg_normalcolour);
  326.         }
  327.     } else {
  328.         LIGHT_BG && gr.FillSolidRect(0, 0, ww, wh, g_ovbg_normalcolour);
  329.     }
  330.  
  331.     for(i=0;i<tab.length;i++) {
  332.         if(Math.round(posy)>=(LINE_HEIGHT*-4) && Math.round(posy)<wh)
  333.         {
  334.             if(i==focus && g_lyrics_status==1) {
  335.                 text_colour = g_txt_highlightcolour;
  336.             } else {
  337.                 if(g_lyrics_status==0) {
  338.                     text_colour = g_txt_highlightcolour;
  339.                 } else {
  340.                     text_colour = g_txt_normalcolour;
  341.                 }
  342.             }
  343.             if(g_lyrics_status>0) {
  344.                 if(!LIGHT_BG && i==focus && tab[i].text.length>1 && g_lyrics_status==1) {
  345.                     gr.FillSolidRect(0, Math.floor(posy), ww, (tab[i].total_lines*LINE_HEIGHT), g_ovbg_highlightcolour);
  346.                 } else {
  347.                     LIGHT_BG && gr.FillSolidRect(0, Math.floor(posy), ww, (tab[i].total_lines*LINE_HEIGHT-1), (i==focus && tab[i].text.length>1 && g_lyrics_status==1)?g_ovbg_highlightcolour:g_ovbg_normalcolour);
  348.                     //LIGHT_BG && gr.FillSolidRect(0, Math.floor(posy+(tab[i].total_lines*LINE_HEIGHT-1)), ww, 1, g_ovbg_lineseparatorcolour);
  349.                 }
  350.             }
  351.             TEXT_SHADOW && gr.DrawString(tab[i].text, g_font, g_txt_shadowcolour, 1+H_PADDING, Math.floor(posy)-1, ww-H_PADDING*2, (tab[i].total_lines*LINE_HEIGHT), g_txt_align);
  352.             TEXT_SHADOW && gr.DrawString(tab[i].text, g_font, g_txt_shadowcolour, 1+H_PADDING, Math.floor(posy), ww-H_PADDING*2, (tab[i].total_lines*LINE_HEIGHT), g_txt_align);
  353.             gr.DrawString(tab[i].text, g_font, text_colour, 0+H_PADDING, Math.floor(posy)-1, ww-H_PADDING*2, (tab[i].total_lines*LINE_HEIGHT), g_txt_align);
  354.         }
  355.         posy = Math.floor(posy+LINE_HEIGHT+((tab[i].total_lines-1)*LINE_HEIGHT));
  356.     }
  357.  
  358.     if(g_lyrics_status>0 && posy<=wh) {
  359.         LIGHT_BG && gr.FillSolidRect(0, Math.floor(posy), ww, Math.floor(wh), g_ovbg_normalcolour);
  360.     }
  361.  
  362. }
  363.  
  364. function grab_timer(tab, str, count, timer_prec, balise) {
  365.     var tminutes, tsecondes, tcentiemes;
  366.     var i;
  367.     var f_sentence = new sentence;
  368.     var b = balise - 1;
  369.     if(g_lyrics_status==1 && balise>0) {
  370.         if (str.substring(0,1)=="[") {
  371.             tminutes = str.substring(1+(b*g_balise_char_offset), 3+(b*g_balise_char_offset));
  372.             tsecondes = str.substring(4+(b*g_balise_char_offset), 6+(b*g_balise_char_offset));
  373.             tcentiemes = str.substring(7+(b*g_balise_char_offset), 9+(b*g_balise_char_offset));
  374.             if(IsNumeric(str.substring(1,2))==true) {
  375.                 f_sentence.type = "ly";
  376.                 f_sentence.timer = Math.round(tminutes)*60*100 + Math.round(tsecondes)*100 + Math.round(tcentiemes) - DEFAULT_OFFSET;
  377.                 f_sentence.text = remove_enhanced_balises(str.substring(g_balise_char_offset*g_balise_total, str.length));
  378.                 f_sentence.text = (f_sentence.text.length==0)?f_sentence.text+" ":f_sentence.text;
  379.             } else {
  380.                 f_sentence.type = null;
  381.                 f_sentence.timer = 0;
  382.                 f_sentence.text = "";
  383.             }
  384.         } else {
  385.             // no balise ==> line is set as a comment (as a blank line)
  386.             if(count==0) g_lyrics_status = 2;
  387.             f_sentence.type = null;
  388.             f_sentence.timer = timer_prec;
  389.             f_sentence.text = "";
  390.         }
  391.     } else {
  392.         f_sentence.type = "tx";
  393.         f_sentence.timer = 0;
  394.         // check if it's not finally a synch lyrics (lrc) with some first lines with no timestamp!
  395.         if (str.substring(0,1)=="[") {
  396.             // test balise (=ts) type is ok ( [99:99.999] )
  397.             if (ts_analyzer(str).substring(9,10)=="]") {
  398.                 g_lyrics_status = 1;
  399.                 str = ts_analyzer(str);
  400.                 tminutes = str.substring(1+(b*g_balise_char_offset), 3+(b*g_balise_char_offset));
  401.                 tsecondes = str.substring(4+(b*g_balise_char_offset), 6+(b*g_balise_char_offset));
  402.                 tcentiemes = str.substring(7+(b*g_balise_char_offset), 9+(b*g_balise_char_offset));
  403.                 f_sentence.type = "ly";
  404.                 f_sentence.timer = Math.round(tminutes)*60*100 + Math.round(tsecondes)*100 + Math.round(tcentiemes) - DEFAULT_OFFSET;
  405.                 f_sentence.text = remove_enhanced_balises(str.substring(g_balise_char_offset*g_balise_total, str.length));
  406.                 f_sentence.text = (f_sentence.text.length==0)?f_sentence.text+" ":f_sentence.text;
  407.             } else {
  408.                 f_sentence.text = str;
  409.             }
  410.         } else {
  411.             f_sentence.text = str;
  412.         }
  413.     }
  414.     return f_sentence;
  415. }
  416.  
  417. function load_file(filePath, fileName) {
  418.     var tab = Array();
  419.     var fline = new sentence;
  420.     var count = 0;
  421.     var enr = 0;
  422.     var str="";
  423.     var balise;
  424.     var delta;
  425.     g_file = open_file(filePath, fileName, ForReading);
  426.     g_balise_shift = 0;
  427.     while(!g_file.AtEndOfStream) {
  428.         str = g_file.ReadLine();
  429.         if(g_lyrics_status==1) {
  430.             if (str.substring(0,1)=="[") {
  431.                 str = ts_analyzer(str);
  432.                 g_balise_total = 0;
  433.                 balise = 0;
  434.                 while(str.substring(balise*10,balise*10+1)=="[") {
  435.                     balise += 1;
  436.                 }
  437.                 g_balise_total = balise;
  438.             } else if(enr==0) {
  439.                 g_lyrics_status = 2;
  440.                 g_balise_total = 1;
  441.             }
  442.         } else {
  443.             g_balise_total = 1;
  444.         }
  445.                
  446.         if(g_balise_total>1) g_multi_balise = true; else g_multi_balise = false;
  447.  
  448.         // str loop for each timestamp found for it ==> occurs created in the array
  449.         for (balise=1;balise<=g_balise_total;balise++) {
  450.             fline=grab_timer(tab, str, count, (count>0)?tab[count-1].timer:0, balise);
  451.             if(fline.type!=null) {
  452.                 tab.push(fline);
  453.                 count++;
  454.             }
  455.         }
  456.         enr += 1;
  457.     }
  458.     close_file(g_file);
  459.    
  460.     // if file read is empty, set lyrics as not found to avoid script errors
  461.     if(count==0) {
  462.         g_lyrics_status = 0;
  463.         g_tab = load_track_info();
  464.         delta = (g_tab[g_tab.length-1].ante_lines + g_tab[g_tab.length-1].total_lines);
  465.         pos = (wh / 2) - (delta * LINE_HEIGHT / 2);
  466.         return g_tab;
  467.     } else {
  468.         // add a default last sentence with a timer maximum (for ease of use focus line search method)
  469.         tab.push(new sentence);
  470.         tab[count].type = "ly";
  471.         tab[count].timer = 9999999;
  472.         tab[count].text = "---";
  473.         tab[count].total_lines = 1;
  474.         tab[count].ante_lines = tab[count-1].ante_lines + tab[count-1].total_lines;
  475.         return sort_tab(tab);
  476.     }
  477. }
  478.  
  479. function parse_tag(tag) {
  480.     var t_tab = Array();
  481.     var i, j;
  482.     j = 0;
  483.     for(i=0;i<tag.length;i++) {
  484.         if(i==tag.length-1 || tag.charCodeAt(i)==10 || (i>0 && (i<tag.length-5) && (tag.substring(i, i+1)=="["))) {
  485.             t_tab.push(tag.substring(j, i));
  486.             if(tag.charCodeAt(i)!=10) {
  487.                 j = i;
  488.             } else {
  489.                 j = i+1;
  490.             }
  491.         }
  492.     }
  493.     return parse_line(t_tab);
  494. }
  495.  
  496. function parse_line(tagtab) {
  497.     var tab = Array();
  498.     var fline = new sentence;
  499.     var count = 0;
  500.     var enr = 0;
  501.     var str="";
  502.     var balise;
  503.     var delta;
  504.     g_balise_shift = 0;
  505.     for(enr=0;enr<tagtab.length;enr++) {
  506.         str = tagtab[enr];
  507.         if(g_lyrics_status==1) {
  508.             if (str.substring(0,1)=="[") {
  509.                 str = ts_analyzer(str);
  510.                 g_balise_total = 0;
  511.                 balise = 0;
  512.                 while(str.substring(balise*10,balise*10+1)=="[") {
  513.                     balise += 1;
  514.                 }
  515.                 g_balise_total = balise;
  516.             } else if(enr==0) {
  517.                 g_lyrics_status = 2;
  518.                 g_balise_total = 1;
  519.             }
  520.         } else {
  521.             g_balise_total = 1;
  522.         }
  523.        
  524.         if(g_balise_total>1) g_multi_balise = true; else g_multi_balise = false;
  525.  
  526.         // str loop for each timestamp found for it ==> occurs created in the array
  527.         for (balise=1;balise<=g_balise_total;balise++) {
  528.             fline=grab_timer(tab, str, count, (count>0)?tab[count-1].timer:0, balise);
  529.             if(fline.type!=null) {
  530.                 tab.push(fline);
  531.                 count++;
  532.             }
  533.         }
  534.     }
  535.    
  536.     // if file read is empty, set lyrics as not found to avoid script errors
  537.     if(count==0) {
  538.         g_lyrics_status = 0;
  539.         g_tab = load_track_info();
  540.         delta = (g_tab[g_tab.length-1].ante_lines + g_tab[g_tab.length-1].total_lines);
  541.         pos = (wh / 2) - (delta * LINE_HEIGHT / 2);
  542.         return g_tab;
  543.     } else {
  544.         // add a default last sentence with a timer maximum (for ease of use focus line search method)
  545.         tab.push(new sentence);
  546.         tab[count].type = "ly";
  547.         tab[count].timer = 9999999;
  548.         tab[count].text = "---";
  549.         tab[count].total_lines = 1;
  550.         tab[count].ante_lines = tab[count-1].ante_lines + tab[count-1].total_lines;
  551.         return sort_tab(tab);
  552.     }
  553. }
  554.  
  555. function load_track_info() {
  556.     var tab = Array(new sentence, new sentence, new sentence, new sentence);
  557.     var count = 0;
  558.  
  559.     tab[count].type = "tx";
  560.     tab[count].text = "---";
  561.     count++;
  562.    
  563.     tab[count].type = "tx";
  564.     tab[count].text = artist.Eval();
  565.     count++;
  566.    
  567.     tab[count].type = "tx";
  568.     tab[count].text = title.Eval();
  569.     count++;
  570.  
  571.     tab[count].type = "tx";
  572.     tab[count].text = "---";
  573.     count++;
  574.    
  575.     return calc_lines(tab);
  576. }
  577.  
  578. function open_file(filePath, fileName, ioMode) {
  579.     var fileInst = null;
  580.     var bool = file_exists(filePath + fileName);
  581.     if(bool) {
  582.         fileInst = g_fso.OpenTextFile(filePath + fileName, ioMode);
  583.     }
  584.     return fileInst;
  585. }
  586.  
  587. function close_file(fileInst) {
  588.         fileInst.Close();
  589. }
  590.  
  591. function read_file(fileInst) {
  592.     var line = fileInst.ReadLine();
  593.     return line;
  594. }
  595.  
  596.  
  597. function folder_exists(folderPath) {
  598.     var fso, bool;
  599.     fso = new ActiveXObject("Scripting.FileSystemObject");
  600.     bool = fso.FolderExists(folderPath);
  601.     return bool;
  602. }
  603.  
  604.  
  605. function file_exists(filePath) {
  606.     var fso, bool;
  607.     fso = new ActiveXObject("Scripting.FileSystemObject");
  608.     bool = fso.Fileexists(filePath);
  609.     return bool;
  610. }
  611.  
  612. function lyrics_folder_exists(folder_name) {
  613.     var fso;
  614.     var bool=1;
  615.     fso = new ActiveXObject("Scripting.FileSystemObject");
  616.     if (folder_exists(fb.ProfilePath + folder_name) == false) {
  617.         fso.CreateFolder(fb.ProfilePath + folder_name);
  618.         bool=0;
  619.     }
  620.     return bool;
  621. }
  622.  
  623. function get_lyrics() {
  624.     var i=0;
  625.     var nbl=0;
  626.     var delta;
  627.     var tag;
  628.     var bool_tag = false;
  629.        
  630.     // reset lyrics tab
  631.     g_lyrics_status = 0;
  632.     if(g_tab.length>0) g_tab.splice(0, g_tab.length);
  633.     pos = midpoint;
  634.     focus = 0;
  635.     window.Repaint();
  636.        
  637.     // check TAGs
  638.     tag = lyrics.Eval();
  639.     if(tag.length>0) {
  640.         bool_tag = true;
  641.         if(tag.substring(0,1)=="[") g_lyrics_status = 1; else g_lyrics_status = 2;
  642.     } else {
  643.         // check files in music folder (filename syntax #1)
  644.         g_lyrics_status=null;
  645.         g_lyrics_filename = artist.Eval() + " -" + title.Eval();
  646.         if(file_exists(lyrics_dir2.EvalWithMetadb(g_metadb)+g_lyrics_filename+".lrc")) {
  647.             g_lyrics_filename  = g_lyrics_filename+".lrc";
  648.             g_lyrics_status = 1;
  649.             g_lyrics_path = lyrics_dir2.EvalWithMetadb(g_metadb);
  650.         } else {
  651.             if(file_exists(lyrics_dir2.EvalWithMetadb(g_metadb)+g_lyrics_filename+".txt")) {
  652.                 g_lyrics_filename  = g_lyrics_filename+".txt";
  653.                 g_lyrics_status = 2;
  654.                 g_lyrics_path = lyrics_dir2.EvalWithMetadb(g_metadb);
  655.             }
  656.         }
  657.         // check files in music folder (filename syntax #2)
  658.         if(g_lyrics_status==null) {
  659.             g_lyrics_filename = artist.Eval() + " - " + title.Eval();
  660.             if(file_exists(lyrics_dir2.EvalWithMetadb(g_metadb)+g_lyrics_filename+".lrc")) {
  661.                 g_lyrics_filename  = g_lyrics_filename+".lrc";
  662.                 g_lyrics_status = 1;
  663.                 g_lyrics_path = lyrics_dir2.EvalWithMetadb(g_metadb);
  664.             } else {
  665.                 if(file_exists(lyrics_dir2.EvalWithMetadb(g_metadb)+g_lyrics_filename+".txt")) {
  666.                     g_lyrics_filename  = g_lyrics_filename+".txt";
  667.                     g_lyrics_status = 2;
  668.                     g_lyrics_path = lyrics_dir2.EvalWithMetadb(g_metadb);
  669.                 }
  670.             }
  671.         }
  672.         // if not found, check in lyrics folder (filename syntax #1)
  673.         if(g_lyrics_status==null) {
  674.             g_lyrics_filename = artist.Eval() + " -" + title.Eval();
  675.             if(file_exists(lyrics_dir1+g_lyrics_filename+".lrc")) {
  676.                 g_lyrics_filename  = g_lyrics_filename+".lrc";
  677.                 g_lyrics_status = 1;
  678.                 g_lyrics_path = lyrics_dir1;
  679.             } else {
  680.                 if(file_exists(lyrics_dir1+g_lyrics_filename+".txt")) {
  681.                     g_lyrics_filename  = g_lyrics_filename+".txt";
  682.                     g_lyrics_status = 2;
  683.                     g_lyrics_path = lyrics_dir1;
  684.                 }
  685.             }
  686.         }
  687.         // if not found, check in lyrics folder (filename syntax #2)
  688.         if(g_lyrics_status==null) {
  689.             g_lyrics_filename = artist.Eval() + " - " + title.Eval();
  690.             if(file_exists(lyrics_dir1+g_lyrics_filename+".lrc")) {
  691.                 g_lyrics_filename  = g_lyrics_filename+".lrc";
  692.                 g_lyrics_status = 1;
  693.                 g_lyrics_path = lyrics_dir1;
  694.             } else {
  695.                 if(file_exists(lyrics_dir1+g_lyrics_filename+".txt")) {
  696.                     g_lyrics_filename  = g_lyrics_filename+".txt";
  697.                     g_lyrics_status = 2;
  698.                     g_lyrics_path = lyrics_dir1;
  699.                 } else {
  700.                     g_lyrics_status = 0;
  701.                     g_lyrics_path = null;
  702.                 }
  703.             }          
  704.         }
  705.     }
  706.     // if lyrics found
  707.     if(g_lyrics_status>0) {
  708.         if(bool_tag) {
  709.             g_tab = parse_tag(tag);
  710.         } else {
  711.             g_tab = load_file(g_lyrics_path, g_lyrics_filename);
  712.         }
  713.     }  else {
  714.         g_tab = load_track_info();
  715.         delta = (g_tab[g_tab.length-1].ante_lines + g_tab[g_tab.length-1].total_lines);
  716.         pos = (wh / 2) - (delta * LINE_HEIGHT / 2);
  717.     }
  718.  
  719.     if(g_lyrics_status==2) {
  720.         for(i=0;i<g_tab.length-1;i++) {
  721.             g_tab[i].timer = i * Math.floor(len_seconds.Eval() * 100 / g_tab.length);
  722.         }
  723.     }
  724. }
  725.  
  726. function change_focus() {
  727.     var i, j;
  728.     var t1 = elap_seconds.Eval()*100+centiemes;
  729.    
  730.     if(g_lyrics_status>0) {
  731.         // search line index just after actual timer
  732.         for(i=0;i<g_tab.length;i++) {
  733.             if(g_tab[i].timer>t1) break;
  734.         }
  735.         focus_next=i;
  736.         focus = (i>0)?i-1:0;
  737.         // now i check if there are more than one line with the same timer as focus one & if found, i take it as new focus 'cause it's the first (not a blank line)
  738.         if(focus>0) {
  739.             for(i=0;i<focus;i++) {
  740.                 if(g_tab[i].timer==focus) {
  741.                     focus = i;
  742.                     break;
  743.                 }
  744.             }
  745.         }
  746.     }
  747. }
  748.  
  749. function calc_lines(ctab) {
  750.     var i, j;
  751.     var padx = 0;
  752.     var tmp_img;
  753.     var gp;
  754.     var lineh;
  755.     g_tab_length = 0;
  756.     if(ww==0) return ctab; // test to avoid errors if panel is hidden (ww=0)
  757.     tmp_img = gdi.CreateImage(ww-(H_PADDING*2)-padx, 100);
  758.     gp = tmp_img.GetGraphics();
  759.     for(i=0;i<ctab.length;i++) {
  760.         // calc sentence #lines to display / window.width
  761.         if(ctab[i].type!=null) {
  762.             lineh = gp.MeasureString(ctab[i].text, g_font, 0, 0, ww-(H_PADDING*2)-padx, wh).Height;
  763.             ctab[i].total_lines = (lineh/LINE_HEIGHT) > Math.floor(lineh/LINE_HEIGHT) ? Math.floor(lineh/LINE_HEIGHT) + 1 : Math.floor(lineh/LINE_HEIGHT)  ;
  764.             ctab[i].ante_lines = 0;
  765.             for(j=0;j<i;j++) {
  766.                 ctab[i].ante_lines += ctab[j].total_lines;
  767.             }
  768.         }
  769.         g_tab_length += ctab[i].total_lines;
  770.     }
  771.     CollectGarbage();
  772.     return ctab;
  773. }
  774.  
  775. function sort_tab(tab2sort) {
  776.     var tab = Array();
  777.     var i, j;
  778.     var tmp = new sentence;
  779.     var smallest = 0;
  780.     for(i=0;i<tab2sort.length;i++) {
  781.         for(j=i;j<tab2sort.length;j++) {
  782.             if(tab2sort[i].timer > tab2sort[j].timer) {
  783.                 tmp = tab2sort[i];
  784.                 tab2sort[i] = tab2sort[j];
  785.                 tab2sort[j] = tmp;
  786.             }
  787.         }
  788.         tab.push(tab2sort[i]);
  789.     }
  790.     tab = calc_lines(tab);
  791.     return tab;
  792. }
  793.  
  794. function remove_enhanced_balises(str) {
  795.     var i;
  796.     var chr1, chr2;
  797.     var new_str="";
  798.     for(i=0;i<str.length;i++) {
  799.         chr1 = str.substring(i, i+1);
  800.         if(i+10<=str.length) chr2 = str.substring(i+9, i+10); else chr2=null;
  801.         if(chr1=="<" && chr2==">") {
  802.             i = i + 10 - 1;
  803.         } else {
  804.             new_str = new_str + chr1;
  805.         }
  806.     }
  807.     return new_str;
  808. }
  809.  
  810. function ts_analyzer(str) {
  811.     var i, j;
  812.     var ch;
  813.     var str2 = "";
  814.     var state=0;
  815.     var deb = -1;
  816.     var fin = -1;
  817.     var sep1 = -1;
  818.     var sep2 = -1;
  819.     var ts_len;
  820.     var suite=0;
  821.     for(i=0;i<str.length;i++) {
  822.         ch = str.substring(i, i+1);
  823.         switch(state) {
  824.         case 0:            
  825.             if(ch=="[") {
  826.                 state=1;
  827.                 deb=i;
  828.                 fin=-1;
  829.             }
  830.             break;
  831.         case 1:
  832.             if(deb>=0 && ch==":") {
  833.                 state=2;
  834.                 sep1=i;
  835.             }
  836.             if(i>deb+3) {
  837.                 deb=-1;
  838.                 fin=-1;
  839.                 sep1=-1;
  840.                 sep2=-1;
  841.                 state=0;
  842.             }
  843.             break;
  844.         case 2:
  845.             if(sep1>=0 && (ch==":" || ch==".")) {
  846.                 state=3;
  847.                 sep2=i;
  848.             }
  849.             if(sep1>=0 && sep2==-1 && ch=="]") {
  850.                 state=4;
  851.                 fin=i;
  852.             }
  853.             if(i>sep1+3) {
  854.                 deb=-1;
  855.                 fin=-1;
  856.                 sep1=-1;
  857.                 sep2=-1;
  858.                 state=0;
  859.             }
  860.             break;
  861.         case 3:
  862.             if(deb>=0 && ch=="]") {
  863.                 state=4;
  864.                 if(i==str.length-1) {
  865.                     str=str+" ";
  866.                 }
  867.                 fin=i;
  868.             }
  869.             if(i>deb+10) {
  870.                 deb=-1;
  871.                 fin=-1;
  872.                 sep1=-1;
  873.                 sep2=-1;
  874.                 state=0;
  875.             }
  876.             break;
  877.         case 4:
  878.             ts_len=fin-deb+1;
  879.             switch(ts_len) {
  880.                 case 6:
  881.                     str2 = str2 + "[0" + str.substring(deb+1,deb+2) + ":" + str.substring(deb+3, deb+5) + ".00]";
  882.                     break;
  883.                 case 7:
  884.                     str2 = str2 + str.substring(deb,deb+6) + ".00]";
  885.                     break;
  886.                 case 9:
  887.                     str2 = str2 + "[0" + str.substring(deb+1,deb+2) + ":" + str.substring(deb+3, deb+5) + "." + str.substring(deb+6, deb+8) + "]";
  888.                     break;
  889.                 case 10:
  890.                     if(sep1==deb+2) {
  891.                         str2 = str2 + "[0" + str.substring(deb+1,deb+2) + ":" + str.substring(deb+3, deb+5) + "." + str.substring(deb+6, deb+8) + "]";
  892.                     } else {
  893.                         str2 = str2 + str.substring(deb,deb+10);
  894.                     }
  895.                     break;
  896.                 case 11:
  897.                     str2 = str2 + str.substring(deb,deb+9) + "]";
  898.                     break;
  899.             }
  900.             j += 10;
  901.             if(str.substring(fin+1,fin+2)=="[") {
  902.                 suite = 1;
  903.                 i = fin;
  904.                 deb = -1;
  905.                 fin = -1;
  906.                 sep1 = -1;
  907.                 sep2 = -1;
  908.                 state = 0;
  909.             } else {
  910.                 suite = -1;
  911.                 i = str.length - 1;
  912.                 str2 = str2 + str.substring(fin+1, str.length);
  913.             }
  914.             break;      
  915.         }
  916.     }
  917.     return str2;
  918. }
  919.  
  920. function IsNumeric(str) {
  921.     var ValidChars = "0123456789.";
  922.     for (i = 0; i < str.length; i++) {
  923.         if (ValidChars.indexOf(str.charAt(i)) == -1) {
  924.             return false;
  925.         }
  926.     }
  927.     return true;
  928. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement