<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>More Than Technical &#187; Solutions</title>
	<atom:link href="http://www.morethantechnical.com/category/solutions/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.morethantechnical.com</link>
	<description>On software, code, the internet and more.</description>
	<lastBuildDate>Mon, 06 Feb 2012 23:48:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>Android Market&#8217;s apps compatibility problem [w/ solution]</title>
		<link>http://www.morethantechnical.com/2011/11/03/android-markets-apps-compatibility-problem-with-solutio/</link>
		<comments>http://www.morethantechnical.com/2011/11/03/android-markets-apps-compatibility-problem-with-solutio/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 18:42:49 +0000</pubDate>
		<dc:creator>Arnon</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[compatibility]]></category>
		<category><![CDATA[compatible]]></category>
		<category><![CDATA[fix]]></category>
		<category><![CDATA[item]]></category>
		<category><![CDATA[market]]></category>
		<category><![CDATA[This item is not compatible with your device]]></category>
		<category><![CDATA[your device is not compatible with this item]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=973</guid>
		<description><![CDATA[WOW That was annoying! From the moment I started using a custom ROM on my Samsung Galaxy S2 (Cognition S2, to be exact), I started having issues with some apps. Sometimes they won&#8217;t appear in search results, other times it will just say it&#8217;s not compatible. It drove me nuts! Naturally I started with the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.morethantechnical.com/wp-content/uploads/2011/11/110311_1837_HowIsolvedt1.png" alt="" align="left" /></p>
<p><span style="font-size: 12pt;">WOW That was annoying! From the moment I started using a custom ROM on my Samsung Galaxy S2 (<a href="http://forum.xda-developers.com/showthread.php?t=1124396">Cognition S2</a>, to be exact), I started having issues with some apps.<br />
</span></p>
<p><span style="font-size: 12pt;">Sometimes they won&#8217;t appear in search results, other times it will just say it&#8217;s not compatible. It drove me nuts!<br />
</span></p>
<p><span style="font-size: 12pt;">Naturally I started with the forums – All the solutions there were about <a href="http://myraroldan.com/wp/2011/09/your-device-is-not-compatible-with-this-item-annoying-android-market-message/">LCD DPI change</a>. Funny, I never thought of that, but it did make sense. The only problem was that I never touched my DPI settings (Heck, I didn&#8217;t know I could).<br />
</span></p>
<p><span style="font-size: 12pt;">(On a side note – tampering with the density is pretty cool… if you want to try it, you can download apps from the Market like LCD Density)<br />
</span></p>
<p><span style="font-size: 12pt;">Back to my problem…<br />
<span id="more-973"></span><br />
</span></p>
<p><span style="font-size: 12pt;">At that point, I knew for sure it was a ROM issue. My friend, who bought the same phone in Thailand, was able to install all the &#8216;problematic&#8217; apps, up until the point that I installed the same ROM on his machine. So, when in doubt – Check what the guys at the awesome <a href="http://www.cyanogenmod.com">CyanogenMod</a> ROM did!<br />
</span></p>
<p><span style="font-size: 12pt;">My experience showed me that a lot can happen by changing <strong>build.prop</strong> file (Guys.. Do it only if you have to! I am not responsible for any damage and ALWAYS BACKUP!).<br />
</span></p>
<p><span style="font-size: 12pt;">Ok now that I got that out of my system, I pulled CyanogenMod&#8217;s build.prop file, and compared it to my device&#8217;s build.prop.<br />
</span></p>
<p><span style="font-size: 12pt;">My hunch told me that it was the fingerprint section. It just made sense that if the device is sending an incorrect fingerprint to the Market, it will think some apps are not incompatible.<br />
</span></p>
<p><span style="font-size: 12pt;">So… My hunch was right!<br />
</span></p>
<p><span style="font-size: 12pt;">The <strong>original build.prop</strong> had those lines in:<br />
</span></p>
<pre class="brush: plain; title: ; notranslate"> ro.build.description=GT-I9100-user 2.3.4 GINGERBREAD XXKH3 release-keys
ro.build.fingerprint=samsung/GT-I9100/GT-I9100:2.3.4/GINGERBREAD/XXKH3:user/release-keys
</pre>
<p><span style="font-size: 12pt;">The changed buildprop had this data instead:</span></p>
<pre class="brush: plain; title: ; notranslate">
ro.build.description=GT-I9100-user 2.3.4 GINGERBREAD XXKG2 release-keys
ro.build.fingerprint=samsung/GT-I9100/GT-I9100:2.3.4/GINGERBREAD/XXKG2:user/release-keys
</pre>
<p><span style="font-size: 12pt;">I really don&#8217;t know what causes the original data to be invalid to some apps, but it did! It appears XXKH3 is for some reason incompatible… It might be a bug on Google&#8217;s side, or there is some logic I don&#8217;t understand (feel free to enlighten me in the comments)</span></p>
<p><span style="font-size: 12pt;">Keep in mind, that you need to compare the lines between two ROMs which are made for YOUR device. In this case it is the GT-I9100. Just download the right ROM from CyanogenMod, and see inside the zip, under &#8220;system&#8221; folder you can get the build.prop file. Then, compare it to the file you got from your own ROM </span></p>
<p><span style="font-size: 12pt;">So, to make a long story short… If you want to do like me you should do the following:<br />
</span></p>
<ol>
<li><span style="font-size: 12pt;">Pull out /system/build.prop file from your device <strong>AND BACK IT UP</strong><br />
</span></li>
<li><span style="font-size: 12pt;">Change the fingerprint attributes<br />
</span></li>
<li><span style="font-size: 12pt;">Remount your system as writable<br />
</span></li>
<li><span style="font-size: 12pt;">Push the modified build.prop back in your device<br />
</span></li>
<li><span style="font-size: 12pt;">Reboot<br />
</span></li>
</ol>
<p><span style="font-size: 12pt;">I hope this post is helpful to some of you!<br />
</span></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.morethantechnical.com%2F2011%2F11%2F03%2Fandroid-markets-apps-compatibility-problem-with-solutio%2F&amp;title=Android%20Market%26%238217%3Bs%20apps%20compatibility%20problem%20%5Bw%2F%20solution%5D" id="wpa2a_2"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2011/11/03/android-markets-apps-compatibility-problem-with-solutio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A GLSL shader showing the normal map [w/ code]</title>
		<link>http://www.morethantechnical.com/2011/10/30/a-glsl-shader-showing-the-normal-map-w-code/</link>
		<comments>http://www.morethantechnical.com/2011/10/30/a-glsl-shader-showing-the-normal-map-w-code/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 15:16:55 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[3d]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[fragment]]></category>
		<category><![CDATA[glsl]]></category>
		<category><![CDATA[normal]]></category>
		<category><![CDATA[shader]]></category>
		<category><![CDATA[vertex]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=958</guid>
		<description><![CDATA[A very simple thing, although I couldn&#8217;t find on Google some place to copy-paste off, so here it is: Vertex shader Fragment shader A technique to load the shaders that will save you a lot of headaches I based it on this example from NeHe. It does periodical error checking so you can see if [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.morethantechnical.com/wp-content/uploads/2011/10/Screen-shot-2011-10-30-at-11.13.48-AM.png" rel="lightbox[958]"><img src="http://www.morethantechnical.com/wp-content/uploads/2011/10/Screen-shot-2011-10-30-at-11.13.48-AM-150x150.png" alt="" title="Screen shot 2011-10-30 at 11.13.48 AM" width="150" height="150" class="alignleft size-thumbnail wp-image-963" /></a><a href="http://www.morethantechnical.com/wp-content/uploads/2011/10/Screen-shot-2011-10-30-at-11.13.54-AM.png" rel="lightbox[958]"><img src="http://www.morethantechnical.com/wp-content/uploads/2011/10/Screen-shot-2011-10-30-at-11.13.54-AM-150x150.png" alt="" title="Screen shot 2011-10-30 at 11.13.54 AM" width="150" height="150" class="alignleft size-thumbnail wp-image-964" /></a><br />
A very simple thing, although I couldn&#8217;t find on Google some place to copy-paste off, so here it is:<br />
<span id="more-958"></span></p>
<h3>Vertex shader</h3>
<pre class="brush: plain; title: ; notranslate">
varying vec3 normal;

void main()
{
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    normal = gl_NormalMatrix * gl_Normal;
}
</pre>
<h3>Fragment shader</h3>
<pre class="brush: plain; title: ; notranslate">
varying vec3 normal;

void main()
{
    vec3 normal_normal = normalize(normal);
	gl_FragColor = vec4(normal_normal, 1.0);
}
</pre>
<h3>A technique to load the shaders that will save you a lot of headaches</h3>
<pre class="brush: plain; title: ; notranslate">
GLvoid* my_program;

//Error-checking function
void checkARBError(GLvoid* obj) {
	char infolog[1024] = {0}; int _written = 0;
	glGetInfoLogARB(obj, 1024, &amp;_written, infolog);
	if(_written&gt;0) {
		cerr &lt;&lt; infolog &lt;&lt; endl;
	}
}	

bool notIsAscii(int i) { return !isascii(i); }

void init_shaders() {
	const GLubyte* lang_ver = glGetString(GL_SHADING_LANGUAGE_VERSION);
	cout &lt;&lt;&quot;shading language version: &quot;&lt;&lt;(uchar*)lang_ver&lt;&lt;endl;

	const char * my_fragment_shader_source;
	const char * my_vertex_shader_source;

        //Reading shaders from files
	ifstream ifs(&quot;vshader.txt&quot;);
	ostringstream ss; ss &lt;&lt; ifs.rdbuf();
	ifstream ifs1(&quot;fshader.txt&quot;);
	ostringstream ss1; ss1 &lt;&lt; ifs1.rdbuf();
	ifs.close(); ifs1.close();

        //Cleaning up the strings...
	string _vertex = ss.str(); _vertex.erase(remove_if(_vertex.begin(), _vertex.end(), notIsAscii), _vertex.end());
	string _frag = ss1.str(); _frag.erase(remove_if(_frag.begin(), _frag.end(), notIsAscii), _frag.end());

	// Get Vertex And Fragment Shader Sources
	my_fragment_shader_source = _frag.c_str();
	my_vertex_shader_source = _vertex.c_str();

        //DEBUG - can remove
	cout &lt;&lt; &quot;vertex shader:&quot;&lt;&lt;endl&lt;&lt;my_vertex_shader_source&lt;&lt;endl;
	cout &lt;&lt; &quot;fragment shader:&quot;&lt;&lt;endl&lt;&lt;my_fragment_shader_source&lt;&lt;endl;

	GLvoid* my_vertex_shader;
	GLvoid* my_fragment_shader;

	// Create Shader And Program Objects
	my_program = glCreateProgramObjectARB();
	my_vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
	my_fragment_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);

	// Load Shader Sources
	glShaderSourceARB(my_vertex_shader, 1, &amp;my_vertex_shader_source, NULL);
	checkARBError(my_vertex_shader);
	glShaderSourceARB(my_fragment_shader, 1, &amp;my_fragment_shader_source, NULL);
	checkARBError(my_fragment_shader);

	// Compile The Shaders
	glCompileShaderARB(my_vertex_shader);
	checkARBError(my_vertex_shader);
	glCompileShaderARB(my_fragment_shader);
	checkARBError(my_fragment_shader);

	// Attach The Shader Objects To The Program Object
	glAttachObjectARB(my_program, my_vertex_shader);
	glAttachObjectARB(my_program, my_fragment_shader);
	checkARBError(my_program);

	// Link The Program Object
	glLinkProgramARB(my_program);
	checkARBError(my_program);

}
</pre>
<p>I based it on <a href="http://nehe.gamedev.net/article/glsl_an_introduction/25007/" target="_blank">this example</a> from NeHe.</p>
<p>It does periodical error checking so you can see if something is wrong, plus it will make sure the vertex shader and fragmetn shader are stripped of all non-ASCII characters.<br />
This way the compilation will not give you cryptic errors such as &#8220;ERROR: 0:1: &#8216;<&#8216; : syntax error syntax error&#8221;&#8230;</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.morethantechnical.com%2F2011%2F10%2F30%2Fa-glsl-shader-showing-the-normal-map-w-code%2F&amp;title=A%20GLSL%20shader%20showing%20the%20normal%20map%20%5Bw%2F%20code%5D" id="wpa2a_4"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2011/10/30/a-glsl-shader-showing-the-normal-map-w-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>UnderGet – Download blocked content</title>
		<link>http://www.morethantechnical.com/2011/06/08/underget-%e2%80%93-download-blocked-content/</link>
		<comments>http://www.morethantechnical.com/2011/06/08/underget-%e2%80%93-download-blocked-content/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 14:39:33 +0000</pubDate>
		<dc:creator>Arnon</dc:creator>
				<category><![CDATA[Recommended]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[Website]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[blocked content]]></category>
		<category><![CDATA[corporate]]></category>
		<category><![CDATA[file extension]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[proxy]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=876</guid>
		<description><![CDATA[Ever wanted to try and download an mp3 file at your workplace, but couldn&#8217;t because corporate firewall policy was to block every url ending with the .mp3 prefix? I had. Until recently, I&#8217;d accept this as it was from above, but that was until I discovered this website called UnderGet. The trick is pretty simple. [...]]]></description>
			<content:encoded><![CDATA[<p>Ever wanted to try and download an mp3 file at your workplace, but couldn&#8217;t because corporate firewall policy was to block every url ending with the .mp3 prefix?<br />
<span id="more-876"></span></p>
<p>I had. Until recently, I&#8217;d accept this as it was from above, but that was until I discovered this website called <a href="http://www.underget.com">UnderGet</a>.</p>
<p>The trick is pretty simple. The engine behind this site works by renaming the file or encoding its content so the blocking software cannot detect it.</p>
<p>I am now able to download my favorite podcast mp3 files when I&#8217;m at my workplace</p>
<p style="text-align: center;"><img src="http://www.morethantechnical.com/wp-content/uploads/2011/06/060811_1439_UnderGetDow1.png" alt="" /></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.morethantechnical.com%2F2011%2F06%2F08%2Funderget-%25e2%2580%2593-download-blocked-content%2F&amp;title=UnderGet%20%E2%80%93%20Download%20blocked%20content" id="wpa2a_6"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2011/06/08/underget-%e2%80%93-download-blocked-content/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How thinking outside of the box might save your “damaged” hard drive (and mental health)</title>
		<link>http://www.morethantechnical.com/2011/03/15/how-thinking-outside-of-the-box-might-save-your-%e2%80%9cdamaged%e2%80%9d-hard-drive-and-mental-health/</link>
		<comments>http://www.morethantechnical.com/2011/03/15/how-thinking-outside-of-the-box-might-save-your-%e2%80%9cdamaged%e2%80%9d-hard-drive-and-mental-health/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 13:31:24 +0000</pubDate>
		<dc:creator>Arnon</dc:creator>
				<category><![CDATA[Hard drive]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[avid]]></category>
		<category><![CDATA[capacity]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[hard drive]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[rescue]]></category>
		<category><![CDATA[restore]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=854</guid>
		<description><![CDATA[This is a short tale about last minute information salvage, and why you should always stay optimistic about your failed hard drive. This of course, doesn&#8217;t cover up case of hard drive that is making funny noises… It started up yesterday noon, when I was working with a friend, a professional video editor, on a [...]]]></description>
			<content:encoded><![CDATA[<p>This is a short tale about last minute information salvage, and why you should always stay optimistic about your failed hard drive.</p>
<p>This of course, doesn&#8217;t cover up case of hard drive that is making funny noises…<span id="more-854"></span></p>
<p>It started up yesterday noon, when I was working with a friend, a professional video editor, on a video clip.</p>
<p>We should have started to suspect the minute his PC started to stutter… but being the optimistic guys we are, we let it slide. How about another reboot for the PC? That should work.</p>
<p>This time it didn&#8217;t. The PC got stuck on Windows 7&#8242;s &#8220;Starting Windows&#8221; screen.</p>
<p>Still, a couple of reboots later, and the PC is up and we continued working.</p>
<p>Evening comes, and the hard drive no longer appears on My Computer. Oh oh! This is never a good sign.</p>
<p>Few SATA rewiring and now it appears. But the 1TB hard drive now shows up as 33MB! (This is not a typo… I mean <strong>megabytes</strong>).</p>
<p>A little bit of digging in forums lead me to <a href="http://blog.atola.com/restoring-factory-hard-drive-capacity/">this handy tool</a></p>
<p><img src="http://www.morethantechnical.com/wp-content/uploads/2011/03/031511_1331_Howthinking1.gif" alt="" /></p>
<p>I had to take the hard drive and connect it to an XP based PC since it supports neither Windows 7, nor 64bit.</p>
<p>But after a quick treatment by this tool, we were managed to get the hard drive size sane again…</p>
<p>This was only halfway through.  Now, the MFT was damaged…</p>
<p>After figuring out that the freeware tools couldn&#8217;t help us at this point, we googled a bit and got to this amazing software called <a href="http://www.z-a-recovery.com/">Zero Assumption Recovery</a>.</p>
<p>With this software we managed to scan the hard drive for about 1 hour, and retrieve EVERYTHING back. Did I say everything? Yes and no… Here&#8217;s why</p>
<p>My friend had finished two big video projects that he needed to deliver in two days. But the recovery software recovered everything BUT the project files… All the directories were restored but the project files weren&#8217;t even listed</p>
<p>If you got to this point, you can imagine the frustration.</p>
<p>I kindly asked him to show me a sample project file. I noticed that his software&#8217;s project files are files with size 0.</p>
<p>That&#8217;s when thinking outside of the box kicked in… I copied a sample file to the root folder where the project folders existed, and renamed it to be the exact name of one of the folders… Voila!!! That&#8217;s all it took. Apparently, this file only marks his software to look for a match-named folder, and take all the info from there…</p>
<p>That was a long journey with long shots, but to think about all the money and time saved for him, not to mention customer loss and bad reputation, I&#8217;d say we were in a really good place</p>
<p>In conclusion – In my opinion, if you hard drive is identified by the system, and does not make any click sound, you might be in a good position to restore your data.</p>
<p>Just think positive!</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.morethantechnical.com%2F2011%2F03%2F15%2Fhow-thinking-outside-of-the-box-might-save-your-%25e2%2580%259cdamaged%25e2%2580%259d-hard-drive-and-mental-health%2F&amp;title=How%20thinking%20outside%20of%20the%20box%20might%20save%20your%20%E2%80%9Cdamaged%E2%80%9D%20hard%20drive%20%28and%20mental%20health%29" id="wpa2a_8"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2011/03/15/how-thinking-outside-of-the-box-might-save-your-%e2%80%9cdamaged%e2%80%9d-hard-drive-and-mental-health/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Download all your Last.fm loved tracks in two simple steps</title>
		<link>http://www.morethantechnical.com/2011/03/14/download-all-you-last-fm-loved-tracks-in-a-single-command/</link>
		<comments>http://www.morethantechnical.com/2011/03/14/download-all-you-last-fm-loved-tracks-in-a-single-command/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 04:27:48 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Recommended]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[Website]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[lame]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[mp4]]></category>
		<category><![CDATA[mplayer]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[youtube]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=844</guid>
		<description><![CDATA[I&#8217;m a fan of Last.fm online radio, and I have a habit of marking every good song that I hear as a &#8220;loved track&#8221;. Over the years I got quite a list, and so I decided to turn it into my jogging playlist. But for that, I need all the songs downloaded to my computer [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a fan of <a href="http://www.last.fm/home">Last.fm</a> online radio, and I have a habit of marking every good song that I hear as a &#8220;loved track&#8221;. Over the years I got quite a list, and so I decided to turn it into my jogging playlist. But for that, I need all the songs downloaded to my computer so I can put them on my mobile. While Last.fm does link to Amazon for downloading all the loved songs for pay, I&#8217;m going to walk the fine moral line here and suggest how you can download every song from existing free YouTube videos.<br />
If it really bothers you, think of it as if I created a YouTube playlist and now I&#8217;m using my data plan to stream the songs off YT itself..<br />
Moral issues resolved, we can move on to the scripting.<br />
<span id="more-844"></span><br />
What you need to have:<br />
Linux-like system, <a href="http://www.mplayerhq.hu/design7/news.html">MPlayer</a>, <a href="http://lame.sourceforge.net/">Lame MP3 encoder</a>, some command-line experience or at least adventure-ness.</p>
<p>So first you&#8217;ll need to export your loved tracks from Last.fm in tab separated format &#8211; a mere button press.<br />
<a href="http://www.morethantechnical.com/wp-content/uploads/2011/03/Screen-shot-2011-03-14-at-12.03.26-AM.png" rel="lightbox[844]"><img src="http://www.morethantechnical.com/wp-content/uploads/2011/03/Screen-shot-2011-03-14-at-12.03.26-AM-300x111.png" alt="" title="Screen shot 2011-03-14 at 12.03.26 AM" width="300" height="111" class="aligncenter size-medium wp-image-849" /></a></p>
<p>The &#8220;tsv&#8221; (tab separated values) file has a simple format: <code>&lt;song name&gt; &lt;artist&gt; &lt;Last.fm url&gt;</code></p>
<p>And now for the script, first, the loved tracks file is tab separated, so we use AWK to get the 2 first fields which are song-name and song-artist.<br />
Then we use a neat command-line tool to download YT movies: <a href="http://rg3.github.com/youtube-dl/documentation.html">http://rg3.github.com/youtube-dl/documentation.html</a>.</p>
<pre class="brush: plain; title: ; notranslate">
mkdir mylovedtracks
cd mylovedtracks
awk -F\t '{print &quot;../youtube-dl.py -f 18 -t \&quot;ytsearch:&quot; $1 &quot; &quot; $2 &quot;\&quot;&quot;}' ../my_lovedtracks.tsv | csh
</pre>
<p>The single-liner will download all the loved tracks from the tsv file into the current directory, given that <code>youtube-dl.py &#038; my_lovedtracks.tsv</code> exist in the parent directory. <code>-f 18</code> says it will download only MP4s and <code>ytsearch</code> says it will try to search YT for the term &#8220;song-name song-artist&#8221; and download the 1st result. The <code>| csh</code> says it will send this command AWK formatted into a new shell process.</p>
<p>The saved MP4 will be named after the name of the video, with addition of the YT hash string.</p>
<p>All the mp4s have been downloaded, so let&#8217;s batch convert them to mp3s:</p>
<pre class="brush: plain; title: ; notranslate">
mkdir sound
for f in *.mp4 ; do n=`echo $f | cut -d '.' -f1`; if [ ! -e sound/$n.mp3 ]; then `mplayer $n.mp4 -vc dummy -vo null -ao pcm:file=sound/temp.wav; lame -V2 sound/temp.wav sound/$n.mp3; rm sound/temp.wav`; fi ; done
</pre>
<p>This single-liner will extract audio from the mp4 into a PCM temp.wav file using MEncoder, and then convert to VBR MP3 using Lame.<br />
You can run this command many times, as it checks if the file has not been converted yet. So you&#8217;re impatient (like me) on converting some of the MP4s before everything was downloaded &#8211; just run it, and later run it again.</p>
<p>Congrats, all your loved tracks were downloaded.</p>
<p>A few limitation to this method:<br />
* Sometimes downloaded songs are not exactly what you wanted, especially specific versions. The search is arbitrary, and can&#8217;t be controlled too much.<br />
* ID3 tags are non existent, although something can probably be done about that in the Lame encoding phase.<br />
* Very high potential for parallelization that is unexploited. Mostly in the YT download phase, where YT pushes the first ~15% of the video very fast (I saw 1200Kb/s even), and then maintains a steady d/l rate to get the video downloaded by ~1:00 minute (may be as low as 50Kb/s). Downloading many videos at once could help.<br />
* Still not a true single-liner, it is a two-step thing. But that can be done by modifying the 2nd step a bit and putting into the AWK print of the 1st step.<br />
* MP3&#8242;s volume normalization &#8211; very important! else every songs sounds different and you must do vol-up vol-down all the time&#8230;</p>
<p>Still, did a nice quick job for me&#8230;</p>
<p>Roy.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.morethantechnical.com%2F2011%2F03%2F14%2Fdownload-all-you-last-fm-loved-tracks-in-a-single-command%2F&amp;title=Download%20all%20your%20Last.fm%20loved%20tracks%20in%20two%20simple%20steps" id="wpa2a_10"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2011/03/14/download-all-you-last-fm-loved-tracks-in-a-single-command/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Some things I learned about Android&#8217;s Frame animation</title>
		<link>http://www.morethantechnical.com/2011/02/07/some-things-i-learned-about-androids-frame-animation/</link>
		<comments>http://www.morethantechnical.com/2011/02/07/some-things-i-learned-about-androids-frame-animation/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 07:09:21 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Mobile phones]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mogrify]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=804</guid>
		<description><![CDATA[Hi Just a quick share of lessons learned about Android&#8217;s Frame-by-Frame animations. Some of the functionality is poorly documented, as many people point out, so the web is the only place for answers. Having looked for some answers to these questions and couldn&#8217;t find any &#8211; here&#8217;s what I found out myself. Update [2/3/11]: A [...]]]></description>
			<content:encoded><![CDATA[<p>Hi</p>
<p>Just a quick share of lessons learned about Android&#8217;s Frame-by-Frame animations. Some of the functionality is poorly documented, as many people point out, so the web is the only place for answers. Having looked for some answers to these questions and couldn&#8217;t find any &#8211; here&#8217;s what I found out myself.</p>
<p>Update [2/3/11]: A <a href="http://www.morethantechnical.com/2011/03/01/the-woes-of-frame-animation-on-android-w-code/">new post</a> on this topic gives a more broad view of my experience.<br />
<span id="more-804"></span></p>
<h2>Resetting Frame Animation</h2>
<p>The API is a bit weird here, because the restart function is inside the setVisible function of AnimationDrawable. If you don&#8217;t restart and just do another <code>start()</code> on an already finished animation &#8211; it will just jump to the last frame. You must reset the animation before starting it.</p>
<p>However if you do <code>setVisible(true,true)</code> your animation will run twice!, so you must do <code>setVisible(false,true);</code>. This will reset the animation for a <code>start()</code> operation.</p>
<h2>Preloading Animations</h2>
<p>I got to preloading animations after understating that trying to fire an animation &#8220;right off the XML&#8221;, has a lag of over a second. This must be due to the inflation process. And I was looking for snappy smooth animations right away, without waiting for them to inflate, so naturally I needed to preload them. But how?</p>
<p>So I loaded the frame animation into an ImageView with <code>android:visibility="gone"</code>, and &#8220;hijacked&#8221; its drawable when I needed to fire it:</p>
<p>The XML, just put it somewhere in your main xml so it will be inflated when the app starts.</p>
<pre class="brush: plain; title: ; notranslate">
&lt;!-- Preload animations --&gt;
&lt;ImageView android:id=&quot;@+id/anim_preloaded_imgview&quot;
	android:layout_width=&quot;wrap_content&quot;
	android:layout_height=&quot;wrap_content&quot;
	android:src=&quot;@drawable/myanim&quot;
	android:visibility=&quot;gone&quot; /&gt;
</pre>
<p>The Java:</p>
<pre class="brush: plain; title: ; notranslate">
ImageView animateHere = (ImageView) findViewById(R.id.animate_here);
animateHere.setImageDrawable(((ImageView)findViewById(R.id.anim_preloaded_imgview).getDrawable());
AnimationDrawable anim = (AnimationDrawable) animateHere.getDrawable();
anim.setVisible(false, true); //reset! see previous section
anim.start(); //now good to start, even if already fired before
</pre>
<p>Voila.</p>
<h2>OutOfMemory expection? srsly?</h2>
<p>So at the beginning I was getting a lot of OutOfMemory exceptions on the loading of the animations. Probably due to loading many big bitmaps into the memory. So I reduced the size of my PNGs to ~80,000 pixels (images are ~200&#215;400), and then I was able to load as many as I wanted! Strange&#8230;<br />
I didn&#8217;t really research what&#8217;s the limit, but using ~140,000 pixels did not fly.</p>
<p>In these cases <code>mogrify</code> is your friend. This will resize all images beginning with &#8220;myanim&#8221; to 200xWhatever keeping aspect ratio:</p>
<pre class="brush: plain; title: ; notranslate">
mogrify -resize 200 myanim*
</pre>
<p>That&#8217;s it for now<br />
But tomorrow I will learn more. Android is surprising..</p>
<p>Please comment if you [dis]agree, and share your own experience!<br />
Roy.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.morethantechnical.com%2F2011%2F02%2F07%2Fsome-things-i-learned-about-androids-frame-animation%2F&amp;title=Some%20things%20I%20learned%20about%20Android%26%238217%3Bs%20Frame%20animation" id="wpa2a_12"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2011/02/07/some-things-i-learned-about-androids-frame-animation/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hacking together a Kinect port</title>
		<link>http://www.morethantechnical.com/2010/11/20/hacking-together-a-kinect-port/</link>
		<comments>http://www.morethantechnical.com/2010/11/20/hacking-together-a-kinect-port/#comments</comments>
		<pubDate>Sat, 20 Nov 2010 19:42:05 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[12v]]></category>
		<category><![CDATA[5v]]></category>
		<category><![CDATA[adapter]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[kinect]]></category>
		<category><![CDATA[usb]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=734</guid>
		<description><![CDATA[Create a DIY Kinect USB &#038; Power adapter.]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">Hi,<br />
<a href="http://www.morethantechnical.com/wp-content/uploads/2010/11/2010-11-19-15.50.44.jpg" rel="lightbox[734]"><img class="alignleft size-medium wp-image-749" title="SAMSUNG" src="http://www.morethantechnical.com/wp-content/uploads/2010/11/2010-11-19-15.50.44-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p style="text-align: left;">Just a quicky on how I hacked together a DIY Microsoft Kinect port. The Kinect port is non standard, USB-like port, and to actually connect it to a PC you must buy an adapter from microsoft for &gt;30$. This is whack. You should make your own. All you need is access to a lasercutter, vinylcutter, plexiglass 1/8&#8243;, some copper sheet and solder equip.<br />
<span id="more-734"></span><br />
So basically cut a piece of plexi that looks like this:<br />
<a href="http://www.morethantechnical.com/wp-content/uploads/2010/11/kinect_plexi.png" rel="lightbox[734]"><img class="size-medium wp-image-745 aligncenter" title="kinect_plexi" src="http://www.morethantechnical.com/wp-content/uploads/2010/11/kinect_plexi-224x300.png" alt="" width="224" height="300" /></a></p>
<p style="text-align: left;">And print a piece of copper in the vinyl cutter that looks like this:<br />
<a href="http://www.morethantechnical.com/wp-content/uploads/2010/11/KINECT.png" rel="lightbox[734]"><img class="aligncenter size-medium wp-image-755" title="KINECT" src="http://www.morethantechnical.com/wp-content/uploads/2010/11/KINECT-300x300.png" alt="" width="300" height="300" /></a><br />
This is the upper and lower pins of the Kinect port, I got from <a href="http://forums.xbox-scene.com/index.php?showtopic=723561&amp;pid=4753968&amp;mode=threaded&amp;show=&amp;st=&amp;#entry4753968">here</a>.</p>
<p style="text-align: left;">Then I pasted the cut copper on the plexi.<br />
<a href="http://www.morethantechnical.com/wp-content/uploads/2010/11/2010-11-19-15.53.36.jpg" rel="lightbox[734]"><img class="size-medium wp-image-747 aligncenter" title="SAMSUNG" src="http://www.morethantechnical.com/wp-content/uploads/2010/11/2010-11-19-15.53.36-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p style="text-align: left;">Then I had to solder it properly, I looked at the USB pin layout <a href="http://pinouts.ru/Slots/USB_pinout.shtml">here</a>, and sorted out what pin goes where: 5v VCC to 5v, GND to GND, Data+, Data-, etc..<br />
I also got a 12VDC female connector, to connect an adapter.</p>
<p style="text-align: left;">And came up with this:<br />
<a href="http://www.morethantechnical.com/wp-content/uploads/2010/11/2010-11-19-15.52.59.jpg" rel="lightbox[734]"><img class="aligncenter size-medium wp-image-748" title="SAMSUNG" src="http://www.morethantechnical.com/wp-content/uploads/2010/11/2010-11-19-15.52.59-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p style="text-align: left;">That&#8217;s it.</p>
<p style="text-align: left;"><a href="http://www.morethantechnical.com/wp-content/uploads/2010/11/Screen-shot-2010-11-20-at-2.37.29-PM.png" rel="lightbox[734]"><img class="size-medium wp-image-751 aligncenter" title="Screen shot 2010-11-20 at 2.37.29 PM" src="http://www.morethantechnical.com/wp-content/uploads/2010/11/Screen-shot-2010-11-20-at-2.37.29-PM-300x142.png" alt="" width="300" height="142" /></a></p>
<p style="text-align: left;">Thanks for tuning in,<br />
Roy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/11/20/hacking-together-a-kinect-port/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>An Android solution for listening to online radio while multitasking</title>
		<link>http://www.morethantechnical.com/2010/10/27/an-android-solution-for-listening-to-streamin-radio-while-multitasking-2/</link>
		<comments>http://www.morethantechnical.com/2010/10/27/an-android-solution-for-listening-to-streamin-radio-while-multitasking-2/#comments</comments>
		<pubDate>Wed, 27 Oct 2010 10:57:11 +0000</pubDate>
		<dc:creator>Arnon</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Recommended]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Stream]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=716</guid>
		<description><![CDATA[Android + Yourmuze.fm + Dolphin Browser HD + XiiaLive = WIN It&#8217;s been a while since I&#8217;ve posted anything in the blog… Sorry for that… very busy times. I had a lot of ideas of what my &#8220;comeback post&#8221; should be about, but I knew I had to share one of my relatively recent discoveries [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Android + Yourmuze.fm + Dolphin Browser HD + XiiaLive = WIN<br />
</em></strong></p>
<p><img src="http://www.morethantechnical.com/wp-content/uploads/2010/10/102710_1056_AnAndroidso5.jpg" alt="" align="left" />It&#8217;s been a while since I&#8217;ve posted anything in the blog… Sorry for that… very busy times. I had a lot of ideas of what my &#8220;comeback post&#8221; should be about, but I knew I had to share one of my relatively recent discoveries that made my smartphone online-radio listening experience a whole lot better</p>
<p>If you don&#8217;t know <a href="http://www.yourmuze.fm" target="_blank">yourmuze.fm</a>, this might be the time to get to know it. It&#8217;s a free service that has a LOT of worldwide radio stations available as an online stream for usage with most of the smartphones.</p>
<p>In order to start using it you need to register for free via your desktop computer, and add the stations you like. Later on, you can surf to the <a href="http://m.yourmuze.fm" target="_blank">mobile version</a> of the service by mobile web and listen to the stations you selected.</p>
<p>So far so good… I like it. But how about multitasking?</p>
<p><img src="http://www.morethantechnical.com/wp-content/uploads/2010/10/102710_1056_AnAndroidso3.png" alt="" /><img src="http://www.morethantechnical.com/wp-content/uploads/2010/10/102710_1056_AnAndroidso4.png" alt="" /></p>
<p><span id="more-716"></span></p>
<p>The thing is, if you are an average Android user, and try to use the service, then when you will try to hear the station, it will use the stock <strong>movie player</strong> and will not let you to do anything on your phone while listening to the music.</p>
<p>If you answer a call, or even go to the home screen – Your playback will be stopped, since it must run in the foreground</p>
<p>I have done a small research and discovered a very nice way to make yourmuze run in the background and let you do whatever you like while listening to music.</p>
<p>I use it with my GPS app, listening to online music while navigating.</p>
<p>This is relatively simple.</p>
<ol>
<li><span>Download <a href="market://search?q=pname:mobi.mgeek.TunnyBrowser">Dolphin Browser HD</a> and <a href="market://search?q=pname:com.android.DroidLiveLite">XiiaLive Lite</a> from the market (feel free to buy XiiaLive full if you like it)<br />
</span></li>
<li><span>Open up Dolphin Browser, and hit your phone&#8217;s <strong>Menu</strong> button, then select <strong>More</strong> and then <strong>Settings</strong><br />
</span></li>
<li><span>Scroll down to <strong>User Agent</strong>, and select <strong>iPhone</strong><br />
</span></li>
</ol>
<p>That&#8217;s it!</p>
<p>Go back to the browser, and surf to m.yourmuze.fm and login with your credentials. When you will try to listen to your station you will be able to choose if you want to listen with XiiaLive. I chose it to be default.</p>
<p>There you go. One the station is played you can navigate away from the app and do your multitasking</p>
<p>Hope you will find this post is helpful</p>
<p>Arnon</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.morethantechnical.com%2F2010%2F10%2F27%2Fan-android-solution-for-listening-to-streamin-radio-while-multitasking-2%2F&amp;title=An%20Android%20solution%20for%20listening%20to%20online%20radio%20while%20multitasking" id="wpa2a_14"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/10/27/an-android-solution-for-listening-to-streamin-radio-while-multitasking-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Iterative Closest Point (ICP) for 2D curves with OpenCV [w/ code]</title>
		<link>http://www.morethantechnical.com/2010/06/06/iterative-closest-point-icp-with-opencv-w-code/</link>
		<comments>http://www.morethantechnical.com/2010/06/06/iterative-closest-point-icp-with-opencv-w-code/#comments</comments>
		<pubDate>Sun, 06 Jun 2010 07:59:37 +0000</pubDate>
		<dc:creator>Roy</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[graphics]]></category>
		<category><![CDATA[opencv]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[vision]]></category>
		<category><![CDATA[curve fitting]]></category>
		<category><![CDATA[icp]]></category>
		<category><![CDATA[knn]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=666</guid>
		<description><![CDATA[ICP &#8211; Iterative closest point, is a very trivial algorithm for matching object templates to noisy data. It&#8217;s also super easy to program, so it&#8217;s good material for a tutorial. The goal is to take a known set of points (usually defining a curve or object exterior) and register it, as good as possible, to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.morethantechnical.com/wp-content/uploads/2010/06/icp.png" rel="lightbox[666]"><img src="http://www.morethantechnical.com/wp-content/uploads/2010/06/icp.png" alt="" title="ICP" width="283" height="223" class="alignleft size-full wp-image-669" /></a>ICP &#8211; Iterative closest point, is a very trivial algorithm for matching object templates to noisy data. It&#8217;s also super easy to program, so it&#8217;s good material for a tutorial. The goal is to take a known set of points (usually defining a curve or object exterior) and register it, as good as possible, to a set of other points, usually a larger and noisy set in which we would like to find the object. The basic algorithm is described very briefly in <a href="http://en.wikipedia.org/wiki/Iterative_Closest_Point">wikipedia</a>, but there are a ton of papers on the subject.</p>
<p>I&#8217;ll take you through the steps of programming it with OpenCV.<br />
<span id="more-666"></span><br />
So the algorithm is basically</p>
<ol>
<li>Find the points which are closest to our curve</li>
<li>Compute the best rotation and translation between our points and the closest points</li>
<li>Move our points according to the found transformation, and check the error</li>
<li>Run another iteration until convergence.</li>
</ol>
<p>How easy is that?? OpenCV gives us the tools to do everything in there!</p>
<h2>Finding closest points</h2>
<p>In v2.x of OpCV they introduced the FLANN framework of range search methods. It&#8217;s fairly easy to use, and produces good results, although I did run into some problems with it before. Let&#8217;s see how it&#8217;s used:</p>
<pre class="brush: plain; title: ; notranslate">
float flann_knn(Mat&amp; m_destinations, Mat&amp; m_object, vector&lt;int&gt;&amp; ptpairs, vector&lt;float&gt;&amp; dists = vector&lt;float&gt;()) {
	// find nearest neighbors using FLANN
	cv::Mat m_indices(m_object.rows, 1, CV_32S);
	cv::Mat m_dists(m_object.rows, 1, CV_32F);

	Mat dest_32f; m_destinations.convertTo(dest_32f,CV_32FC2);
	Mat obj_32f; m_object.convertTo(obj_32f,CV_32FC2);

	assert(dest_32f.type() == CV_32F);

	cv::flann::Index flann_index(dest_32f, cv::flann::KDTreeIndexParams(2));  // using 2 randomized kdtrees
    flann_index.knnSearch(obj_32f, m_indices, m_dists, 1, cv::flann::SearchParams(64) ); 

    int* indices_ptr = m_indices.ptr&lt;int&gt;(0);
    //float* dists_ptr = m_dists.ptr&lt;float&gt;(0);
    for (int i=0;i&lt;m_indices.rows;++i) {
   		ptpairs.push_back(indices_ptr[i]);
    }

	dists.resize(m_dists.rows);
	m_dists.copyTo(Mat(dists));

	return cv::sum(m_dists)[0];
}
</pre>
<p>This code was practically ripped off OpenCV&#8217;s sample code, and worked straight up.. You can see I have 2 input matrices that define the &#8220;destination&#8221; points &#8211; these are the unknown, the &#8220;object&#8221; points &#8211; these are our points, and an output vector to mark the correspondence between the two sets. I also have a vector for distances between points of each pair.<br />
I define a FLANN index object using KD-tree and perform a KNN (K nearest neighbors) search on it, for all the object points. After invoking the search function, it&#8217;s all garnish.</p>
<h2>Compute transform</h2>
<p>With the point pairs given, computing the transform between the two sets should be easy. And it is. I started by computing it using least-squares to find the parameters of the transformation: rotation angle, translation in X and Y directions. But my solution was not &#8220;resistant&#8221; to scale, so I looked up another easy solution to the problem, and surely enough a simple solution was found in this <a href="http://www.cs.duke.edu/researchers/artificial_intelligence/temp/eggert_rigid_body_transformations.pdf">paper</a>. </p>
<pre class="brush: plain; title: ; notranslate">
void findBestReansformSVD(Mat&amp; _m, Mat&amp; _d) {
	Mat m; _m.convertTo(m,CV_32F);
	Mat d; _d.convertTo(d,CV_32F);

	Scalar d_bar = mean(d);
	Scalar m_bar = mean(m);
	Mat mc = m - m_bar;
	Mat dc = d - d_bar;

	mc = mc.reshape(1); dc = dc.reshape(1);

	Mat H(2,2,CV_32FC1);
	for(int i=0;i&lt;mc.rows;i++) {
		Mat mci = mc(Range(i,i+1),Range(0,2));
		Mat dci = dc(Range(i,i+1),Range(0,2));
		H = H + mci.t() * dci;
	}

	cv::SVD svd(H);

	Mat R = svd.vt.t() * svd.u.t();
	double det_R = cv::determinant(R);
	if(abs(det_R + 1.0) &lt; 0.0001) {
		float _tmp[4] = {1,0,0,cv::determinant(svd.vt*svd.u)};
		R = svd.u * Mat(2,2,CV_32FC1,_tmp) * svd.vt;
	}
#ifdef BTM_DEBUG
	//for some strange reason the debug version of OpenCV is flipping the matrix
	R = -R;
#endif
	float* _R = R.ptr&lt;float&gt;(0);
	Scalar T(d_bar[0] - (m_bar[0]*_R[0] + m_bar[1]*_R[1]),d_bar[1] - (m_bar[0]*_R[2] + m_bar[1]*_R[3]));

	m = m.reshape(1);
	m = m * R;
	m = m.reshape(2);
	m = m + T;// + m_bar;
	m.convertTo(_m,CV_32S);
}
</pre>
<p>I really just followed what they said in the paper: take the mean point off the two sets, build a correlation matrix from the distances, do <a href="http://en.wikipedia.org/wiki/Singular_value_decomposition">SVD</a> and use U and Vt for computing the rotation and translation. It actually works!</p>
<h2>Putting it together</h2>
<p>This is the easy part, just using these two functions and small while loop:</p>
<pre class="brush: plain; title: ; notranslate">
	while(true) {
		pair.clear(); dists.clear();
		double dist = flann_knn(destination, X, pair, dists);

		if(lastDist &lt;= dist) {
			X = lastGood;
			break;	//converged?
		}
		lastDist = dist;
		X.copyTo(lastGood);

		cout &lt;&lt; &quot;distance: &quot; &lt;&lt; dist &lt;&lt; endl;

		Mat X_bar(X.size(),X.type());
		for(int i=0;i&lt;X.rows;i++) {
			Point p = destination.at&lt;Point&gt;(pair[i],0);
			X_bar.at&lt;Point&gt;(i,0) = p;
		}

		ShowQuery(destination,X,X_bar);

		X = X.reshape(2);
		X_bar = X_bar.reshape(2);
		findBestReansformSVD(X,X_bar);
		X = X.reshape(1); // back to 1-channel
	}
</pre>
<p>This will iteratively search for points and move the curve until the curve doesn&#8217;t move anymore.</p>
<h2>Some proof</h2>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/0eBpBxCaYpE&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/0eBpBxCaYpE&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<h2>Code</h2>
<p>Available in the SVN repo:</p>
<pre class="brush: plain; title: ; notranslate">
svn checkout https://morethantechnical.googlecode.com/svn/trunk/ICP ICP
</pre>
<p>Thanks for joining!<br />
Roy.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.morethantechnical.com%2F2010%2F06%2F06%2Fiterative-closest-point-icp-with-opencv-w-code%2F&amp;title=Iterative%20Closest%20Point%20%28ICP%29%20for%202D%20curves%20with%20OpenCV%20%5Bw%2F%20code%5D" id="wpa2a_16"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/06/06/iterative-closest-point-icp-with-opencv-w-code/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Stream your favorite radio station to your workplace</title>
		<link>http://www.morethantechnical.com/2010/01/29/stream-your-favorite-radio-station-to-your-workplace/</link>
		<comments>http://www.morethantechnical.com/2010/01/29/stream-your-favorite-radio-station-to-your-workplace/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 14:53:00 +0000</pubDate>
		<dc:creator>Arnon</dc:creator>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Stream]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[block]]></category>
		<category><![CDATA[bypass]]></category>
		<category><![CDATA[corporate]]></category>
		<category><![CDATA[re-stream]]></category>
		<category><![CDATA[vlc]]></category>
		<category><![CDATA[worksplace]]></category>

		<guid isPermaLink="false">http://www.morethantechnical.com/?p=567</guid>
		<description><![CDATA[I want to suggest a trick that worked for me. My work place blocks most of the popular radio stations stream sites in my country. I can understand why they&#8217;re doing that, but hey – if you want to save bandwidth I suggest you block YouTube (not that I complain…) Well, I thought of a [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">I want to suggest a trick that worked for me. My work place blocks most of the popular radio stations stream sites in my country.<br />
I can understand why they&#8217;re doing that, but hey – if you want to save bandwidth I suggest you block YouTube (not that I complain…)<br />
Well, I thought of a way to listen to my favorite radio station from work, by re-streaming it from my home. And it worked!</p>
<p style="text-align: left;">It can also work for you, in case your IT does not block by protocol, only by address.</p>
<p style="text-align: left;">So here&#8217;s how to do it:</p>
<p style="text-align: left;"><span id="more-567"></span></p>
<h2 style="text-align: left;">STEP 1 – Retrieve the actual link for your radio station</h2>
<p style="text-align: left;">Go to the station&#8217;s website and try to get a link that you can play in Windows Media Center.<br />
Some stations will let you find it, others won&#8217;t.<br />
If this is the case, here&#8217;s what you need to do (At home!)</p>
<ol style="text-align: left;">
<li>
<div style="text-align: justify;">Download <a href="http://www.wireshark.org/">wireshark</a> and install it</div>
</li>
<li>
<div style="text-align: justify;">Start capturing using this filter: <strong>rtsp.request</strong></div>
</li>
<li>
<div style="text-align: justify;">Try to listen to the station</div>
</li>
<li>
<div style="text-align: justify;">You should see such an output in wireshark:</div>
<p style="text-align: right;"><img class="alignleft" src="http://www.morethantechnical.com/wp-content/uploads/2010/01/012910_1452_Streamyourf1.png" alt="" /></p>
<p style="text-align: left;">As you can see, there is a url here that looks like this:<br />
<strong>rtsp://someurl/somefile RTSP/1.0</strong></p>
</li>
<li>Take this URL, and replace <strong>RTSP</strong> with <strong>MMS</strong> and omit the <strong>RTSP/1.0</strong> ending.<br />
Your URL should look like this: <a href="mms://someurl.somefile">mms://someurl.somefile</a></li>
<li>
<div style="text-align: justify;">Try to play this URK in windows media player. If it works – you&#8217;re half way through</div>
</li>
</ol>
<p style="text-align: left;">If you can get the link in any other way, it&#8217;s fine… This is only a suggestion</p>
<p style="text-align: left;"> </p>
<h2 style="text-align: left;">STEP 2 – Set up VLC as a stream server at your home</h2>
<p style="text-align: left;">I will start with an apology. I didn&#8217;t find a proper way to do it with the GUI of version 1.0+.<br />
On the past versions it was relatively clear, so that&#8217;s where I managed to find the command line you need to run in order for it to work<br />
So, at this point, you need to run <a href="http://www.videolan.org/">VLC</a> on your PC with these parameters:</p>
<p style="text-align: left;"><span style="font-family: Courier New;">vlc mms://yourserver/yourlink :sout=#transcode{acodec=mp3,ab=64,channels=2}:duplicate{dst=std{access=mmsh,mux=asfh,dst=:8080}}<br />
</span></p>
<p style="text-align: left;">This will stream the web-radio station to port 8080.<br />
You can test this using Windows Media Player, just open it up, and open the url <a href="mms://localhost:8080">mms://localhost:8080</a></p>
<p style="text-align: left;">Another thing you need to keep in mind, is that you should establish port forwarding if you are behind NAT.</p>
<p style="text-align: left;"> That&#8217;s the whole deal… Of course you can improve it by creating a script that will run it, or add the http interface of VLC to remote control it on another port, but I don&#8217;t want to overload this guide…</p>
<p style="text-align: left;">keep it simple!</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.morethantechnical.com%2F2010%2F01%2F29%2Fstream-your-favorite-radio-station-to-your-workplace%2F&amp;title=Stream%20your%20favorite%20radio%20station%20to%20your%20workplace" id="wpa2a_18"><img src="http://www.morethantechnical.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.morethantechnical.com/2010/01/29/stream-your-favorite-radio-station-to-your-workplace/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

