Saturday, November 2, 2013

Sound Forge 11: no FX chain apply?

I’m a long time Sound Forge user, since the golden pre-Sony Sonic Foundry days, when the horrendous .NET Framework, a toy for script kiddies, was not needed. I’ve been following the version upgrades until today, when I gladly installed version 11. One of my most used options – applying the FX chain right away – simply disappeared. I’ve been searching around, and I found that I’m not the only one who complains about this.

There’s an alternative way to apply the FX chain through the FX Favorites menu, but it’s cumbersome and you cannot work upon the waveform while it’s open. Ironically, the new FX chain window is one of the “new” things Sony is marketing about. Well, congratulations for messing it out, Sony. I’ll pass.

I rolled back to Sound Forge 10, and I’m keeping it. Let’s see if a future Sound Forge 12 will bring that facility back.

Saturday, August 31, 2013

Plotting icons in OpenStreetMap with GPS coordinates

I’ve been working on a project with GPS data, where a map plotting would be handy. At first I thought about using Google Maps, but it’s always better go open source, and since I’m an enthusiast of OpenStreetMap, I started searching a way to do it, and I found the OpenLayers project, which is insanely cool.

My goal: plot some small images on the map (icons), and when the cursor goes over an image, a popup would appear. On my way to make it happen, I had to develop some interesting things, that I share now with everyone, in the hope that it can be useful.

The first difficulty I found was to make OpenLayers understand GPS coordinates without much fuss. To do so, you must have a coordinate transformation, which is not exactly trivial. Below is a function to make this conversion trivial, yes, so that you’ll never need to worry about it again. The map argument is the map object you’re working upon, and lon and lat are floating point numbers.
function Geo(map, lat, lon) {
	return new OpenLayers.LonLat(lon, lat)
		.transform(new OpenLayers.Projection('EPSG:4326'),
			map.getProjectionObject());
}

// Example usage:
var map = new OpenLayers.Map('myMapDivId');
map.addLayer(new OpenLayers.Layer.OSM());
var coor = Geo(map, -5.773274, -35.204948);
map.setCenter(coor, 8);
Second, the image (icon) plotting. When you plot an image at a given point, this image is centered at that point. I wanted to plot an image of a pushpin, which points at the wrong location if centered – the very end of the pushpin will point to a location below the center of the image. It had to be moved above, so that the bottom of the image was exactly over the point.

The function below creates the image and plots it with a bottom offset, if needed. The img argument is a valid image URL, cx and cy are the size of the image in pixels, and bottomOffset is a boolean value. The function is asychronous and waits the image to be loaded; use the onDone callback, which receives the new marker as argument.
function PlotMarker(map, img, lat, lon, bottomOffset, onDone) {
	var imgObj = new Image();
	imgObj.src = img;
	imgObj.onload = function() {
		var sz = new OpenLayers.Size(imgObj.width, imgObj.height);
		var off = new OpenLayers.Pixel(-(sz.w / 2),
			bottomOffset ? -sz.h : -(sz.w / 2));
		var ico = new OpenLayers.Icon(img, sz, off);
		if(onDone !== undefined && onDone !== null)
			onDone(new OpenLayers.Marker(Geo(map, lat, lon), ico));
	};
}

// Example usage:
var map = new OpenLayers.Map('myMapDivId');
map.addLayer(new OpenLayers.Layer.OSM());
var markers = new OpenLayers.Layer.Markers('Markers');
map.addLayer(markers);
PlotMarker(map, 'pushpin.png', -5.773274, -35.204948,
	true, // it's a pushpin, I want it bottom-aligned
	function(mk) {
		markers.addMarker(mk);
	});
Below you have a fully functional web application composed of three files, which displays an OpenStreetMap map at the whole page, loads points from a separated JSON file, and renders it accordingly. There’s no server-side processing involved, but the JSON file could easily be something processed by the server, which would load the data from some sort of database. I used jQuery library to handle the mouseover event which shows the popup over the images, but it’s not really necessary if you want to use something else.

1) index.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8"/>
	<title>Rodrigo's map</title>
	<style>
	* { -moz-box-sizing:border-box; -webkit-box-sizing:border-box; box-sizing:border-box; }
	body { margin:0; font:10pt Arial; color:#242424; }
	#mapArea { position:absolute; width:100%; height:100%; }
	</style>
	<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
	<script src="http://openlayers.org/api/2.13.1/OpenLayers.js"></script>
	<script src="index.js"></script>
</head>
<body>
	<div id="mapArea"></div>
</body>
</html>
2) index.js
function PlotData(divId, data) {
	function Geo(map, lat, lon) {
		return new OpenLayers.LonLat(lon, lat)
			.transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());
	}
	function PlotMarker(map, img, lat, lon, bottomOffset, onDone) {
		var imgObj = new Image();
		imgObj.src = img;
		imgObj.onload = function() {
			var sz = new OpenLayers.Size(imgObj.width, imgObj.height);
			var off = new OpenLayers.Pixel(-(sz.w / 2),
				bottomOffset ? -sz.h : -(sz.w / 2));
			var ico = new OpenLayers.Icon(img, sz, off);
			if(onDone !== undefined && onDone !== null)
				onDone(new OpenLayers.Marker(Geo(map, lat, lon), ico));
		};
	}

	var map = new OpenLayers.Map(divId);
	map.addLayer(new OpenLayers.Layer.OSM());
	map.setCenter(Geo(map, data.center[0], data.center[1]), data.zoom);

	var markers = new OpenLayers.Layer.Markers('Markers');
	map.addLayer(markers);

	var $map = $('#'+divId),
	$det = $('<div></div>').css({
			'position':'absolute',
			'padding':'0 4px',
			'display':'none',
			'box-shadow':'2px 2px 3px #999',
			'background-color':'rgba(255,255,255,.85)',
			'border':'1px solid #AAA'
		}).appendTo('body');
	$.each(data.points, function(i, pt) {
		PlotMarker(map, pt.icon, pt.coor[0], pt.coor[1], true, function(mk) {
			markers.addMarker(mk);
			mk.events.on({
				mouseover: function(ev) {
					$det.html(pt.text).css({
						left: (ev.pageX < $(document).width() / 2) ?
							ev.pageX+'px' : (ev.pageX - $det.outerWidth())+'px',
						top: (ev.pageY < $(document).height() / 2) ?
							ev.pageY+'px' : (ev.pageY - $det.outerHeight())+'px',
						display: 'block'
					});
					$map.css('cursor', 'pointer');
				},
				mouseout: function(ev) {
					$det.empty().css('display', 'none');
					$map.css('cursor', 'auto');
				}
			});
		});
	});
}

$(document).ready(function() {
	$.getJSON('data.json', function(data) {
		PlotData('mapArea', data);
	});
});
3) data.json – assumes image “pushpin.png” exists
{
	"center": [ -5.797942,-35.211782 ],
	"zoom": 14,
	"points": [
		{
			"coor": [ -5.799500,-35.21951 ],
			"icon": "pushpin.png",
			"text": "First point<br/>Anything here"
		},
		{
			"coor": [ -5.790982,-35.19409 ],
			"icon": "pushpin.png",
			"text": "Other <b>point</b> here"
		},
		{
			"coor": [ -5.802083,-35.20877 ],
			"icon": "pushpin.png",
			"text": "Something else<br/>placed here"
		}
	]
}
Enjoy.

Thursday, August 8, 2013

Firefox 23 is slower than Firefox 22

In last June, I’ve been amazed with the Firefox 22 launching. It featured a new JavaScript engine called OdinMonkey, and particularly on Linux, the browser became really fast and smooth. The upgrade was instantly noticeable with Firebug, which became a lot more responsive.

Yesterday, however, Mozilla rolled out Firefox 23 – with a horrible new logo, without contrast and which looks blurry at small size. But mainly, to my dismay, right after upgrade, everything became slower. It felt like last year’s versions, with a sluggish performance, and essentially a pain to use. On Firebug, this is felt very strongly.

I forgot to backup my profile, but luckily the profile structure was not modified, and I was able to downgrade, download Firefox 22 again and removing this horrible Firefox 23, in the hope that they can fix it on the next version.

Update, Sep. 19:
I’ve just tested Firefox 24, and it seems to be even slower than 23. So, I’m still keeping Firefox 22.

Update, Nov. 7:
Apparently the slowness is fixed on Firefox 25, which I’m testing right now. Finally.

Tuesday, July 30, 2013

PHP and JavaScript internationalization

These days I’ve been working on a PHP/JavaScript project which needed to be translated from English into other languages. I made a search and the results were pretty disappointing. All the solutions I’ve came across were either too complicated, too heavy or too messy. I wanted something more hygienic, that could be easily integrated into any project, so I ended up writing my own.

Basically, all you have to do is add a subdirectory called “i18n” (or any other name you want) and copy the “i18n.php” file there, then create a file to each language you need. One of those language files will be your default – probably the English one –, where the strings will also serve as the mapping keys. The other language files will simply have all the lines, one by one, translated.

Once the “i18n.php” file is included into your PHP script, you’ll have to set up the translation by calling i18n_set_map(), choosing the source (the default) language file, and the target language. And it’s done. Every string passed to the I() function will be translated, both in PHP and JavaScript.

There is a comprehensive example on the GitHub repository, where I published everything under the MIT license, in the hope that it can be useful to someone else. The repository is at github.com/rodrigocfd/php-js-i18n.

Saturday, July 20, 2013

Sibelius 7 sucks

As a musician with classical training, I love sheet music. They are not only beautiful pieces of graphic art, but also great repositories of musical knowledge, which are always ready to have music pulled out of them. And music writing is universal: sheet music written in China is the same written in Canada.

Obviously, when it comes to computers, I always was interested in sheet music editors. My first editor was Encore, a very simple one. But soon I moved to a more powerful editor: Sibelius 2. And since then, I’ve been a faithful Sibelius user. Well, up to version 6.

Sibelius Software was acquired by Avid, know for its sluggish Pro Tools. Unfortunately, Sibelius 7 suffered a huge shift in development direction, jumping on the ribbon bandwagon – the single worst thing ever invented in computer user interface history – and bringing up a very confusing and keyboard-unfriendly screen. Now, all the actions and option dialogs – previously organized into regular menus, easy to reach with keyboard shortcuts only – are spread among the ribbon tabs, with distracting and childish icons, wasting precious screen space and requiring you to execute many, many additional mouse clicks while searching for something among that mess. Oh, and there’s still a File ribbon tab, with even more additional tabs at left and options distributed like mucus dropped from a strong sneeze!

But Sibelius 7 didn’t change only the interface, they also brought improvements, right? Wrong. There is only one improvement, relative to text flowing inside textboxes. Everything else is insignificant for music writing. I felt really ashamed by watching the what's new videos from Sibelius Software, with nothing new to show besides that horrible user interface. Don’t they have some critical sense, at least?

So it seems that I’m stuck with Sibelius 6, which is a bit slow, but it’s usable. Well, until some other company comes out with something better. And without a ribbon.

Friday, June 7, 2013

Command line password prompt in PHP

These days I’ve been writing a quick command line script in PHP, and at some point I needed the user to type username and password to authenticate in some remote account. The standard way to prompt for a password in Linux is to hide the characters as the person goes typing, and I wanted that feeling on the script.

I assembled some code from here and here and I wrote a small function which prompts for username and password and returns an stdClass, which I share here:
function PromptUsrPwd()
{
	fwrite(STDOUT, 'Enter user name: ');
	$usr = trim(fgets(STDIN));
	$command = "/usr/bin/env bash -c 'echo OK'";
	if(rtrim(shell_exec($command)) !== 'OK') {
		die("Can't invoke bash.\n");
		return null;
	}
	$command = "/usr/bin/env bash -c 'read -s -p \"".
		addslashes("Password for $usr:").
		"\" mypassword && echo \$mypassword'";
	$pwd = rtrim(shell_exec($command));
	echo "\n";
	return (object)array('usr' => $usr, 'pwd' => $pwd);
}
This is an usage example. Run it on command line to see it in action:
$credentials = PromptUsrPwd();
echo 'Your name is '.$credentials->usr."\n";
echo 'Your password is '.$credentials->pwd."\n";

Monday, May 6, 2013

Brazilian progressive music

Well-made progressive music is just amazing. There’s not much to write about this one – lyrics (see here and here), arrangements, actual playing, mixing – there are no flaws I can spot. I’ll just leave this here and appreciate:



Unfortunately the other songs of the band are not good as this one – not even close, actually. But this very one song is so exceptionally good that the guys can die in peace.

Sunday, April 21, 2013

jQuery facepunches old IE versions

The jQuery team announced that they dropped support for Internet Explorer 6, 7 and 8 on the v2.0.0 of the library. That’s one huge and important move. First, because jQuery is widely used worldwide, and even endorsed by some big companies like Microsoft and Google. Second, because these versions of Internet Explorer still have a considerable percentage of the market share as of today. The jQuery guys announced that v1.9.x will still support these old IE versions, but who knows for how long.

This made me think the primary reason that jQuery was conceived for: a thin layer of cross-browser compatibility. If the library is not so widely compatible anymore, isn’t it losing its main reason to exist? Or maybe it’s heading towards becoming a framework like many others, just providing some useful and funny tricks.

I’m not against this decision, but given the wide adoption of jQuery in the wild, maybe it’s too early to force the migration to the latest IE version. Although when I think of the real pain that is to develop to those terrible browsers, I just raise my hands and scream hallelujah, they finally did it!

Friday, March 15, 2013

The best SRT editor for subtitles

After a couple months of work, it has just been published on CNet’s Download.com my newest program: SRTEd, a visual and portable editor to SRT files for Windows.

Basically, I decided to write this program because I had to edit some subtitles a while ago, in SRT format, and the available editors were quite tedious and painful to use. I somewhat got this insight of a more visual editor, and some time later I began writing it. The most important thing to “get the feel” is the use of the keyboard arrow keys to sync the subs. Left/right arrows move them, and when holding Shift key, change the duration. This makes the sync incredibly easy to do, visual.



Technically, the program is pure C-like C++ (that’s how I define my own C++ style) and native Win32, so it’s really light and fast. To video playback, it uses DirectX infrastructure. Moreover, SRTEd uses my own Win32 object-oriented library, which I plan to release as open source some day.

Here’s a getting started video:



CNet download link: SRTEd - SRT Subtitles Editor.

Update: I just received an e-mail from Softpedia, they published SRTEd on their site too.

Wednesday, February 20, 2013

KRK VXT frequency charts

As looking for a pair of studio monitors, I wanted to have a comparison between the three KRK VXT series models: VXT4, VXT6 and VXT8 – cones being respectively 4, 6 and 8 inches. I got the individual charts from KRK website, and I just made a collage with the three. This is what I ended up with:



It’s easy to spot how the low end increases with the cone size. Many people recommend a subwoofer, but not everyone has an appropriated room to fit everything. Indeed, in my case, I can hardly fit anything larger than the VXT4 on my desk, so I’ll probably have to stick with the VXT4 or other monitor with similar size, like the Yamaha HS50M – although I found these too bright and lacking in lows, rather unpleasant.

And the quest for my new home studio monitors goes on.

Update: after a lot of research and some listenings, I ended up picking up the KRK VXT4, which not only sounds really good, but also fits my desk. I’ve got a new pair for a good price, and I’m pretty satisfied so far.

Thursday, February 14, 2013

Reading version from EXE and DLL files

Here’s a C++ and Win32 class to read version information from the resource section within EXE and DLL Windows binaries. The key functions are GetFileVersionInfo and VerQueryValue. The object will provide public pointers to the strings; these pointers should not be deleted, since they point straight into the allocated data block. If version information can’t be read – for example, if it’s a file with no version information – the load method will simply return false.

There’s room for more improvements, like tighter error checking, but it’s pretty usable:
#include <Windows.h>
#pragma comment(lib, "Version.lib")

class VersionInfo {
public:
	const wchar_t *pComments, *pCompanyName, *pLegalCopyright, *pProductVersion;

	VersionInfo() : _data(NULL),
		pComments(NULL), pCompanyName(NULL),
		pLegalCopyright(NULL), pProductVersion(NULL) { }

	~VersionInfo() {
		if(_data) free(_data);
	}

	bool load(const wchar_t *path) {
		DWORD szVer = 0;
		if(!(szVer = GetFileVersionInfoSize(path, &szVer)))
			return false;
		_data = (BYTE*)malloc(sizeof(BYTE) * szVer);
		if(!GetFileVersionInfo(path, 0, szVer, _data))
			return false;

		UINT len = 0;
		VerQueryValue(_data, L"\\StringFileInfo\\040904b0\\Comments",
			(void**)&pComments, &len);
		VerQueryValue(_data, L"\\StringFileInfo\\040904b0\\CompanyName",
			(void**)&pCompanyName, &len);
		VerQueryValue(_data, L"\\StringFileInfo\\040904b0\\LegalCopyright",
			(void**)&pLegalCopyright, &len);
		VerQueryValue(_data, L"\\StringFileInfo\\040904b0\\ProductVersion",
			(void**)&pProductVersion, &len);
		return true;
	}

private:
	BYTE *_data;
};
Usage example:
{
	VersionInfo vi;
	if(vi.load(L"C:\\Program.exe")) {
		OutputDebugString(vi.pProductVersion);
		OutputDebugString(vi.pComments);
	}
}
Can’t be simpler than that.

Like Firefox? Try Pale Moon

When it comes to internet browsers, overall, I prefer Firefox behavior over Chrome’s. But when using Firefox 18.0.2 on Windows 7 x64, I started to become increasingly angry with its memory usage. Even with only 4 tabs opened, Firefox peaked 800 MB of RAM easily, like not releasing memory at all. This was making Firefox really slow, a pain to use.

Searching around, I found Pale Moon. Basically it’s Firefox compiled specifically for Windows, letting out compatibility with older processors, all compiler optimization switches on, and also some minor changes done by the Pale Moon mantainer, which follows Firefox with some gap, waiting for the bugs to be fixed. Pale Moon seems to release memory faster, and on my tests, the RAM usage floats around 300 MB, compared to 800 MB on Firefox. On the use, it’s noticeably faster, a joy.

I’m testing a portable version of Pale Moon 15.4.1, and so far I’m very pleased. All my add-ons worked fine. I totally recommend it as an alternative to Firefox itself.