Advertisement
Guest User

Br3tt

a guest
Nov 3rd, 2010
1,125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ===========================================================================================================
  3. Lyriks 1.3 (build 20101103.2140) - 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 LINE_HEIGHT = window.GetProperty("Line height", 24);
  23. var TEXT_SHADOW = window.GetProperty("Text shadow", true);
  24. var TEXT_GLOW = window.GetProperty("Glow enabled", true);
  25. var TXT_GLOW_COLOUR = window.GetProperty("Text glow colour", "RGBA(040, 040, 040, 255);");
  26. var BG_FOCUS_COLOUR = window.GetProperty("Active line background colour", "RGBA(235, 245, 255, 075);");
  27. var TXT_NORMAL_COLOUR = window.GetProperty("Text normal colour", "RGBA(210, 210, 210, 255);");
  28. var TXT_FOCUS_COLOUR = window.GetProperty("Text highlite colour", "RGBA(255, 255, 255, 255);");
  29. var BG_DRAW = window.GetProperty("Background enabled", false);
  30. var BG_DEFAULT_COLOUR = window.GetProperty("Background colour", "RGBA(000, 000, 000, 170);");
  31. var DITHER = window.GetProperty("Top & Botom shadow", true);
  32. var H_PADDING = window.GetProperty("Horizontal padding", 20);
  33. var TXT_ALIGN = window.GetProperty("Text alignment (left/center/right)", "center");
  34. var DEBUG = false;
  35. var DEFAULT_OFFSET = 29;
  36.  
  37. // ================================================/ Constants
  38.  
  39. var SCROLL_STEP = 1; // do not modify this value
  40. var PLAYTIMER_VALUE = 10;  // do not modify this value
  41.  
  42. // Text formatting function
  43. // {{
  44. function StringFormat() {
  45.     var h_align = 0, v_align = 0, trimming = 0, flags = 0;
  46.     switch (arguments.length)
  47.     {
  48.         // fall-thru
  49.         case 4:
  50.             flags = arguments[3];
  51.         case 3:
  52.             trimming = arguments[2];
  53.         case 2:
  54.             v_align = arguments[1];
  55.         case 1:
  56.             h_align = arguments[0];
  57.             break;
  58.         default:
  59.             return 0;
  60.     }
  61.     return ((h_align << 28) | (v_align << 24) | (trimming << 20) | flags);
  62. }
  63. StringAlignment = {
  64.     Near: 0,
  65.     Centre: 1,
  66.     Far: 2
  67. };
  68. var lt_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Near);
  69. var ct_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Near);
  70. var rt_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Near);
  71. var lc_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Centre);
  72. var cc_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Centre);
  73. var rc_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Centre);
  74. var lb_stringformat = StringFormat(StringAlignment.Near, StringAlignment.Far);
  75. var cb_stringformat = StringFormat(StringAlignment.Centre, StringAlignment.Far);
  76. var rb_stringformat = StringFormat(StringAlignment.Far, StringAlignment.Far);
  77. // }}
  78.  
  79. // Use with GdiDrawText()
  80. // {{
  81. var DT_LEFT = 0x00000000;
  82. var DT_RIGHT = 0x00000002;
  83. var DT_TOP = 0x00000000;
  84. var DT_CENTER = 0x00000001;
  85. var DT_VCENTER = 0x00000004;
  86. var DT_WORDBREAK = 0x00000010;
  87. var DT_CALCRECT = 0x00000400;
  88. var DT_NOPREFIX = 0x00000800;
  89. var DT_END_ELLIPSIS = 0x00008000;
  90. // }}
  91.  
  92. //{{
  93. // IO Mode
  94. var ForReading = 1;
  95. var ForWriting = 2;
  96. var ForAppending = 8;
  97. //}}
  98.  
  99. //{{
  100. // Paths
  101. var lyrics_dir1 = fb.Titleformat("$replace($replace(%path%,%filename_ext%,),\,\\)");
  102. var lyrics_dir2 =  fb.FoobarPath + "lyrics\\";
  103. //}}
  104.  
  105. //{{
  106. // new objects
  107. sentence = function () {
  108.     this.timer = 0;
  109.     this.text = "";
  110.     this.total_lines = 0;
  111.     this.ante_lines = 0;
  112. }
  113. //}}
  114.  
  115. function RGBA(r, g, b, a) {
  116.     return ((a << 24) | (r << 16) | (g << 8) | (b));
  117. }
  118.  
  119. // ================================================/ TF
  120. var len = fb.Titleformat("%length%");
  121. var elap = fb.TitleFormat("%playback_time%");
  122. var remain = fb.TitleFormat("%playback_time_remaining%");
  123. var len_seconds = fb.Titleformat("%length_seconds%");
  124. var elap_seconds = fb.TitleFormat("%playback_time_seconds%");
  125. var remain_seconds = fb.Titleformat("%playback_time_remaining_seconds%");
  126. var artist = fb.Titleformat("$replace(%artist%,'/','_')");
  127. var title = fb.Titleformat("%title%");
  128. var lyrics = fb.TitleFormat("[$if2(%LYRICS%,$if2(%LYRIC%,$if2(%UNSYNCED LYRICS%,%UNSYNCED LYRIC%)))]");
  129.  
  130. // ================================================/ Globals
  131. var g_font = gdi.Font("segoe ui", FONT_SIZE, 1);
  132. var g_playtimer;
  133. var g_timer_abs;
  134. var g_metadb;
  135. var ww = 0, wh = 0;
  136.  
  137. var g_fso = new ActiveXObject("Scripting.FileSystemObject");
  138. var g_file = null;
  139. var g_tab = Array();
  140. var g_scroll=0;
  141. var g_lyrics_path;
  142. var g_lyrics_filename;
  143. var g_lyrics_status;
  144. var focus=0;
  145. var focus_next=0;
  146. var g_bg_colour;
  147. var g_ovbg_highlightcolour;
  148. var g_txt_normalcolour;
  149. var g_txt_highlightcolour;
  150. var g_txt_shadowcolour;
  151. var g_txt_glowcolour;
  152. var g_dither_shadowcolour;
  153. var centiemes = 0;
  154. var g_is_scrolling = false;
  155. var g_multi_balise = false;
  156. var g_balise_total;
  157. var g_balise_char_offset = 10;
  158. var g_tab_length;
  159. var g_txt_align;
  160.  
  161. var midpoint;
  162. var pos;
  163.  
  164. // START
  165. function on_size() {
  166.     var k;
  167.     ww = window.Width;
  168.     wh = window.Height;
  169.     g_metadb = fb.IsPlaying ? fb.GetNowPlaying() : false;
  170.     midpoint = wh / 2 - LINE_HEIGHT / 2;
  171.     // colour definitions
  172.     g_bg_colour = eval(BG_DEFAULT_COLOUR);
  173.     g_ovbg_highlightcolour = eval(BG_FOCUS_COLOUR);
  174.     g_txt_normalcolour = eval(TXT_NORMAL_COLOUR);
  175.     g_txt_highlightcolour = eval(TXT_FOCUS_COLOUR);
  176.     g_txt_shadowcolour = RGBA(000, 000, 000, 240);
  177.     g_txt_glowcolour = eval(TXT_GLOW_COLOUR);
  178.     g_dither_shadowcolour = RGBA(000, 000, 000, 200);
  179.    
  180.     g_playtimer && window.KillTimer(g_playtimer);
  181.  
  182.     if(fb.IsPlaying||fb.IsPaused) {
  183.         g_scroll=0;
  184.         g_is_scrolling = false;
  185.         get_lyrics();
  186.         change_focus();
  187.         k = g_tab[focus].ante_lines * LINE_HEIGHT;
  188.         if(g_lyrics_status>0) {
  189.             pos = midpoint - k;
  190.             g_playtimer = window.CreateTimerInterval(PLAYTIMER_VALUE);
  191.             g_timer_abs = 4;
  192.         } else {
  193.             delta = (g_tab[g_tab.length-1].ante_lines + g_tab[g_tab.length-1].total_lines);
  194.             pos = Math.round((wh / 2) - (delta * LINE_HEIGHT / 2));
  195.         }
  196.     }
  197.  
  198. }
  199.  
  200. function on_paint(gr) {
  201.     BG_DRAW && gr.FillSolidRect(0, 0, ww, wh, g_bg_colour);
  202.     if(fb.IsPlaying||fb.IsPaused) {
  203.         show_lyrics(gr, g_tab, pos);
  204.         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);
  205.     }
  206.     DITHER && gr.FillGradRect(-20, 0, ww+40, 9, 90, g_dither_shadowcolour, RGBA(0,0,0,0));
  207.     DITHER && gr.FillGradRect(-20, wh-8, ww+40, 8, 270, g_dither_shadowcolour, RGBA(0,0,0,0));
  208. }
  209.  
  210. function on_mouse_lbtn_dblclk(x, y, mask) {
  211.     on_size();
  212. }
  213.  
  214. function on_mouse_leave() {
  215.     window.Repaint();
  216. }
  217.  
  218. function on_playback_time(time) {
  219.     // at each new seconde, centiemes is reset to 0 (Increment on timer every 100ms)
  220.     centiemes = 0;
  221.     if(g_lyrics_status==0) {
  222.         if(elap_seconds.Eval()==3) {
  223.             on_size();
  224.         }
  225.         window.Repaint();
  226.     }
  227. }
  228.  
  229. function on_playback_new_track(info) {
  230.     g_metadb = fb.IsPlaying ? fb.GetNowPlaying() : false;
  231.     g_playtimer && window.KillTimer(g_playtimer);
  232.     pos=0;
  233.     g_scroll = 0;
  234.     g_is_scrolling = false;
  235.     get_lyrics();
  236.     change_focus();
  237.     if(g_lyrics_status>0) {
  238.         g_playtimer = window.CreateTimerInterval(PLAYTIMER_VALUE);
  239.         g_timer_abs = 4;
  240.     }
  241. }
  242.  
  243. function on_playback_seek(time) {
  244.     var k;
  245.     if(g_lyrics_status>0) {
  246.         on_size();
  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.     var t1 = elap_seconds.Eval() * 100 + centiemes;
  272.     var t2 = len_seconds.Eval() * 100;
  273.     var p1, p2, p3;
  274.     if(t1>t2-100) {
  275.         g_playtimer && window.KillTimer(g_playtimer);
  276.     }
  277.     if(g_playtimer) {
  278.         if(g_playtimer.ID == id) {
  279.             if(!g_is_scrolling && t1>=g_tab[focus_next].timer) {
  280.             //if(t1>=g_tab[focus_next].timer) {
  281.                 p1 = g_tab[focus].ante_lines*LINE_HEIGHT;
  282.                 p2 = g_tab[focus_next].ante_lines*LINE_HEIGHT;
  283.                 //p3 = (g_tab[focus_next].total_lines-1)*LINE_HEIGHT;
  284.                 g_scroll = (p2 - p1);
  285.                 change_focus();
  286.                 g_is_scrolling = true;
  287.             }
  288.             g_timer_abs--;
  289.             if (g_scroll>0) {
  290.                 pos -= g_scroll<SCROLL_STEP?g_scroll:SCROLL_STEP;
  291.                 g_scroll -= g_scroll<SCROLL_STEP?g_scroll:SCROLL_STEP;
  292.                 if(g_timer_abs<=1) {
  293.                     g_timer_abs = 4;
  294.                     window.Repaint();
  295.                 }
  296.             } else {
  297.                 g_timer_abs = 4;
  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(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>30) {
  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() {
  530.     var i, j, t1;
  531.     t1 = elap_seconds.Eval()*100+centiemes;
  532.     if(g_lyrics_status>0) {
  533.         // search line index just after actual timer
  534.         for(i=focus;i<g_tab.length;i++) {
  535.             if(g_tab[i].timer>t1) break;
  536.         }
  537.         focus_next=i;
  538.         focus = (i>0)?i-1:0;
  539.         // 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)
  540.         if(focus>0) {
  541.             for(i=0;i<focus;i++) {
  542.                 if(g_tab[i].timer==g_tab[focus].timer) {
  543.                     focus = i;
  544.                     break;
  545.                 }
  546.             }
  547.         }
  548.     }
  549. }
  550.  
  551. function calc_lines(ctab) {
  552.     var i, j;
  553.     var padx = 0;
  554.     var tmp_img;
  555.     var gp;
  556.     var lineh;
  557.     g_tab_length = 0;
  558.     if(ww==0) return ctab; // test to avoid errors if panel is hidden (ww=0)
  559.     tmp_img = gdi.CreateImage(ww-(H_PADDING*2)-padx, 100);
  560.     gp = tmp_img.GetGraphics();
  561.     for(i=0;i<ctab.length;i++) {
  562.         // calc sentence #lines to display / window.width
  563.         lineh = gp.MeasureString(ctab[i].text, g_font, 0, 0, ww-(H_PADDING*2)-padx, wh).Height;
  564.         ctab[i].total_lines = (lineh/LINE_HEIGHT) > Math.floor(lineh/LINE_HEIGHT) ? Math.floor(lineh/LINE_HEIGHT) + 1 : Math.floor(lineh/LINE_HEIGHT)  ;
  565.         ctab[i].ante_lines = 0;
  566.         for(j=0;j<i;j++) {
  567.             ctab[i].ante_lines += ctab[j].total_lines;
  568.         }
  569.         g_tab_length += ctab[i].total_lines;
  570.     }
  571.     CollectGarbage();
  572.     return ctab;
  573. }
  574.  
  575. function sort_tab(tab2sort) {
  576.     var tab = Array();
  577.     var i, j;
  578.     var tmp = new sentence;
  579.     var smallest = 0;
  580.     for(i=0;i<tab2sort.length;i++) {
  581.         for(j=i;j<tab2sort.length;j++) {
  582.             if(tab2sort[i].timer > tab2sort[j].timer) {
  583.                 tmp = tab2sort[i];
  584.                 tab2sort[i] = tab2sort[j];
  585.                 tab2sort[j] = tmp;
  586.             }
  587.         }
  588.         tab.push(tab2sort[i]);
  589.     }
  590.     return tab;
  591. }
  592.  
  593. function remove_enhanced_balises(str) {
  594.     var i;
  595.     var chr1, chr2;
  596.     var new_str="";
  597.     for(i=0;i<str.length;i++) {
  598.         chr1 = str.substring(i, i+1);
  599.         if(i+10<=str.length) chr2 = str.substring(i+9, i+10); else chr2=null;
  600.         if(chr1=="<" && chr2==">") {
  601.             i = i + 10 - 1;
  602.         } else {
  603.             new_str = new_str + chr1;
  604.         }
  605.     }
  606.     return new_str;
  607. }
  608.  
  609. function ts_analyzer(str) {
  610.     var i, j, ch,  ts_len;
  611.     var str2 = "";
  612.     var state=0;
  613.     var deb = -1;
  614.     var fin = -1;
  615.     var sep1 = -1;
  616.     var sep2 = -1;
  617.     var suite=0;
  618.     for(i=0;i<str.length;i++) {
  619.         ch = str.substring(i, i+1);
  620.         switch(state) {
  621.         case 0:            
  622.             if(ch=="[" && IsNumeric(str.substring(i+1, i+2))) {
  623.                 state=1;
  624.                 deb=i;
  625.                 fin=-1;
  626.             }
  627.             break;
  628.         case 1:
  629.             if(deb>=0 && ch==":") {
  630.                 state=2;
  631.                 sep1=i;
  632.             }
  633.             if(i>deb+3) {
  634.                 deb=-1;
  635.                 fin=-1;
  636.                 sep1=-1;
  637.                 sep2=-1;
  638.                 state=0;
  639.             }
  640.             break;
  641.         case 2:
  642.             if(sep1>=0 && (ch==":" || ch==".")) {
  643.                 state=3;
  644.                 sep2=i;
  645.             }
  646.             if(sep1>=0 && sep2==-1 && ch=="]") {
  647.                 state=4;
  648.                 fin=i;
  649.             }
  650.             if(i>sep1+3) {
  651.                 deb=-1;
  652.                 fin=-1;
  653.                 sep1=-1;
  654.                 sep2=-1;
  655.                 state=0;
  656.             }
  657.             break;
  658.         case 3:
  659.             if(deb>=0 && ch=="]") {
  660.                 state=4;
  661.                 if(i==str.length-1) {
  662.                     str=str+" ";
  663.                 }
  664.                 fin=i;
  665.             }
  666.             if(i>deb+10) {
  667.                 deb=-1;
  668.                 fin=-1;
  669.                 sep1=-1;
  670.                 sep2=-1;
  671.                 state=0;
  672.             }
  673.             break;
  674.         case 4:
  675.             ts_len=fin-deb+1;
  676.             switch(ts_len) {
  677.                 case 6:
  678.                     str2 = str2 + "[0" + str.substring(deb+1,deb+2) + ":" + str.substring(deb+3, deb+5) + ".00]";
  679.                     break;
  680.                 case 7:
  681.                     str2 = str2 + str.substring(deb,deb+6) + ".00]";
  682.                     break;
  683.                 case 9:
  684.                     str2 = str2 + "[0" + str.substring(deb+1,deb+2) + ":" + str.substring(deb+3, deb+5) + "." + str.substring(deb+6, deb+8) + "]";
  685.                     break;
  686.                 case 10:
  687.                     if(sep1==deb+2) {
  688.                         str2 = str2 + "[0" + str.substring(deb+1,deb+2) + ":" + str.substring(deb+3, deb+5) + "." + str.substring(deb+6, deb+8) + "]";
  689.                     } else {
  690.                         str2 = str2 + str.substring(deb,deb+10);
  691.                     }
  692.                     break;
  693.                 case 11:
  694.                     str2 = str2 + str.substring(deb,deb+9) + "]";
  695.                     break;
  696.             }
  697.             j += 10;
  698.             if(str.substring(fin+1,fin+2)=="[") {
  699.                 suite = 1;
  700.                 i = fin;
  701.                 deb = -1;
  702.                 fin = -1;
  703.                 sep1 = -1;
  704.                 sep2 = -1;
  705.                 state = 0;
  706.             } else {
  707.                 suite = -1;
  708.                 i = str.length - 1;
  709.                 str2 = str2 + str.substring(fin+1, str.length);
  710.             }
  711.             break;      
  712.         }
  713.     }
  714.     return str2;
  715. }
  716.  
  717. function IsNumeric(str) {
  718.     var ValidChars = "0123456789.";
  719.     for (i = 0; i < str.length; i++) {
  720.         if (ValidChars.indexOf(str.charAt(i)) == -1) {
  721.             return false;
  722.         }
  723.     }
  724.     return true;
  725. }
  726.  
  727. function IsTimestamped(str) {
  728.     var ValidChars = "[0123456789:.]";
  729.     var count = 0;
  730.     for (i = 0; i < (str.length>10?10:str.length); i++) {
  731.         if (ValidChars.indexOf(str.charAt(i)) >=0) {
  732.             count++;
  733.         }
  734.     }
  735.     if(count>=6 && count <=11) {
  736.         return true;
  737.     } else {
  738.         return false;
  739.     }
  740. }
  741.  
  742. function check_file(path, filename) {
  743.     if(file_exists(path+filename+".lrc")) {
  744.         g_lyrics_filename  = filename+".lrc";
  745.         g_lyrics_path = path;
  746.         return true;
  747.     } else {
  748.         if(file_exists(path+filename+".txt")) {
  749.             g_lyrics_filename  = filename+".txt";
  750.             g_lyrics_path = path;
  751.             return true;
  752.         }
  753.     }
  754.     return false;
  755. }
  756.  
  757. function get_lyrics() {
  758.     var i, count, delta, tag;
  759.     var tpath = Array(lyrics_dir1.EvalWithMetadb(g_metadb), lyrics_dir2);
  760.     var tfilename= Array(artist.Eval() + " -" + title.Eval(), artist.Eval() + " - " + title.Eval());
  761.     var bool_tag = false;
  762.     var bool_file = false;
  763.        
  764.     // reset lyrics tab
  765.     g_lyrics_status = 0;
  766.     if(g_tab.length>0) g_tab.splice(0, g_tab.length);
  767.     pos = midpoint;
  768.     focus = 0;
  769.     window.Repaint();
  770.        
  771.     // check TAGs
  772.     tag = lyrics.Eval();
  773.     if(tag.length>0) {
  774.         bool_tag = true;
  775.         if(tag.substring(0,1)=="[") g_lyrics_status = 1; else g_lyrics_status = 2;
  776.     } else {
  777.         // check files
  778.         i = 0;
  779.         while(!bool_file && i<2) {
  780.             j = 0;
  781.             while(!bool_file && j<2) {
  782.                 bool_file = check_file(tpath[i], tfilename[j]);
  783.                 j++;
  784.             }
  785.             i++;
  786.         }
  787.     }
  788.     // if lyrics found
  789.     if(bool_tag || bool_file) {
  790.         if(bool_tag) {
  791.             g_tab = parse_tag(tag, "[");
  792.         } else {
  793.             g_tab = load_file(g_lyrics_path, g_lyrics_filename);
  794.         }
  795.     }  else {
  796.         g_tab = load_track_info();
  797.         delta = (g_tab[g_tab.length-1].ante_lines + g_tab[g_tab.length-1].total_lines);
  798.         pos = (wh / 2) - (delta * LINE_HEIGHT / 2);
  799.     }
  800.  
  801.     if(g_lyrics_status==2) {
  802.         for(i=0;i<g_tab.length-1;i++) {
  803.             g_tab[i].timer = i * Math.floor(len_seconds.Eval() * 100 / g_tab.length);
  804.         }
  805.     }
  806.    
  807.     // dump
  808.     for(i=0;i<g_tab.length;i++) {
  809.         //fb.trace("i="+i+" // timer="+g_tab[i].timer+" // txt="+g_tab[i].text+" // ante="+g_tab[i].ante_lines+" // nbl="+g_tab[i].total_lines);
  810.     }
  811. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement