Advertisement
Guest User

Br3tt

a guest
Nov 1st, 2010
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ===========================================================================================================
  3. Lyriks 1.3 (build 20101101.1430) - 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. // ================================================/ Properties
  21. var FONT_SIZE = window.GetProperty("Font size", 12);
  22. var PLAYTIMER_VALUE = window.GetProperty("Timer value in ms [10;100]", 10);
  23. var LINE_HEIGHT = window.GetProperty("Line height [20;30]", 24);
  24. var TEXT_SHADOW = window.GetProperty("Text shadow", true);
  25. var TEXT_GLOW = window.GetProperty("Glow enabled", true);
  26. var GLOW_COLOUR = window.GetProperty("Glow colour", "RGBA(40, 60, 100, 200);");
  27. var FOCUS_COLOUR = window.GetProperty("Active line colour (focus)", "RGBA(235, 245, 255, 075);");
  28. var BG_DRAW = window.GetProperty("Background enabled", false);
  29. var BG_COLOUR = window.GetProperty("Background colour", "RGBA(000, 000, 000, 170);");
  30. var DITHER = window.GetProperty("Top & Botom shadow", true);
  31. var H_PADDING = window.GetProperty("Horizontal padding [0;20]", 20);
  32. var TXT_ALIGN = window.GetProperty("Text alignment (left/center/right)", "center");
  33. var DEBUG = false;
  34. var DEFAULT_OFFSET = 29;
  35.  
  36. // ================================================/ Constants
  37.  
  38. // Text formatting function
  39. // {{
  40. function StringFormat() {
  41.     var h_align = 0, v_align = 0, trimming = 0, flags = 0;
  42.     switch (arguments.length)
  43.     {
  44.         // fall-thru
  45.         case 4:
  46.             flags = arguments[3];
  47.         case 3:
  48.             trimming = arguments[2];
  49.         case 2:
  50.             v_align = arguments[1];
  51.         case 1:
  52.             h_align = arguments[0];
  53.             break;
  54.         default:
  55.             return 0;
  56.     }
  57.     return ((h_align << 28) | (v_align << 24) | (trimming << 20) | flags);
  58. }
  59. StringAlignment = {
  60.     Near: 0,
  61.     Centre: 1,
  62.     Far: 2
  63. };
  64. var lt_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Near);
  65. var ct_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Near);
  66. var rt_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Near);
  67. var lc_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Centre);
  68. var cc_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Centre);
  69. var rc_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Centre);
  70. var lb_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Far);
  71. var cb_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Far);
  72. var rb_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Far);
  73. // }}
  74.  
  75. // Use with GdiDrawText()
  76. // {{
  77. var DT_LEFT = 0x00000000;
  78. var DT_RIGHT = 0x00000002;
  79. var DT_TOP = 0x00000000;
  80. var DT_CENTER = 0x00000001;
  81. var DT_VCENTER = 0x00000004;
  82. var DT_WORDBREAK = 0x00000010;
  83. var DT_CALCRECT = 0x00000400;
  84. var DT_NOPREFIX = 0x00000800;
  85. var DT_END_ELLIPSIS = 0x00008000;
  86. // }}
  87.  
  88. //{{
  89. // IO Mode
  90. var ForReading = 1;
  91. var ForWriting = 2;
  92. var ForAppending = 8;
  93. //}}
  94.  
  95. //{{
  96. // Paths
  97. var lyrics_dir1 = fb.Titleformat("$replace($replace(%path%,%filename_ext%,),\,\\)");
  98. var lyrics_dir2 =  fb.FoobarPath + "lyrics\\";
  99. //}}
  100.  
  101. //{{
  102. // new objects
  103. sentence = function () {
  104.     this.timer = 0;
  105.     this.text = "";
  106.     this.total_lines = 0;
  107.     this.ante_lines = 0;
  108. }
  109. //}}
  110.  
  111. function RGBA(r, g, b, a) {
  112.     return ((a << 24) | (r << 16) | (g << 8) | (b));
  113. }
  114.  
  115. // ================================================/ TF
  116. var len = fb.Titleformat("%length%");
  117. var elap = fb.TitleFormat("%playback_time%");
  118. var remain = fb.TitleFormat("%playback_time_remaining%");
  119. var len_seconds = fb.Titleformat("%length_seconds%");
  120. var elap_seconds = fb.TitleFormat("%playback_time_seconds%");
  121. var remain_seconds = fb.Titleformat("%playback_time_remaining_seconds%");
  122. var artist = fb.Titleformat("$replace(%artist%,'/','_')");
  123. var title = fb.Titleformat("%title%");
  124. var lyrics = fb.TitleFormat("[$if2(%LYRICS%,$if2(%LYRIC%,$if2(%UNSYNCED LYRICS%,%UNSYNCED LYRIC%)))]");
  125.  
  126. // ================================================/ Globals
  127. var g_font = gdi.Font("segoe ui", FONT_SIZE, 1);
  128. var g_playtimer;
  129. var g_metadb;
  130. var ww = 0, wh = 0;
  131.  
  132. var g_fso = new ActiveXObject("Scripting.FileSystemObject");
  133. var g_file = null;
  134. var g_tab = Array();
  135. var g_scroll=0;
  136. var g_lyrics_path;
  137. var g_lyrics_filename;
  138. var g_lyrics_status;
  139. var focus=0;
  140. var focus_next=0;
  141. var g_bg_colour;
  142. var g_ovbg_highlightcolour;
  143. var g_txt_normalcolour;
  144. var g_txt_highlightcolour;
  145. var g_txt_shadowcolour;
  146. var g_txt_glowcolour;
  147. var g_dither_shadowcolour;
  148. var centiemes = 0;
  149. var g_is_scrolling = false;
  150. var g_multi_balise = false;
  151. var g_balise_total;
  152. var g_balise_char_offset = 10;
  153. var g_tab_length;
  154. var g_txt_align;
  155.  
  156. var midpoint;
  157. var pos;
  158.  
  159. // START
  160. function on_size() {
  161.     var k;
  162.     ww = window.Width;
  163.     wh = window.Height;
  164.     g_metadb = fb.IsPlaying ? fb.GetNowPlaying() : false;
  165.    
  166.     midpoint = wh / 2 - LINE_HEIGHT / 2;
  167.  
  168.     // colour definitions
  169.     g_bg_colour = eval(BG_COLOUR);
  170.     g_ovbg_highlightcolour = eval(FOCUS_COLOUR);
  171.     g_txt_normalcolour = RGBA(255, 255, 255, 205);
  172.     g_txt_highlightcolour = RGBA(255, 255, 255, 255);
  173.     g_txt_shadowcolour = RGBA(000, 000, 000, 240);
  174.     g_txt_glowcolour = eval(GLOW_COLOUR);
  175.     g_dither_shadowcolour = RGBA(000, 000, 000, 220);
  176.    
  177.     g_playtimer && window.KillTimer(g_playtimer);
  178.  
  179.     if(fb.IsPlaying||fb.IsPaused) {
  180.         g_scroll=0;
  181.         g_is_scrolling = false;
  182.         get_lyrics();
  183.         change_focus(null);
  184.         k = g_tab[focus].ante_lines * LINE_HEIGHT;
  185.         if(g_lyrics_status>0) {
  186.             pos = midpoint - k;
  187.             g_playtimer = window.CreateTimerInterval(PLAYTIMER_VALUE);
  188.         } else {
  189.             delta = (g_tab[g_tab.length-1].ante_lines + g_tab[g_tab.length-1].total_lines);
  190.             pos = (wh / 2) - (delta * LINE_HEIGHT / 2);
  191.         }
  192.     }
  193.  
  194. }
  195.  
  196. function on_paint(gr) {
  197.  
  198.     BG_DRAW && gr.FillSolidRect(0, 0, ww, wh, g_bg_colour);
  199.     if(fb.IsPlaying||fb.IsPaused) {
  200.         show_lyrics(gr, g_tab, pos);
  201.         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);
  202.     }
  203.  
  204.    
  205.     DITHER && gr.FillGradRect(-20, 0, ww+40, 11, 90, g_dither_shadowcolour, RGBA(0,0,0,0));
  206.     DITHER && gr.FillGradRect(-20, wh-11, ww+40, 11, 270, g_dither_shadowcolour, RGBA(0,0,0,0));
  207.     //DITHER && gr.FillGradRect(0, 0, ww, 1, 90, g_dither_shadowcolour, RGBA(0,0,0,0));
  208.     //DITHER && gr.FillGradRect(0, wh-2, ww, 1, 90, RGBA(0,0,0,0), g_dither_shadowcolour);
  209.  
  210. }
  211.  
  212. function on_mouse_lbtn_dblclk(x, y, mask) {
  213.     on_size();
  214. }
  215.  
  216. function on_mouse_leave() {
  217.     window.Repaint();
  218. }
  219.  
  220. function on_playback_time(time) {
  221.     // at each new seconde, centiemes is reset to 0 (Increment on timer every 100ms)
  222.     centiemes = 0;
  223.     if(g_lyrics_status==0) {
  224.         if(elap_seconds.Eval()==3) {
  225.             on_size();
  226.         }
  227.         window.Repaint();
  228.     }
  229. }
  230.  
  231. function on_playback_new_track(info) {
  232.     g_metadb = fb.IsPlaying ? fb.GetNowPlaying() : false;
  233.     g_playtimer && window.KillTimer(g_playtimer);
  234.     pos=0;
  235.     g_scroll = 0;
  236.     g_is_scrolling = false;
  237.     get_lyrics();
  238.     change_focus(null);
  239.     if(g_lyrics_status>0) {
  240.         g_playtimer = window.CreateTimerInterval(PLAYTIMER_VALUE);
  241.     }
  242. }
  243.  
  244. function on_playback_seek(time) {
  245.     var k;
  246.     if(g_lyrics_status>0) {
  247.         g_scroll = 0;
  248.         g_is_scrolling = false;
  249.         change_focus(null);
  250.         k = g_tab[focus].ante_lines * LINE_HEIGHT;
  251.         pos = midpoint - k;
  252.         window.Repaint();
  253.     }
  254. }
  255.  
  256. function on_playback_stop(reason) {
  257.     g_metadb = fb.IsPlaying ? fb.GetNowPlaying() : false;
  258.     g_playtimer && window.KillTimer(g_playtimer);
  259.     if(reason==0) {
  260.         // Stop
  261.         window.Repaint();
  262.     }
  263. }
  264.  
  265. function on_mouse_wheel(delta) {
  266.     if(g_lyrics_status>0) {
  267.         if(delta>0) {
  268.             pos = (pos>=midpoint)?pos:pos + LINE_HEIGHT;
  269.         } else {
  270.             pos = (pos<=(wh/2 - g_tab_length*LINE_HEIGHT))?pos:pos - LINE_HEIGHT;
  271.         }
  272.         window.Repaint();
  273.     }
  274. }
  275.  
  276. function on_timer(id) {
  277.     var t1 = elap_seconds.Eval() * 100 + centiemes;
  278.     var t2 = len_seconds.Eval() * 100;
  279.     var p1, p2;
  280.     if(t1>t2-100) {
  281.         g_playtimer && window.KillTimer(g_playtimer);
  282.     }
  283.     if(g_playtimer) {
  284.         if(g_playtimer.ID == id) {
  285.             if(!g_is_scrolling && t1>=g_tab[focus_next].timer) {
  286.             //if(t1>=g_tab[focus_next].timer) {
  287.                 p1 = g_tab[focus].ante_lines*LINE_HEIGHT;
  288.                 p2 = g_tab[focus_next].ante_lines*LINE_HEIGHT;
  289.                 g_scroll = p2 - p1;
  290.                 change_focus(t1);
  291.                 g_is_scrolling = true;
  292.             }
  293.             if (g_scroll>0) {
  294.                 pos -= 2;
  295.                 g_scroll -= 2;
  296.                 window.Repaint();
  297.             } else {
  298.                 g_is_scrolling = false;
  299.             }
  300.             centiemes = (centiemes>98)?0:(centiemes+1);
  301.         }
  302.     }
  303. }
  304.  
  305. function show_lyrics(gr, tab, posy) {
  306.     var i, k, text_colour;
  307.     gr.SetTextRenderingHint(5);
  308.     switch(TXT_ALIGN.toUpperCase()) {
  309.         case "LEFT":
  310.             g_txt_align = lc_stringformat;
  311.             break;
  312.         case "CENTER":
  313.             g_txt_align = cc_stringformat;
  314.             break;
  315.         case "RIGHT":
  316.             g_txt_align = rc_stringformat;
  317.             break;
  318.         default:
  319.             g_txt_align = cc_stringformat;
  320.     }
  321.  
  322.     for(i=0;i<tab.length;i++) {
  323.         if(Math.round(posy)>=(LINE_HEIGHT*-4) && Math.round(posy)<wh) {
  324.             if(i==focus && g_lyrics_status==1) {
  325.                 text_colour = g_txt_highlightcolour;
  326.             } else {
  327.                 if(g_lyrics_status==0) {
  328.                     text_colour = g_txt_highlightcolour;
  329.                 } else {
  330.                     text_colour = g_txt_normalcolour;
  331.                 }
  332.             }
  333.             if(g_lyrics_status>0) {
  334.                 if(g_scroll<=0 && i==focus && tab[i].text.length>1 && g_lyrics_status==1) {
  335.                     gr.FillGradRect(0, Math.floor(posy), ww, (tab[i].total_lines*LINE_HEIGHT), 90, g_ovbg_highlightcolour, RGBA(0,0,0,0), 0.5);
  336.                 }
  337.             }
  338.             TEXT_GLOW && gr.DrawString(tab[i].text, g_font, g_txt_glowcolour, H_PADDING-1, Math.floor(posy)-1, ww-H_PADDING*2, (tab[i].total_lines*LINE_HEIGHT), g_txt_align);
  339.             TEXT_GLOW && gr.DrawString(tab[i].text, g_font, g_txt_glowcolour, H_PADDING+1, Math.floor(posy)-1, ww-H_PADDING*2, (tab[i].total_lines*LINE_HEIGHT), g_txt_align);
  340.             TEXT_GLOW && gr.DrawString(tab[i].text, g_font, g_txt_glowcolour, H_PADDING, Math.floor(posy)-1-1, ww-H_PADDING*2, (tab[i].total_lines*LINE_HEIGHT), g_txt_align);
  341.             TEXT_GLOW && gr.DrawString(tab[i].text, g_font, g_txt_glowcolour, H_PADDING, Math.floor(posy)-1+1, ww-H_PADDING*2, (tab[i].total_lines*LINE_HEIGHT), g_txt_align);
  342.             TEXT_SHADOW && gr.DrawString(tab[i].text, g_font, g_txt_shadowcolour, H_PADDING+1, Math.floor(posy)-1+2, ww-H_PADDING*2, (tab[i].total_lines*LINE_HEIGHT), g_txt_align);
  343.             gr.DrawString(tab[i].text, g_font, text_colour, H_PADDING, Math.floor(posy)-1, ww-H_PADDING*2, (tab[i].total_lines*LINE_HEIGHT), g_txt_align);
  344.         }
  345.         posy = Math.floor(posy+LINE_HEIGHT+((tab[i].total_lines-1)*LINE_HEIGHT));
  346.     }
  347. }
  348.  
  349. function grab_timer(t_tab) {
  350.     var tminutes, tsecondes, tcentiemes;
  351.     var i, k, f_sentence, b, c, delta, repeat_text;
  352.     var tab = Array();
  353.     for(i=0;i<t_tab.length;i++) {
  354.         if(g_lyrics_status==1) {
  355.             // -----------
  356.             // sync lyrics
  357.             // -----------
  358.             if(IsTimestamped(t_tab[i])) {
  359.                 b = 0;
  360.                 while(t_tab[i].substring(b*10, b*10+1)=="[") {
  361.                     b++;
  362.                 }
  363.                 c = b;
  364.                 repeat_text = remove_enhanced_balises(t_tab[i].substring(c*10, t_tab[i].length));
  365.                 if(repeat_text.length==0) repeat_text = repeat_text + " ";
  366.                 for(b=0;b<c;b++) {
  367.                     f_sentence = new sentence;
  368.                     tminutes = t_tab[i].substring(1+(b*10), 3+(b*10));
  369.                     tsecondes = t_tab[i].substring(4+(b*10), 6+(b*10));
  370.                     tcentiemes = t_tab[i].substring(7+(b*10), 9+(b*10));
  371.                     f_sentence.timer = Math.round(tminutes)*60*100 + Math.round(tsecondes)*100 + Math.round(tcentiemes) - DEFAULT_OFFSET;
  372.                     if(f_sentence.timer<0) f_sentence.timer=0;
  373.                     f_sentence.text = repeat_text;
  374.                     tab.push(f_sentence);
  375.                 }
  376.             }
  377.         } else {
  378.             // -------------
  379.             // unsync lyrics
  380.             // -------------
  381.             if(IsTimestamped(t_tab[i])) {
  382.                 // if sync line in unsync lyrics, i remove timestamps in this line
  383.                 b = 0;
  384.                 while(IsTimestamped(t_tab[i].substring(b*10, b*10+10))) {
  385.                     b++;
  386.                 }
  387.                 t_tab[i] = t_tab[i].substring(b*10, t_tab[i].length);
  388.             }
  389.             f_sentence = new sentence;
  390.             f_sentence.timer = 0;
  391.             f_sentence.text = t_tab[i];
  392.             tab.push(f_sentence);
  393.         }
  394.     }
  395.     if(tab.length==0) {
  396.         g_lyrics_status = 0;
  397.         tab = load_track_info();
  398.         delta = (tab[tab.length-1].ante_lines + tab[tab.length-1].total_lines);
  399.         pos = (wh / 2) - (delta * LINE_HEIGHT / 2);
  400.     } else {
  401.         f_sentence = new sentence;
  402.         f_sentence.timer = 9999999;
  403.         f_sentence.text = "---";
  404.         tab.push(f_sentence);
  405.     }
  406.     CollectGarbage();
  407.     return calc_lines(sort_tab(tab));
  408. }
  409.  
  410. function load_file(filePath, fileName) {
  411.     var i;
  412.     var t_tab = Array();
  413.     var str;
  414.     g_file = open_file(filePath, fileName, ForReading);
  415.     while(!g_file.AtEndOfStream) {
  416.         str = g_file.ReadLine();
  417.         // blank lines are ignored
  418.         if(str.length>0) t_tab.push(str);
  419.     }
  420.     close_file(g_file);
  421.     return grab_timer(check_lyrics_type(t_tab));
  422. }
  423.  
  424. function check_lyrics_type(t_tab) {
  425.     var i;
  426.     var count = 0;
  427.     var ts_percent;
  428.     var tab = Array();
  429.     for(i=0;i<t_tab.length;i++) {
  430.         if(IsTimestamped(t_tab[i])) {
  431.             // format timestamps to default syntax : [99:99.99]
  432.             tab.push(ts_analyzer(t_tab[i]));
  433.             // count # of sync lines
  434.             count++;
  435.         } else {
  436.             if(t_tab[i].length>1) tab.push(t_tab[i]);
  437.         }
  438.     }
  439.     // calc percent of sync lines, if more than 50% of the total filled lines, it's sync lyrics, else, unsync lyrics!
  440.     ts_percent = Math.round(count/tab.length*100);
  441.     if(ts_percent>50) {
  442.         // sync lyrics
  443.         g_lyrics_status = 1;
  444.     } else {
  445.         // unsync lyrics
  446.         g_lyrics_status = 2;
  447.     }
  448.     return tab;
  449. }
  450.  
  451. function parse_tag(tag, delimiter) {
  452.     var t_tab = Array();
  453.     var i, j;
  454.     j = 0;
  455.     for(i=0;i<tag.length;i++) {
  456.         if(i==tag.length-1 || tag.charCodeAt(i)==10 || (i>0 && (i<tag.length-5) && (tag.substring(i, i+1)==delimiter) && (tag.substring(i-1, i)!="]"))) {
  457.             if(i==tag.length-1) {
  458.                 t_tab.push(tag.substring(j, i+1));
  459.             } else {
  460.                 t_tab.push(tag.substring(j, i));
  461.             }
  462.             if(tag.charCodeAt(i)!=10) {
  463.                 j = i;
  464.             } else {
  465.                 j = i+1;
  466.             }
  467.         }
  468.     }
  469.     return grab_timer(check_lyrics_type(t_tab));
  470. }
  471.  
  472. function load_track_info() {
  473.     var tab = Array(new sentence, new sentence, new sentence, new sentence);
  474.     var count = 0;
  475.     tab[count].text = "---";
  476.     count++;
  477.     tab[count].text = artist.Eval();
  478.     count++;
  479.     tab[count].text = title.Eval();
  480.     count++;
  481.     tab[count].text = "---";
  482.     count++;
  483.     return calc_lines(tab);
  484. }
  485.  
  486. function open_file(filePath, fileName, ioMode) {
  487.     var fileInst = null;
  488.     var bool = file_exists(filePath + fileName);
  489.     if(bool) {
  490.         fileInst = g_fso.OpenTextFile(filePath + fileName, ioMode);
  491.     }
  492.     return fileInst;
  493. }
  494.  
  495. function close_file(fileInst) {
  496.         fileInst.Close();
  497. }
  498.  
  499. function read_file(fileInst) {
  500.     var line = fileInst.ReadLine();
  501.     return line;
  502. }
  503.  
  504. function folder_exists(folderPath) {
  505.     var fso, bool;
  506.     fso = new ActiveXObject("Scripting.FileSystemObject");
  507.     bool = fso.FolderExists(folderPath);
  508.     return bool;
  509. }
  510.  
  511. function file_exists(filePath) {
  512.     var fso, bool;
  513.     fso = new ActiveXObject("Scripting.FileSystemObject");
  514.     bool = fso.Fileexists(filePath);
  515.     return bool;
  516. }
  517.  
  518. function lyrics_folder_exists(folder_name) {
  519.     var fso;
  520.     var bool=1;
  521.     fso = new ActiveXObject("Scripting.FileSystemObject");
  522.     if (folder_exists(fb.ProfilePath + folder_name) == false) {
  523.         fso.CreateFolder(fb.ProfilePath + folder_name);
  524.         bool=0;
  525.     }
  526.     return bool;
  527. }
  528.  
  529. function change_focus(tt) {
  530.     var i, j, t1;
  531.     if(tt!=null) {
  532.         t1 = tt;
  533.     } else {
  534.         t1 = elap_seconds.Eval()*100+centiemes;
  535.     }
  536.     if(g_lyrics_status>0) {
  537.         // search line index just after actual timer
  538.         for(i=focus;i<g_tab.length;i++) {
  539.             if(g_tab[i].timer>t1) break;
  540.         }
  541.         focus_next=i;
  542.         focus = (i>0)?i-1:0;
  543.         // 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)
  544.         if(focus>0) {
  545.             for(i=0;i<focus;i++) {
  546.                 if(g_tab[i].timer==g_tab[focus].timer) {
  547.                     focus = i;
  548.                     break;
  549.                 }
  550.             }
  551.         }
  552.     }
  553. }
  554.  
  555. function calc_lines(ctab) {
  556.     var i, j;
  557.     var padx = 0;
  558.     var tmp_img;
  559.     var gp;
  560.     var lineh;
  561.     g_tab_length = 0;
  562.     if(ww==0) return ctab; // test to avoid errors if panel is hidden (ww=0)
  563.     tmp_img = gdi.CreateImage(ww-(H_PADDING*2)-padx, 100);
  564.     gp = tmp_img.GetGraphics();
  565.     for(i=0;i<ctab.length;i++) {
  566.         // calc sentence #lines to display / window.width
  567.         lineh = gp.MeasureString(ctab[i].text, g_font, 0, 0, ww-(H_PADDING*2)-padx, wh).Height;
  568.         ctab[i].total_lines = (lineh/LINE_HEIGHT) > Math.floor(lineh/LINE_HEIGHT) ? Math.floor(lineh/LINE_HEIGHT) + 1 : Math.floor(lineh/LINE_HEIGHT)  ;
  569.         ctab[i].ante_lines = 0;
  570.         for(j=0;j<i;j++) {
  571.             ctab[i].ante_lines += ctab[j].total_lines;
  572.         }
  573.         g_tab_length += ctab[i].total_lines;
  574.     }
  575.     CollectGarbage();
  576.     return ctab;
  577. }
  578.  
  579. function sort_tab(tab2sort) {
  580.     var tab = Array();
  581.     var i, j;
  582.     var tmp = new sentence;
  583.     var smallest = 0;
  584.     for(i=0;i<tab2sort.length;i++) {
  585.         for(j=i;j<tab2sort.length;j++) {
  586.             if(tab2sort[i].timer > tab2sort[j].timer) {
  587.                 tmp = tab2sort[i];
  588.                 tab2sort[i] = tab2sort[j];
  589.                 tab2sort[j] = tmp;
  590.             }
  591.         }
  592.         tab.push(tab2sort[i]);
  593.     }
  594.     return tab;
  595. }
  596.  
  597. function remove_enhanced_balises(str) {
  598.     var i;
  599.     var chr1, chr2;
  600.     var new_str="";
  601.     for(i=0;i<str.length;i++) {
  602.         chr1 = str.substring(i, i+1);
  603.         if(i+10<=str.length) chr2 = str.substring(i+9, i+10); else chr2=null;
  604.         if(chr1=="<" && chr2==">") {
  605.             i = i + 10 - 1;
  606.         } else {
  607.             new_str = new_str + chr1;
  608.         }
  609.     }
  610.     return new_str;
  611. }
  612.  
  613. function ts_analyzer(str) {
  614.     var i, j, ch,  ts_len;
  615.     var str2 = "";
  616.     var state=0;
  617.     var deb = -1;
  618.     var fin = -1;
  619.     var sep1 = -1;
  620.     var sep2 = -1;
  621.     var suite=0;
  622.     for(i=0;i<str.length;i++) {
  623.         ch = str.substring(i, i+1);
  624.         switch(state) {
  625.         case 0:            
  626.             if(ch=="[" && IsNumeric(str.substring(i+1, i+2))) {
  627.                 state=1;
  628.                 deb=i;
  629.                 fin=-1;
  630.             }
  631.             break;
  632.         case 1:
  633.             if(deb>=0 && ch==":") {
  634.                 state=2;
  635.                 sep1=i;
  636.             }
  637.             if(i>deb+3) {
  638.                 deb=-1;
  639.                 fin=-1;
  640.                 sep1=-1;
  641.                 sep2=-1;
  642.                 state=0;
  643.             }
  644.             break;
  645.         case 2:
  646.             if(sep1>=0 && (ch==":" || ch==".")) {
  647.                 state=3;
  648.                 sep2=i;
  649.             }
  650.             if(sep1>=0 && sep2==-1 && ch=="]") {
  651.                 state=4;
  652.                 fin=i;
  653.             }
  654.             if(i>sep1+3) {
  655.                 deb=-1;
  656.                 fin=-1;
  657.                 sep1=-1;
  658.                 sep2=-1;
  659.                 state=0;
  660.             }
  661.             break;
  662.         case 3:
  663.             if(deb>=0 && ch=="]") {
  664.                 state=4;
  665.                 if(i==str.length-1) {
  666.                     str=str+" ";
  667.                 }
  668.                 fin=i;
  669.             }
  670.             if(i>deb+10) {
  671.                 deb=-1;
  672.                 fin=-1;
  673.                 sep1=-1;
  674.                 sep2=-1;
  675.                 state=0;
  676.             }
  677.             break;
  678.         case 4:
  679.             ts_len=fin-deb+1;
  680.             switch(ts_len) {
  681.                 case 6:
  682.                     str2 = str2 + "[0" + str.substring(deb+1,deb+2) + ":" + str.substring(deb+3, deb+5) + ".00]";
  683.                     break;
  684.                 case 7:
  685.                     str2 = str2 + str.substring(deb,deb+6) + ".00]";
  686.                     break;
  687.                 case 9:
  688.                     str2 = str2 + "[0" + str.substring(deb+1,deb+2) + ":" + str.substring(deb+3, deb+5) + "." + str.substring(deb+6, deb+8) + "]";
  689.                     break;
  690.                 case 10:
  691.                     if(sep1==deb+2) {
  692.                         str2 = str2 + "[0" + str.substring(deb+1,deb+2) + ":" + str.substring(deb+3, deb+5) + "." + str.substring(deb+6, deb+8) + "]";
  693.                     } else {
  694.                         str2 = str2 + str.substring(deb,deb+10);
  695.                     }
  696.                     break;
  697.                 case 11:
  698.                     str2 = str2 + str.substring(deb,deb+9) + "]";
  699.                     break;
  700.             }
  701.             j += 10;
  702.             if(str.substring(fin+1,fin+2)=="[") {
  703.                 suite = 1;
  704.                 i = fin;
  705.                 deb = -1;
  706.                 fin = -1;
  707.                 sep1 = -1;
  708.                 sep2 = -1;
  709.                 state = 0;
  710.             } else {
  711.                 suite = -1;
  712.                 i = str.length - 1;
  713.                 str2 = str2 + str.substring(fin+1, str.length);
  714.             }
  715.             break;      
  716.         }
  717.     }
  718.     return str2;
  719. }
  720.  
  721. function IsNumeric(str) {
  722.     var ValidChars = "0123456789.";
  723.     for (i = 0; i < str.length; i++) {
  724.         if (ValidChars.indexOf(str.charAt(i)) == -1) {
  725.             return false;
  726.         }
  727.     }
  728.     return true;
  729. }
  730.  
  731. function IsTimestamped(str) {
  732.     var ValidChars = "[0123456789:.]";
  733.     var count = 0;
  734.     for (i = 0; i < (str.length>10?10:str.length); i++) {
  735.         if (ValidChars.indexOf(str.charAt(i)) >=0) {
  736.             count++;
  737.         }
  738.     }
  739.     if(count>=6 && count <=11) {
  740.         return true;
  741.     } else {
  742.         return false;
  743.     }
  744. }
  745.  
  746. function check_file(path, filename) {
  747.     if(file_exists(path+filename+".lrc")) {
  748.         g_lyrics_filename  = filename+".lrc";
  749.         g_lyrics_path = path;
  750.         return true;
  751.     } else {
  752.         if(file_exists(path+filename+".txt")) {
  753.             g_lyrics_filename  = filename+".txt";
  754.             g_lyrics_path = path;
  755.             return true;
  756.         }
  757.     }
  758.     return false;
  759. }
  760.  
  761. function get_lyrics() {
  762.     var i, count, delta, tag;
  763.     var tpath = Array(lyrics_dir1.EvalWithMetadb(g_metadb), lyrics_dir2);
  764.     var tfilename= Array(artist.Eval() + " -" + title.Eval(), artist.Eval() + " - " + title.Eval());
  765.     var bool_tag = false;
  766.     var bool_file = false;
  767.        
  768.     // reset lyrics tab
  769.     g_lyrics_status = 0;
  770.     if(g_tab.length>0) g_tab.splice(0, g_tab.length);
  771.     pos = midpoint;
  772.     focus = 0;
  773.     window.Repaint();
  774.        
  775.     // check TAGs
  776.     tag = lyrics.Eval();
  777.     if(tag.length>0) {
  778.         bool_tag = true;
  779.         if(tag.substring(0,1)=="[") g_lyrics_status = 1; else g_lyrics_status = 2;
  780.     } else {
  781.         // check files
  782.         i = 0;
  783.         while(!bool_file && i<2) {
  784.             j = 0;
  785.             while(!bool_file && j<2) {
  786.                 bool_file = check_file(tpath[i], tfilename[j]);
  787.                 j++;
  788.             }
  789.             i++;
  790.         }
  791.     }
  792.     // if lyrics found
  793.     if(bool_tag || bool_file) {
  794.         if(bool_tag) {
  795.             g_tab = parse_tag(tag, "[");
  796.         } else {
  797.             g_tab = load_file(g_lyrics_path, g_lyrics_filename);
  798.         }
  799.     }  else {
  800.         g_tab = load_track_info();
  801.         delta = (g_tab[g_tab.length-1].ante_lines + g_tab[g_tab.length-1].total_lines);
  802.         pos = (wh / 2) - (delta * LINE_HEIGHT / 2);
  803.     }
  804.  
  805.     if(g_lyrics_status==2) {
  806.         for(i=0;i<g_tab.length-1;i++) {
  807.             g_tab[i].timer = i * Math.floor(len_seconds.Eval() * 100 / g_tab.length);
  808.         }
  809.     }
  810. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement