Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Recent Posts
1
3rd Party Plugins - (fb2k) / Re: JScript Panel script discussion/help
Last post by eurekagliese -
Code: [Select]
var x = (panel.w - (bs * 7)) / 2

You have 8 buttons so that's why it is off centre.  :D

And yay, the SVG parser which takes around 1.5MB (or 25%) of the overall DLL size is getting some use.

edit: you should not comment this out...

Code: [Select]
// function on_playback_time() {
// text.playback_time();
// window.RepaintRect(0, bottom_y, panel.w, panel.h - bottom_y);
// }

People customising their own text may want %playback_time% etc during playback. There is a toggle on the right click menu to turn per second updates on or off.

Ah that's why it's off center.
I didn't know the SVG parser was that big.

Thanks again for the correction and updates Marc
2
MP3 - Tech / Re: Making MP3's sound more stereo
Last post by Klymins -
@Arachnid79 Does they modify the file?
Why would they modify the file?

The file contains as much spacial information as there is ever going to be.  All you can do is process the two channels to remove any commonality and so create the impression of greater L-R separation.  This is a DSP effect applied on playback.  If you wanted to bake that into the file so that a player which does not have DSP could reproduce the same spatial effect, then yes it would be necessary to take the DSP output and re-encode it.

I think you might be confusing this with the difference between full stereo and joint stereo.  In full stereo, L and R are separately encoded.  With joint stereo, L+R and L-R are separately encoded.  Joint stereo provides more efficient encoding because typically L-R is a lesser signal than L or R separately.  The actual output from decoding joint stereo is no different than decoding full stereo.  There is very little reason not to use joint stereo.

Why you assumed I don't know joint stereo? I know what is it and that's why I use joint stereo instead of LR stereo. Also, as joint stereo can be encoded as MS stereo, I think expanding it can be achieved by simply amplifying the S channel. I just don't know how can I do that. For me, the only reason to use LR stereo is making encoding and decoding faster, and I don't need it right now.

Hello. Is there a way to make the stereo width of a joint stereo MP3 file wider without decoding and re-encoding it?
When it comes to files with the lowest bit rate and 11 kHz sampling rate, any ‘enhancer’ will also amplify the coding artefacts that are unavoidable at your bit rates.
I just wonder what this process will sound like. I will use it if I like it.

By the way, I'm targeting 32kbps.
3
3rd Party Plugins - (fb2k) / Re: JScript Panel script discussion/help
Last post by marc2k3 -
This removes a lot of dead code, fixes the button count and improves the search button to find all tracks by the current artist. I've also uncommented the code that broke per second updates.

Code: [Select]
// ==PREPROCESSOR==
// @name "Text Display + Album Art + Custom SVG and PNG Buttons"
// @author "marc2003 / eurekagliese"
// @import "%fb2k_component_path%helpers.txt"
// @import "%fb2k_component_path%samples\js\lodash.min.js"
// @import "%fb2k_component_path%samples\js\common.js"
// @import "%fb2k_component_path%samples\js\panel.js"
// @import "%fb2k_component_path%samples\js\albumart.js"
// @import "%fb2k_component_path%samples\js\text_display.js"
// ==/PREPROCESSOR==

// https://jscript-panel.github.io/gallery/text-display/

//.svg files
var google = utils.LoadSVG(fb.ProfilePath + 'images\\google.svg');
var youtube = utils.LoadSVG(fb.ProfilePath + 'images\\youtube.svg');
var spotify = utils.LoadSVG(fb.ProfilePath + 'images\\spotify.svg');
var wikipedia = utils.LoadSVG(fb.ProfilePath + 'images\\wikipedia.svg');
var lastfm = utils.LoadSVG(fb.ProfilePath + 'images\\lastfm.svg');
var search = utils.LoadSVG(fb.ProfilePath + 'images\\search.svg');
var settings = utils.LoadSVG(fb.ProfilePath + 'images\\settings.svg');
//.png files
var discogs = utils.LoadImage(fb.ProfilePath + 'images\\discogs.png');

var tfo = {
artist: fb.TitleFormat('%artist%'),
title: fb.TitleFormat('%title%'),
}

var panel = new _panel({ custom_background : true });
var albumart = new _albumart(0, 0, 0, 0);
var text = new _text_display(LM, 0, 0, 0, true);

var colours = {
white : RGB(255, 255, 255),
};

var font = CreateFontString('Segoe UI', 12);
var buttons = new _buttons();
var bs = _scale(24);
var bottom_y = 0;

buttons.update = function () {
var x = (panel.w - (bs * 8)) / 2
var y = bottom_y;
this.buttons.google = new _button(x, y, bs, bs, { img : google }, null, function () { utils.Run('https://www.google.com/search?tbm=isch&q=' + encodeURIComponent(tfo.artist.Eval() + " " + tfo.title.Eval())); }, 'Google');
this.buttons.youtube = new _button(x + bs, y, bs, bs, { img : youtube }, null, function () { utils.Run('http://www.youtube.com/results?search_query=' + encodeURIComponent(tfo.artist.Eval() + " " + tfo.title.Eval())); }, 'youtube');
this.buttons.spotify = new _button(x + (bs * 2), y, bs, bs, { img : spotify}, null, function () { utils.Run('https://open.spotify.com/search/' + encodeURIComponent(tfo.artist.Eval() + " " + tfo.title.Eval())); }, 'spotify');
this.buttons.wikipedia = new _button(x + (bs * 3), y, bs, bs, { img : wikipedia }, null, function () { utils.Run('http://en.wikipedia.org/wiki/Special:Search?search=' + encodeURIComponent(tfo.artist.Eval()));  }, 'wikipedia');
this.buttons.lastfm = new _button(x + (bs * 4), y, bs, bs, { img : lastfm }, null, function () { utils.Run('https://www.last.fm/search?q=' + encodeURIComponent(tfo.artist.Eval()));  }, 'lastfm');
this.buttons.discogs = new _button(x + (bs * 5), y, bs, bs, { img : discogs }, null, function () { utils.Run('http://www.discogs.com/search?q=' + encodeURIComponent(tfo.artist.Eval()));  }, 'discogs');
this.buttons.search = new _button(x + (bs * 6), y, bs, bs, { img : search }, null, function () { fb.ShowLibrarySearchUI('artist IS ' + tfo.artist.Eval()); }, 'Search');
this.buttons.preferences = new _button(x + (bs * 7), y, bs, bs, { img : settings}, null, function () { fb.ShowPreferences(); }, 'Preferences');
}

panel.item_focus_change();

function on_colours_changed() {
panel.colours_changed();
text.refresh(true);
}

function on_font_changed() {
panel.font_changed();
text.refresh(true);
}

function on_item_focus_change() {
if (panel.selection.value == 0 && fb.IsPlaying) return;
panel.item_focus_change();
}

function on_metadb_changed(handles, fromhook) {
if (!fromhook) {
albumart.metadb_changed();
}
text.metadb_changed();
}

function on_mouse_lbtn_dblclk(x, y) {
if (albumart.img && albumart.containsXY(x, y)) {
panel.metadb.ShowAlbumArtViewer();
}
}

function on_mouse_lbtn_up(x, y) {
if (buttons.lbtn_up(x, y)) {
return;
}
text.lbtn_up(x, y);
}

function on_mouse_leave() {
buttons.leave();
}

function on_mouse_move(x, y) {
text.move(x, y);
buttons.move(x, y);

_.forEach(buttons.buttons, function (button) {
if (button.containsXY(x, y)) {
window.SetCursor(IDC_HAND);
return;
}
});
}

function on_mouse_rbtn_up(x, y) {
return panel.rbtn_up(x, y, text);
}

function on_mouse_wheel(s) {
if (seekbar.wheel(s)) {
return;
}
text.wheel(s);
}

function on_paint(gr) {
panel.paint(gr);
text.paint(gr);
buttons.paint(gr);
}

function on_playback_dynamic_info_track(type) {
if (type == 0) text.metadb_changed();
else if (type == 1) albumart.metadb_changed();
}

function on_playback_new_track() {
panel.item_focus_change();
}

function on_playback_pause() {
text.refresh();
buttons.update();
window.Repaint();
}

function on_playback_starting() {
buttons.update();
window.Repaint();
}

function on_playback_stop(reason) {
if (reason != 2) {
panel.item_focus_change();
}

buttons.update();
window.Repaint();
}

function on_playback_time() {
text.playback_time();
}

function on_playlist_items_added() {
text.refresh();
}

function on_playlist_items_removed() {
text.refresh();
}

function on_playlist_items_reordered() {
text.refresh();
}

function on_playlist_switch() {
on_item_focus_change();
}

function on_playlists_changed() {
text.refresh();
}

function on_size() {
panel.size();
text.size();

bottom_y = panel.h - _scale(36);
buttons.update();
}

edit: requires images from this post...

https://hydrogenaud.io/index.php/topic,110516.msg1048037.html#msg1048037

edit2: script edited to remove more dead callbacks
4
foobar2000 mobile / Re: Opus ReplayGain/Normalization on fb2k iOS mobile 1.5.2
Last post by Case -
This is not foobar2000 mobile related. Your files are missing Album based gain tag, which should be stored in tag field R128_ALBUM_GAIN. If you look at your files for example with desktop foobar2000 you'll see that ReplayGain album gain field is empty.
ReplayGain specs state that if the other gain field is empty the correct behavior is to use the other gain value, so ReplayGain-wise things work exactly as expected.

Back in the super early Opus days before there was R128_ALBUM_GAIN tag the header gain worked as an album gain fallback in this scenario. But not anymore as there is a proper tag for it now.

It is intentional that when ReplayGain is off the header gain is ignored against the specs. The user has to have the power to get the original signal level out from any audio format.

Easiest fix for you issues, if you insist on using Opus, is to ReplayGain scan the files in foobar2000 so they get all the gain related tags.
6
3rd Party Plugins - (fb2k) / Re: JScript Panel script discussion/help
Last post by ApacheReal -
Thank you very much for the update and the guide @marc2k3
---
This is a composite image of an image from the foo_uie_webview thread, so I don't know. Sorry.
No worries, mate. With latest JSP update, we can also replicate it on a text display.
The script and image files with the PNG and SVG icons are available below.
In your foobar config folder, extract it to the images folder.
Just modify the link on script or the icons as needed.


Code: [Select]
// ==PREPROCESSOR==
// @name "Text Display + Album Art + Custom SVG and PNG Buttons"
// @author "marc2003"
// @import "%fb2k_component_path%helpers.txt"
// @import "%fb2k_component_path%samples\js\lodash.min.js"
// @import "%fb2k_component_path%samples\js\common.js"
// @import "%fb2k_component_path%samples\js\panel.js"
// @import "%fb2k_component_path%samples\js\albumart.js"
// @import "%fb2k_component_path%samples\js\text_display.js"
// @import "%fb2k_component_path%samples\js\seekbar.js"
// ==/PREPROCESSOR==

// https://jscript-panel.github.io/gallery/text-display/

//.svg files
var google = utils.LoadSVG(fb.ProfilePath + 'images\\google.svg');
var youtube = utils.LoadSVG(fb.ProfilePath + 'images\\youtube.svg');
var spotify = utils.LoadSVG(fb.ProfilePath + 'images\\spotify.svg');
var wikipedia = utils.LoadSVG(fb.ProfilePath + 'images\\wikipedia.svg');
var lastfm = utils.LoadSVG(fb.ProfilePath + 'images\\lastfm.svg');
var search = utils.LoadSVG(fb.ProfilePath + 'images\\search.svg');
var settings = utils.LoadSVG(fb.ProfilePath + 'images\\settings.svg');
//.png files
var discogs = utils.LoadImage(fb.ProfilePath + 'images\\discogs.png');

var tfo = {
artist: fb.TitleFormat('%artist%'),
title: fb.TitleFormat('%title%'),
// playback_time : fb.TitleFormat('[%playback_time%]'),
// length : fb.TitleFormat('$if2(%length%,LIVE)'),
}

var panel = new _panel({ custom_background : true });
var albumart = new _albumart(0, 0, 0, 0);
var text = new _text_display(LM, 0, 0, 0, true);
var seekbar = new _seekbar(0, 0, 0, 0);

var colours = {
slider_background : RGB(160, 160, 160),
white : RGB(255, 255, 255),
contrast : RGB(196, 30, 35),
};

var font = CreateFontString('Segoe UI', 12);
var buttons = new _buttons();
var bs = _scale(24);
var bottom_y = 0;

buttons.update = function () {
var x = (panel.w - (bs * 7)) / 2
var y = seekbar.y + _scale(12);
this.buttons.google = new _button(x, y, bs, bs, { img : google }, null, function () { utils.Run('https://www.google.com/search?tbm=isch&q=' + encodeURIComponent(tfo.artist.Eval() + " " + tfo.title.Eval())); }, 'Google');
this.buttons.youtube = new _button(x + bs, y, bs, bs, { img : youtube }, null, function () { utils.Run('http://www.youtube.com/results?search_query=' + encodeURIComponent(tfo.artist.Eval() + " " + tfo.title.Eval())); }, 'youtube');
this.buttons.spotify = new _button(x + (bs * 2), y, bs, bs, { img : spotify}, null, function () { utils.Run('https://open.spotify.com/search/' + encodeURIComponent(tfo.artist.Eval() + " " + tfo.title.Eval())); }, 'spotify');
this.buttons.wikipedia = new _button(x + (bs * 3), y, bs, bs, { img : wikipedia }, null, function () { utils.Run('http://en.wikipedia.org/wiki/Special:Search?search=' + encodeURIComponent(tfo.artist.Eval()));  }, 'wikipedia');
this.buttons.lastfm = new _button(x + (bs * 4), y, bs, bs, { img : lastfm }, null, function () { utils.Run('https://www.last.fm/search?q=' + encodeURIComponent(tfo.artist.Eval()));  }, 'lastfm');
this.buttons.discogs = new _button(x + (bs * 5), y, bs, bs, { img : discogs }, null, function () { utils.Run('http://www.discogs.com/search?q=' + encodeURIComponent(tfo.artist.Eval()));  }, 'discogs');
this.buttons.search = new _button(x + (bs * 6), y, bs, bs, { img : search }, null, function () { fb.RunMainMenuCommand('Library/Search'); }, 'Library Search');
this.buttons.preferences = new _button(x + (bs * 7), y, bs, bs, { img : settings}, null, function () { fb.ShowPreferences(); }, 'Preferences');
}

panel.item_focus_change();

function on_colours_changed() {
panel.colours_changed();
text.refresh(true);
}

function on_font_changed() {
panel.font_changed();
text.refresh(true);
}

function on_item_focus_change() {
if (panel.selection.value == 0 && fb.IsPlaying) return;
panel.item_focus_change();
}

function on_metadb_changed(handles, fromhook) {
if (!fromhook) {
albumart.metadb_changed();
}
text.metadb_changed();
}

function on_mouse_lbtn_dblclk(x, y) {
if (albumart.img && albumart.containsXY(x, y)) {
panel.metadb.ShowAlbumArtViewer();
}
}

function on_mouse_lbtn_down(x, y) {
seekbar.lbtn_down(x, y);
}

function on_mouse_lbtn_up(x, y) {
if (seekbar.lbtn_up(x, y)) {
return;
}
if (buttons.lbtn_up(x, y)) {
return;
}
text.lbtn_up(x, y);
}

function on_mouse_leave() {
buttons.leave();
}

function on_mouse_move(x, y) {
window.SetCursor(buttons.buttons.google.containsXY(x, y) ? IDC_HAND
: buttons.buttons.youtube.containsXY(x, y) ? IDC_HAND
: buttons.buttons.spotify.containsXY(x, y) ? IDC_HAND
: buttons.buttons.wikipedia.containsXY(x, y) ? IDC_HAND
: buttons.buttons.lastfm.containsXY(x, y) ? IDC_HAND
: buttons.buttons.discogs.containsXY(x, y) ? IDC_HAND
: buttons.buttons.search.containsXY(x, y) ? IDC_HAND
: buttons.buttons.preferences.containsXY(x, y) ? IDC_HAND
: IDC_ARROW);

if (seekbar.move(x, y)) {
return;
}
if (buttons.move(x, y)) {
return;
}
text.move(x, y);
}

function on_mouse_rbtn_up(x, y) {
// if (buttons.buttons.stop.containsXY(x, y)) {
// fb.StopAfterCurrent = !fb.StopAfterCurrent;
// return true;
// }
return panel.rbtn_up(x, y, text);
}

function on_mouse_wheel(s) {
if (seekbar.wheel(s)) {
return;
}
text.wheel(s);
}

function on_paint(gr) {
panel.paint(gr);
text.paint(gr);
buttons.paint(gr);

// gr.FillRoundedRectangle(seekbar.x, seekbar.y, seekbar.w, seekbar.h, _scale(2), _scale(2), colours.slider_background);

// if (fb.IsPlaying) {
// var time_width = seekbar.x - _scale(12);
// gr.WriteText(tfo.playback_time.Eval(), font, colours.white, 0, bottom_y, time_width, _scale(12), 1, 2);
// gr.WriteText(tfo.length.Eval(), font, colours.white, seekbar.x + seekbar.w + _scale(12), bottom_y, time_width, _scale(12), 0, 2);

// if (fb.PlaybackLength > 0) {
// gr.FillEllipse(seekbar.x + seekbar.pos(), seekbar.y + _scale(3), _scale(6), _scale(6), colours.white);
// }
// }
}

function on_playback_order_changed() {
buttons.update();
window.Repaint();
}

function on_playback_dynamic_info_track(type) {
if (type == 0) text.metadb_changed();
else if (type == 1) albumart.metadb_changed();
}

function on_playback_new_track() {
panel.item_focus_change();
}

function on_playback_pause() {
text.refresh();
buttons.update();
window.Repaint();
}

function on_playback_seek() {
seekbar.playback_seek();
}

function on_playback_starting() {
buttons.update();
window.Repaint();
}

function on_playback_stop(reason) {
if (reason != 2) {
panel.item_focus_change();
}

buttons.update();
window.Repaint();
}

// function on_playback_time() {
// text.playback_time();
// window.RepaintRect(0, bottom_y, panel.w, panel.h - bottom_y);
// }

function on_playlist_items_added() {
text.refresh();
}

function on_playlist_items_removed() {
text.refresh();
}

function on_playlist_items_reordered() {
text.refresh();
}

function on_playlist_stop_after_current_changed() {
buttons.update();
window.Repaint();
}

function on_playlist_switch() {
on_item_focus_change();
}

function on_playlists_changed() {
text.refresh();
}

function on_size() {
panel.size();
text.size();

seekbar.x = _scale(60);
seekbar.y = panel.h - _scale(44);
seekbar.w = panel.w - (seekbar.x * 2);
seekbar.h  = _scale(6);

bottom_y = seekbar.y - _scale(4);
buttons.update();
}
Logo discogs
https://postimg.cc/LJxJnRDQ
7
3rd Party Plugins - (fb2k) / Re: JScript Panel script discussion/help
Last post by marc2k3 -
Code: [Select]
var x = (panel.w - (bs * 7)) / 2

You have 8 buttons so that's why it is off centre.  :D

And yay, the SVG parser which takes around 1.5MB (or 25%) of the overall DLL size is getting some use.

edit: you should not comment this out...

Code: [Select]
// function on_playback_time() {
// text.playback_time();
// window.RepaintRect(0, bottom_y, panel.w, panel.h - bottom_y);
// }

People customising their own text may want %playback_time% etc during playback. There is a toggle on the right click menu to turn per second updates on or off.
9
3rd Party Plugins - (fb2k) / Re: JScript Panel script discussion/help
Last post by eurekagliese -
Thank you very much for the update and the guide @marc2k3
---
This is a composite image of an image from the foo_uie_webview thread, so I don't know. Sorry.
No worries, mate. With latest JSP update, we can also replicate it on a text display.
The script and image files with the PNG and SVG icons are available below.
In your foobar config folder, extract it to the images folder.
Just modify the link on script or the icons as needed.


Code: [Select]
// ==PREPROCESSOR==
// @name "Text Display + Album Art + Custom SVG and PNG Buttons"
// @author "marc2003"
// @import "%fb2k_component_path%helpers.txt"
// @import "%fb2k_component_path%samples\js\lodash.min.js"
// @import "%fb2k_component_path%samples\js\common.js"
// @import "%fb2k_component_path%samples\js\panel.js"
// @import "%fb2k_component_path%samples\js\albumart.js"
// @import "%fb2k_component_path%samples\js\text_display.js"
// @import "%fb2k_component_path%samples\js\seekbar.js"
// ==/PREPROCESSOR==

// https://jscript-panel.github.io/gallery/text-display/

//.svg files
var google = utils.LoadSVG(fb.ProfilePath + 'images\\google.svg');
var youtube = utils.LoadSVG(fb.ProfilePath + 'images\\youtube.svg');
var spotify = utils.LoadSVG(fb.ProfilePath + 'images\\spotify.svg');
var wikipedia = utils.LoadSVG(fb.ProfilePath + 'images\\wikipedia.svg');
var lastfm = utils.LoadSVG(fb.ProfilePath + 'images\\lastfm.svg');
var search = utils.LoadSVG(fb.ProfilePath + 'images\\search.svg');
var settings = utils.LoadSVG(fb.ProfilePath + 'images\\settings.svg');
//.png files
var discogs = utils.LoadImage(fb.ProfilePath + 'images\\discogs.png');

var tfo = {
artist: fb.TitleFormat('%artist%'),
title: fb.TitleFormat('%title%'),
// playback_time : fb.TitleFormat('[%playback_time%]'),
// length : fb.TitleFormat('$if2(%length%,LIVE)'),
}

var panel = new _panel({ custom_background : true });
var albumart = new _albumart(0, 0, 0, 0);
var text = new _text_display(LM, 0, 0, 0, true);
var seekbar = new _seekbar(0, 0, 0, 0);

var colours = {
slider_background : RGB(160, 160, 160),
white : RGB(255, 255, 255),
contrast : RGB(196, 30, 35),
};

var font = CreateFontString('Segoe UI', 12);
var buttons = new _buttons();
var bs = _scale(24);
var bottom_y = 0;

buttons.update = function () {
var x = (panel.w - (bs * 7)) / 2
var y = seekbar.y + _scale(12);
this.buttons.google = new _button(x, y, bs, bs, { img : google }, null, function () { utils.Run('https://www.google.com/search?tbm=isch&q=' + encodeURIComponent(tfo.artist.Eval() + " " + tfo.title.Eval())); }, 'Google');
this.buttons.youtube = new _button(x + bs, y, bs, bs, { img : youtube }, null, function () { utils.Run('http://www.youtube.com/results?search_query=' + encodeURIComponent(tfo.artist.Eval() + " " + tfo.title.Eval())); }, 'youtube');
this.buttons.spotify = new _button(x + (bs * 2), y, bs, bs, { img : spotify}, null, function () { utils.Run('https://open.spotify.com/search/' + encodeURIComponent(tfo.artist.Eval() + " " + tfo.title.Eval())); }, 'spotify');
this.buttons.wikipedia = new _button(x + (bs * 3), y, bs, bs, { img : wikipedia }, null, function () { utils.Run('http://en.wikipedia.org/wiki/Special:Search?search=' + encodeURIComponent(tfo.artist.Eval()));  }, 'wikipedia');
this.buttons.lastfm = new _button(x + (bs * 4), y, bs, bs, { img : lastfm }, null, function () { utils.Run('https://www.last.fm/search?q=' + encodeURIComponent(tfo.artist.Eval()));  }, 'lastfm');
this.buttons.discogs = new _button(x + (bs * 5), y, bs, bs, { img : discogs }, null, function () { utils.Run('http://www.discogs.com/search?q=' + encodeURIComponent(tfo.artist.Eval()));  }, 'discogs');
this.buttons.search = new _button(x + (bs * 6), y, bs, bs, { img : search }, null, function () { fb.RunMainMenuCommand('Library/Search'); }, 'Library Search');
this.buttons.preferences = new _button(x + (bs * 7), y, bs, bs, { img : settings}, null, function () { fb.ShowPreferences(); }, 'Preferences');
}

panel.item_focus_change();

function on_colours_changed() {
panel.colours_changed();
text.refresh(true);
}

function on_font_changed() {
panel.font_changed();
text.refresh(true);
}

function on_item_focus_change() {
if (panel.selection.value == 0 && fb.IsPlaying) return;
panel.item_focus_change();
}

function on_metadb_changed(handles, fromhook) {
if (!fromhook) {
albumart.metadb_changed();
}
text.metadb_changed();
}

function on_mouse_lbtn_dblclk(x, y) {
if (albumart.img && albumart.containsXY(x, y)) {
panel.metadb.ShowAlbumArtViewer();
}
}

function on_mouse_lbtn_down(x, y) {
seekbar.lbtn_down(x, y);
}

function on_mouse_lbtn_up(x, y) {
if (seekbar.lbtn_up(x, y)) {
return;
}
if (buttons.lbtn_up(x, y)) {
return;
}
text.lbtn_up(x, y);
}

function on_mouse_leave() {
buttons.leave();
}

function on_mouse_move(x, y) {
window.SetCursor(buttons.buttons.google.containsXY(x, y) ? IDC_HAND
: buttons.buttons.youtube.containsXY(x, y) ? IDC_HAND
: buttons.buttons.spotify.containsXY(x, y) ? IDC_HAND
: buttons.buttons.wikipedia.containsXY(x, y) ? IDC_HAND
: buttons.buttons.lastfm.containsXY(x, y) ? IDC_HAND
: buttons.buttons.discogs.containsXY(x, y) ? IDC_HAND
: buttons.buttons.search.containsXY(x, y) ? IDC_HAND
: buttons.buttons.preferences.containsXY(x, y) ? IDC_HAND
: IDC_ARROW);

if (seekbar.move(x, y)) {
return;
}
if (buttons.move(x, y)) {
return;
}
text.move(x, y);
}

function on_mouse_rbtn_up(x, y) {
// if (buttons.buttons.stop.containsXY(x, y)) {
// fb.StopAfterCurrent = !fb.StopAfterCurrent;
// return true;
// }
return panel.rbtn_up(x, y, text);
}

function on_mouse_wheel(s) {
if (seekbar.wheel(s)) {
return;
}
text.wheel(s);
}

function on_paint(gr) {
panel.paint(gr);
text.paint(gr);
buttons.paint(gr);

// gr.FillRoundedRectangle(seekbar.x, seekbar.y, seekbar.w, seekbar.h, _scale(2), _scale(2), colours.slider_background);

// if (fb.IsPlaying) {
// var time_width = seekbar.x - _scale(12);
// gr.WriteText(tfo.playback_time.Eval(), font, colours.white, 0, bottom_y, time_width, _scale(12), 1, 2);
// gr.WriteText(tfo.length.Eval(), font, colours.white, seekbar.x + seekbar.w + _scale(12), bottom_y, time_width, _scale(12), 0, 2);

// if (fb.PlaybackLength > 0) {
// gr.FillEllipse(seekbar.x + seekbar.pos(), seekbar.y + _scale(3), _scale(6), _scale(6), colours.white);
// }
// }
}

function on_playback_order_changed() {
buttons.update();
window.Repaint();
}

function on_playback_dynamic_info_track(type) {
if (type == 0) text.metadb_changed();
else if (type == 1) albumart.metadb_changed();
}

function on_playback_new_track() {
panel.item_focus_change();
}

function on_playback_pause() {
text.refresh();
buttons.update();
window.Repaint();
}

function on_playback_seek() {
seekbar.playback_seek();
}

function on_playback_starting() {
buttons.update();
window.Repaint();
}

function on_playback_stop(reason) {
if (reason != 2) {
panel.item_focus_change();
}

buttons.update();
window.Repaint();
}

// function on_playback_time() {
// text.playback_time();
// window.RepaintRect(0, bottom_y, panel.w, panel.h - bottom_y);
// }

function on_playlist_items_added() {
text.refresh();
}

function on_playlist_items_removed() {
text.refresh();
}

function on_playlist_items_reordered() {
text.refresh();
}

function on_playlist_stop_after_current_changed() {
buttons.update();
window.Repaint();
}

function on_playlist_switch() {
on_item_focus_change();
}

function on_playlists_changed() {
text.refresh();
}

function on_size() {
panel.size();
text.size();

seekbar.x = _scale(60);
seekbar.y = panel.h - _scale(44);
seekbar.w = panel.w - (seekbar.x * 2);
seekbar.h  = _scale(6);

bottom_y = seekbar.y - _scale(4);
buttons.update();
}
10
Other Lossy Codecs / Re: lossyWAV 1.4.2 Development (was 1.5.0)
Last post by Nick.C -
If lossyWAV was a DSP then it would *have* to be the last in the chain if the preservation of zeroed LSBs was to be guaranteed.

Although I would question the need to insert lossyWAV as a DSP in the playback chain in the first place - why waste the CPU cycles processing the source to a lossy/lossier form while listening when one could simply listen to the unprocessed version?