<?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>tdistler.com &#187; programming</title>
	<atom:link href="http://tdistler.com/tag/programming/feed" rel="self" type="application/rss+xml" />
	<link>http://tdistler.com</link>
	<description>&#34;To err is human, but to really foul things up you need a computer.”</description>
	<lastBuildDate>Tue, 06 Dec 2011 20:46:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Eubonicode++: Hackin C++ Gangsta Style</title>
		<link>http://tdistler.com/2011/12/03/eubonicode-hackin-c-gangsta-style</link>
		<comments>http://tdistler.com/2011/12/03/eubonicode-hackin-c-gangsta-style#comments</comments>
		<pubDate>Sat, 03 Dec 2011 16:00:02 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[funny]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=1077</guid>
		<description><![CDATA["Foshizzle" is a modified version of the Clang compiler which supports Eubonicode++ (an alternate C++ syntax). Foshizzle supports all the existing features of Clang, but with extensions to more fully express your gansta style. All the regular C++ syntax still works, but you can now substitute Eubonicode++ keywords and operators.]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2011/12/Bjarne_foshizzle.jpg"><img class="alignright size-thumbnail wp-image-1078" title="A small part of me died doing this to Bjarne, but I couldn't resist." src="http://tdistler.com/wp-content/uploads/2011/12/Bjarne_foshizzle-150x150.jpg" alt="A little part of me died doing this to Bjarne, but I couldn't resist." width="150" height="150" /></a></p>
<p>&#8220;Foshizzle&#8221; is a modified version of the <a title="Clang Compiler" href="http://clang.llvm.org/" target="_blank">Clang</a> compiler which supports Eubonicode++ (an alternate C++ syntax). Foshizzle supports all the existing features of Clang, but with extensions to more fully express your gansta style. All the regular C++ syntax still works, but you can now substitute Eubonicode++ keywords and operators (see below).</p>
<p>Here&#8217;s a sample method that calculates factorials (Note: the semicolons can be replaced with a certain expletive):</p>
<pre>int factorialz(int n)
{
    int rezult be 1;
    slongas (n bepimpin 0)
    {
        rezult be rezult dimes n;
        dissin n;
    }
    putou rezult;
}</pre>
<p>&nbsp;</p>
<p>I can&#8217;t take all the credit. I was inspired by the Iowa State students that first created Eubonicode (webpage no longer available).</p>
<p>Here are my Clang modifications:<a title="Eubonicode++ Clang modifications" href="http://tdistler.com/media/code/eubonicode/ebpp-clang30rc4.patch" target="_blank"> ebpp-clang30rc4.patch</a></p>
<p>Build instructions are near the end of this post.<span id="more-1077"></span></p>
<h2>How It Happened</h2>
<p>I periodically venture off into the h4x0r wilderness and pour myself into some random project. It always starts out innocently enough, but the project soon takes on a life of it’s own. This time was no different&#8230; except it happened over Thanksgiving (much to my wife’s chagrin).</p>
<p>Being the charismatic socialite that I am (sarcasm), I was digging through the C++11 spec on Thanksgiving. What struck me was how much of my language design course I had forgotten, and it really bugged me. It&#8217;s one of those required courses in the CompSci graduate program that I loathed having to take, but turned out to be invaluable (don’t get me started on the database and UI design courses&#8230; blah).</p>
<p>Long story less long, I started refreshing on compilers (<a title="Rich Programmer Food" href="http://steve-yegge.blogspot.com/2007/06/rich-programmer-food.html" target="_blank">read this</a> for inspiration). I’d heard about Clang and <a title="LLVM" href="http://llvm.org/" target="_blank">LLVM</a> awhile ago, and I remembered their focus on modularity, maintainability, and all sorts of other *ability’s. I figured it&#8217;d be a good place to start, so I download the source code and dug through it (watch <a title="Clang Video" href="http://clang.llvm.org/clang_video-05-25-2007.html" target="_blank">this video</a> for background on Clang).</p>
<p>Stepping through Clang in a debugger sounded like a great way to start, but I quickly had mental stack overflow through the recursive parsing code. Okay, time for plan B. Common wisdom says that a good way to learn a piece of code is to try and fix a bug. So I went to the Clang bug list looking for a starter task, but all the “interesting” tasks were way too large in scope for a Clang newb like me.</p>
<p>Time to invent plan C: make a small tweak to the language and see if I can get it working. I remembered a few years ago that some students from Iowa State built an Eubonicode compiler for a language class they had. It got quite a few laughs around the office and was always wishing for a working compiler. So I decided take their idea and replace ‘<code>while</code>’ with ‘<code>slongas</code>’&#8230; and an hour later I had it working (which is testament to the readability of the Clang code&#8230; it’s very well commented).</p>
<p>Not satisfied to stop there, I moved on to other keywords&#8230; simple, once you get comfortable with how the code’s laid out. &#8220;What about operators and punctuators?&#8221;, I wondered. After a few failed attempts, it dawned on me that C++ has aliases for operators (‘<code>and_eq</code>’ can be used in place of ‘<code>&amp;=</code>’, etc). Instead of heavily modifying the parser/lexer, I started looking for how Clang handled these aliases&#8230; maybe I could just add some more. Turns out, it fairly simple to add new aliases, so ‘<code>==</code>’ got overloaded with ‘<code>sameas</code>’, ‘<code>!=</code>’ got overloaded with ‘<code>aint</code>’, etc&#8230; and it worked! Sweet!</p>
<p>After all that, I dug a little into the preprocessor and figured out how to support ‘<code>#mahomie</code>’ in place of ‘<code>#include</code>’. Simple enough. I dug a little into the build stuff and changed the name from ‘clang’ to ‘foshizzle’&#8230; cool. I little bit of frustration later, and I had it recognizing ‘*.opp’ and ‘*.ho’ as source and header files, respectively.</p>
<p>Three days after I started, I had a fully functional Eubonicode++ compiler and a lot deeper understanding of how a production C++ compiler works. I can’t stress enough that this project would never have happened if the Clang code wasn’t written so well. Kudos to the Clang team.</p>
<p>I really enjoyed this project, and I hope you get half the fun out of it I did. Next time you have a coding task, consider adding a litta gansta sizzle <img src='http://tdistler.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h2>C++ To Eubonicode++ Mapping</h2>
<p>&nbsp;</p>
<table style="text-align: center;" width="400" border="0">
<tbody>
<tr>
<th>C++</th>
<th>Eubonicode++</th>
<th>|</th>
<th>C++</th>
<th>Eubonicode++</th>
</tr>
<tr>
<td><code>#include</code></td>
<td><code>#mahomie</code></td>
<td>|</td>
<td><code>switch</code></td>
<td><code>whatchugondo</code></td>
</tr>
<tr>
<td><code>break</code></td>
<td><code>bustanut</code></td>
<td>|</td>
<td><code>this</code></td>
<td><code>dis</code></td>
</tr>
<tr>
<td><code>case</code></td>
<td><code>ifa</code></td>
<td>|</td>
<td><code>throw</code></td>
<td><code>throz</code></td>
</tr>
<tr>
<td><code>catch</code></td>
<td><code>wrekdit</code></td>
<td>|</td>
<td><code>true</code></td>
<td><code>tru</code></td>
</tr>
<tr>
<td><code>char</code></td>
<td><code>alphabizzle</code></td>
<td>|</td>
<td><code>try</code></td>
<td><code>checkit</code></td>
</tr>
<tr>
<td><code>class</code></td>
<td><code>claz</code></td>
<td>|</td>
<td><code>typedef</code></td>
<td><code>reprezentin</code></td>
</tr>
<tr>
<td><code>const</code></td>
<td><code>foodonchange</code></td>
<td>|</td>
<td><code>using</code></td>
<td><code>uzin</code></td>
</tr>
<tr>
<td><code>continue</code></td>
<td><code>mo</code></td>
<td>|</td>
<td><code>virtual</code></td>
<td><code>frontin</code></td>
</tr>
<tr>
<td><code>delete</code></td>
<td><code>cap</code></td>
<td>|</td>
<td><code>void</code></td>
<td><code>shiznit</code></td>
</tr>
<tr>
<td><code>else</code></td>
<td><code>elz</code></td>
<td>|</td>
<td><code>volatile</code></td>
<td><code>trippin</code></td>
</tr>
<tr>
<td><code>export</code></td>
<td><code>bounce</code></td>
<td>|</td>
<td><code>while</code></td>
<td><code>slongas</code></td>
</tr>
<tr>
<td><code>extern</code></td>
<td><code>othahood</code></td>
<td>|</td>
<td><code>;</code></td>
<td><code>bitch</code> or <code>biatch</code></td>
</tr>
<tr>
<td><code>false</code></td>
<td><code>falz</code></td>
<td>|</td>
<td><code>=</code></td>
<td><code>be</code></td>
</tr>
<tr>
<td><code>float</code></td>
<td><code>flo</code></td>
<td>|</td>
<td><code>==</code></td>
<td><code>sameas</code></td>
</tr>
<tr>
<td><code>for</code></td>
<td><code>fo</code></td>
<td>|</td>
<td><code>!=</code></td>
<td><code>aint</code></td>
</tr>
<tr>
<td><code>friend</code></td>
<td><code>homie</code></td>
<td>|</td>
<td><code>+</code></td>
<td><code>an</code></td>
</tr>
<tr>
<td><code>long</code></td>
<td><code>shlong</code></td>
<td>|</td>
<td><code>-</code></td>
<td><code>widout</code></td>
</tr>
<tr>
<td><code>namespace</code></td>
<td><code>namespaze</code></td>
<td>|</td>
<td><code>*</code></td>
<td><code>dimes</code></td>
</tr>
<tr>
<td><code>new</code></td>
<td><code>makea</code></td>
<td>|</td>
<td><code>/</code></td>
<td><code>videdby</code></td>
</tr>
<tr>
<td><code>private</code></td>
<td><code>nonyobiz</code></td>
<td>|</td>
<td><code>&gt;</code></td>
<td><code>bepimpin</code></td>
</tr>
<tr>
<td><code>protected</code></td>
<td><code>indafamily</code></td>
<td>|</td>
<td><code>&lt;</code></td>
<td><code>fearin</code></td>
</tr>
<tr>
<td><code>public</code></td>
<td><code>tweetdat</code></td>
<td>|</td>
<td><code>++</code></td>
<td><code>propsta</code></td>
</tr>
<tr>
<td><code>return</code></td>
<td><code>putou</code></td>
<td>|</td>
<td><code>--</code></td>
<td><code>dissin</code></td>
</tr>
</tbody>
</table>
<ul>
<li> *.cpp -&gt; *.opp</li>
<li>*.h -&gt; *.ho</li>
</ul>
<p>Many thanks to <a href="https://plus.google.com/s/sean%20tegtmeyer" target="_blank">Sean Tegtmeyer</a> for helping with the syntax definition.</p>
<h2>Building Foshizzle</h2>
<p>I <em>highly</em> suggest building Clang <strong>without</strong> my changes first and verify that you have it working correctly. Then it should be simple to apply my patch and rebuild. I did all my work on Fedora 16, so your mileage may vary on other distros or OSes.</p>
<p><strong>Note</strong>: If you have any problems building LLVM or Clang, please refer to their build page: <a title="Clang: Getting Started" href="http://clang.llvm.org/get_started.html" target="_blank">Getting Started</a></p>
<ol>
<li>Create a new directory (e.g. &#8220;foshizzle&#8221;).</li>
<li>Within the &#8220;foshizzle&#8221; directory, create the following directories: &#8220;build&#8221;, &#8220;src&#8221;, &#8220;install&#8221;</li>
<li>Checkout the LLVM source code into the &#8220;src&#8221; directory:</li>
<ul>
<li><code>svn co http://llvm.org/svn/llvm-project/llvm/tags/RELEASE_30/rc4 ./src</code></li>
</ul>
<li>Create a new directory for the Clang source within the LLVM &#8220;tools&#8221; directory:</li>
<ul>
<li><code>mkdir src/tools/clang</code></li>
</ul>
<li>Checkout the Clang source code into the &#8220;src/tools/clang&#8221; directoy:</li>
<ul>
<li><code>svn co http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_30/rc4 ./src/tools/clang</code></li>
</ul>
<li>Change directories into the &#8220;build&#8221; directory.</li>
<li>Configure the Clang/LLVM build and point it to the &#8220;install&#8221; directory you created earlier:</li>
<ul>
<li><code>../src/configure --prefix=&lt;path&gt;/&lt;to&gt;/&lt;foshizzle&gt;/install</code></li>
</ul>
<li>Build (takes quite a while): <code>make</code></li>
<li>Install: <code>make install</code></li>
<li>Compile some test code to make sure it works: <code>install/bin/clang++ yourtestcode.cpp</code></li>
</ol>
<p><strong>Only</strong> continue on once the unmodified version of Clang is working.</p>
<ol>
<li>Download my patch file: <a href="http://tdistler.com/media/code/eubonicode/ebpp-clang30rc4.patch" target="_blank">ebpp-clang30rc4.patch</a></li>
<li>Change directories to where the Clang source is (src/tools/clang).</li>
<li>Apply the patch: <code>patch -p0 -i ebpp-clang30rc4.patch</code></li>
<li>Change back to the &#8220;build&#8221; directory.</li>
<li>Build: <code>make</code></li>
<li>Install: <code>make install</code></li>
<li>Test: <code>install/bin/foshizzle++ yordopecodez.opp</code></li>
</ol>
<p>You can also build the sample code below.</p>
<h2>Sample Code</h2>
<p><a href="http://tdistler.com/media/code/eubonicode/baseclaz.ho" target="_blank">baseclaz.ho</a>, <a href="http://tdistler.com/media/code/eubonicode/friendclaz.ho" target="_blank">friendclaz.ho</a>, <a href="http://tdistler.com/media/code/eubonicode/main.opp" target="_blank">main.opp</a></p>
<p><strong>Building</strong></p>
<pre>install/bin/foshizzle++ main.opp</pre>
<p>&nbsp;</p>
<p><strong>Program Output</strong></p>
<pre>baseclaz: protected = 1, private = 1
derivedclaz: protected = 0, private = 1
friendclaz: friend private = 0

Factorial(7) = 5040</pre>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/12/03/eubonicode-hackin-c-gangsta-style/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CRC32: A Simple C++ Class</title>
		<link>http://tdistler.com/2011/06/22/crc32-a-simple-c-class</link>
		<comments>http://tdistler.com/2011/06/22/crc32-a-simple-c-class#comments</comments>
		<pubDate>Wed, 22 Jun 2011 17:32:51 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=993</guid>
		<description><![CDATA[A simple C++ class for calculating CRC32.]]></description>
			<content:encoded><![CDATA[<p><a title="Wikipedia: Cyclic Redundancy Check" href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check" target="_blank">Cyclic Redundancy Checks</a> are a quick and convenient way to verify if a data set has changed. They are not meant to be &#8220;secure&#8221; like a MD5 or SHA-1, but they offer a very practical solution to most problems. CRC&#8217;s are also useful for verifying if 2 data sets are equal. Here&#8217;s a simple class I use that&#8217;s efficient. Honestly, I don&#8217;t remember what flavor of CRC32 it implements (sorry), but it has always worked for what I&#8217;ve needed. Cheers!</p>
<pre><code>static const uint32_t kCrc32Table[256] = {
    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
    0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
    0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
    0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
    0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
    0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
    0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
    0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
    0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
    0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
    0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
    0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,<span id="more-993"></span>
    0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
    0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
    0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
    0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
    0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
    0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
    0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
    0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
    0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
    0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
    0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
    0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
    0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
    0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
    0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
    0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
    0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
    0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
    0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
    0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
    0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
    0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
    0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
    0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
    0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
    0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
    0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
    0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
    0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
    0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
    0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
    0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
}; // kCrc32Table

class Crc32
{
public:
    Crc32() { Reset(); }
    ~Crc32() throw() {}
    void Reset() { _crc = (uint32_t)~0; }
    void AddData(const uint8_t* pData, const uint32_t length)
    {
        uint8_t* pCur = (uint8_t*)pData;
        uint32_t remaining = length;
        for (; remaining--; ++pCur)
            _crc = ( _crc &gt;&gt; 8 ) ^ kCrc32Table[(_crc ^ *pCur) &amp; 0xff];
    }
    const uint32_t GetCrc32() { return ~_crc; }

private:
    uint32_t _crc;
};

</code></pre>
<p><strong>Note</strong>: I always have <code>uint32_t</code> defined in Windows, so you may have to define it yourself or use the Microsoft intrinsic <code>unsigned __int32</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/06/22/crc32-a-simple-c-class/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Live555: Compiling with VS2008</title>
		<link>http://tdistler.com/2011/05/14/live555-compiling-with-vs2008</link>
		<comments>http://tdistler.com/2011/05/14/live555-compiling-with-vs2008#comments</comments>
		<pubDate>Sat, 14 May 2011 18:30:49 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[live555]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=959</guid>
		<description><![CDATA[4 easy steps to compile Live555 using VS2008. Fixes link error: LNK1181: cannot open input file 'msvcirt.lib'.]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2011/02/network.jpg"><img class="alignright size-thumbnail wp-image-795" title="network" src="http://tdistler.com/wp-content/uploads/2011/02/network-150x150.jpg" alt="" width="100" height="100" /></a>Compiling <a title="Live555 Streaming Media" href="http://www.live555.com/liveMedia/" target="_blank">Live555 Streaming Media</a> with Visual Studio 2008 isn&#8217;t obvious. Using Cygwin or MinGW is just a pain and frankly unnecessary. There is no built-in support for VS solution files, because Windows support is a low priority for the Live555 community. This is evidenced by <a title="Live555 Forum" href="http://lists.live555.com/pipermail/live-devel/2008-January/008022.html" target="_blank">this forum response</a> from Ross Finlayson:</p>
<blockquote><p><em>&gt;4.  Is it possible to include a Visual Studio solution in the</em><br />
<em> &gt;distrubution to make it more convenient for Windows developers to</em><br />
<em> &gt;use live555?</em><br />
<em> &gt;5.  Is it possible for live555 to generate adequate makefiles for</em><br />
<em> &gt;Windows systems with development environments newer than Visual</em><br />
<em> &gt;Studio 2003?</em></p>
<p><strong>I have no current plans to change this.  (These days, fewer and fewer</strong> <strong>people seem to be using Windows for development of system software.)</strong></p></blockquote>
<p>Regardless, Live555 works fine on Windows and is actually quite easy to build. Simply do the following:</p>
<ol>
<li>Open the &#8216;win32config&#8217; file and change the <code>TOOLS32=... </code>variable to your VS2008 install directory. For me, it&#8217;s <code>TOOLS32=C:\Program Files\Microsoft Visual Studio 9.0\VC</code></li>
<li>In &#8216;win32config&#8217;, modify the <code>LINK_OPTS_0=...</code> line from <code>msvcirt.lib</code> to <code>msvcrt.lib</code>. This fixes the link error:<br />
<code>LINK : fatal error LNK1181: cannot open input file 'msvcirt.lib'</code></li>
<li>Open the Visual Studio command prompt.</li>
<li>From the &#8216;live&#8217; source directory, run <code>genWindowsMakefiles</code></li>
<li>Now you&#8217;re ready to build. Simply run the following commands:
<pre><code>cd liveMedia
nmake /B -f liveMedia.mak
cd ..\groupsock
nmake /B -f groupsock.mak
cd ..\UsageEnvironment
nmake /B -f UsageEnvironment.mak
cd ..\BasicUsageEnvironment
nmake /B -f BasicUsageEnvironment.mak
cd ..\testProgs
nmake /B -f testProgs.mak
cd ..\mediaServer
nmake /B -f mediaServer.mak</code></pre>
</li>
</ol>
<p>That&#8217;s it. You should be good to go.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/05/14/live555-compiling-with-vs2008/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Lua: Get CPU Load on Linux</title>
		<link>http://tdistler.com/2011/05/02/lua-get-cpu-load-on-linux</link>
		<comments>http://tdistler.com/2011/05/02/lua-get-cpu-load-on-linux#comments</comments>
		<pubDate>Tue, 03 May 2011 00:07:01 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=951</guid>
		<description><![CDATA[Here's a Lua function that returns the percentage of CPU used on Linux. The load includes time in user space and system space. ]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a Lua function that returns the percentage of CPU used on Linux. The load includes time in user space and system space. In case you&#8217;re curious, I used `<code>top</code>` to get the load for a couple reasons:</p>
<ol>
<li>It&#8217;s installed by default on most distros (as opposed to the <code>sysstat</code> tools).</li>
<li>It gives the idle time in percentage normalized to 100% (as opposed to <code>/proc/stat</code> which requires knowledge of the jiffy&#8217;s interval, which can vary).</li>
</ol>
<pre><code>function cpu_load(interval)
   interval = interval or 1
   local f = io.popen('top -bp$$ -d ' .. interval .. ' -n 2')
   local s = f:read('*all')

   -- Find the idle times in the stdout output
   local tokens = s:gmatch(',%s*([%d%.]+)%%%s*id')

   -- We're interested in the 2nd 'top' idle time
   local ii = 1
   for idle in tokens do
      if ii == 2 then
         return 100.0 - tonumber(idle)
      end
      ii = ii + 1
   end
end

</code></pre>
<p>You can call it from the Lua shell as:</p>
<pre><code>&gt; load = cpu_load()
&gt; print(load)
43.7

</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/05/02/lua-get-cpu-load-on-linux/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Define NaN (Not-a-Number) on Windows</title>
		<link>http://tdistler.com/2011/03/24/how-to-define-nan-not-a-number-on-windows</link>
		<comments>http://tdistler.com/2011/03/24/how-to-define-nan-not-a-number-on-windows#comments</comments>
		<pubDate>Thu, 24 Mar 2011 20:41:48 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=874</guid>
		<description><![CDATA[The C99 spec requires that math.h should define the constant float value NAN. However, NAN isn&#8217;t defined in the Visual Studio version of math.h, so you have to define it yourself (VS only implements C89). It&#8217;s pretty straight-forward for 32-bit machines&#8230; here&#8217;s my implementation with cross-platform protection: #ifdef WIN32 #ifndef NAN static const unsigned long [...]]]></description>
			<content:encoded><![CDATA[<p>The C99 spec requires that <a title="The Open Group: math.h" href="http://pubs.opengroup.org/onlinepubs/009695399/basedefs/math.h.html" target="_blank">math.h should define the constant float value NAN</a>. However, NAN isn&#8217;t defined in the Visual Studio version of math.h, so you have to define it yourself (VS only implements C89). It&#8217;s pretty straight-forward for 32-bit machines&#8230; here&#8217;s my implementation with cross-platform protection:</p>
<pre><code>#ifdef WIN32
    #ifndef NAN
        static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
        #define NAN (*(const float *) __nan)
    #endif
#endif

</code></pre>
<p>This code is adapted from an MSDN <a title="MSDN: Not A Number (NAN) Items" href="http://msdn.microsoft.com/en-us/library/w22adx1s(v=vs.80).aspx" target="_blank">example</a>.<del datetime="2011-04-20T17:26:37+00:00"></del></p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/03/24/how-to-define-nan-not-a-number-on-windows/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Cross-Platform IPv6 Socket Programming</title>
		<link>http://tdistler.com/2011/02/28/cross-platform-ipv6-socket-programming</link>
		<comments>http://tdistler.com/2011/02/28/cross-platform-ipv6-socket-programming#comments</comments>
		<pubDate>Tue, 01 Mar 2011 04:00:39 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[IPv6]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=793</guid>
		<description><![CDATA[Writing code that works on Windows, Linux, and Mac is frequently challenging. Socket programming is no exception. Modern versions of Linux and Mac have full implementations of the latest IPv6 socket API extensions defined in RFC 3493. Windows, however, has only a partial implementation of the original (deprecated) version, RFC 2553. This sounds worse than [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2011/02/network.jpg"><img class="alignright size-thumbnail wp-image-795" title="network" src="http://tdistler.com/wp-content/uploads/2011/02/network-150x150.jpg" alt="IPv6 Networking" width="150" height="150" /></a>Writing code that works on Windows, Linux, and Mac is frequently challenging. Socket programming is no exception. Modern versions of Linux and Mac have full implementations of the latest IPv6 socket API extensions defined in <a title="IETF RFC 3493" href="http://tools.ietf.org/html/rfc3493" target="_blank">RFC 3493</a>. Windows, however, has only a partial implementation of the original (deprecated) version, <a title="IETF RFC 2553" href="http://tools.ietf.org/html/rfc2553" target="_blank">RFC 2553</a>. This sounds worse than it is, but it&#8217;s something you have to consider.</p>
<p><em><strong>Note</strong></em>: This post assumes you are already familiar with the socket extensions for IPv6 (<a title="IETF RFC 3493" href="http://tools.ietf.org/html/rfc3493" target="_blank">RFC 3493</a>).</p>
<p><strong>Linux and Mac</strong><br />
Good news&#8230; they both fully support <a title="IETF RFC 3493" href="http://tools.ietf.org/html/rfc3493" target="_blank">RFC 3493</a>.</p>
<p><strong>Windows</strong><br />
Windows IPv6 support varies based on which version you&#8217;re targeting. Microsoft started adding IPv6 in Windows 2000, and they&#8217;ve continued adding more of the socket extensions as time went on. Most of the core functionality is present in XP, and what&#8217;s missing is easily replaced by using Winsock calls directly (more on this later).</p>
<p>Windows gained IPv6 support while <a title="IETF RFC 2553" href="http://tools.ietf.org/html/rfc2553" target="_blank">RFC 2553</a> was still the supported standard. Since then, it has been deprecated by <a title="IETF RFC 3493" href="http://tools.ietf.org/html/rfc3493" target="_blank">RFC 3493</a>. However, Microsoft doesn&#8217;t want to break existing code written against it&#8217;s API, so the older API lives on. The main impact of this is that <code>sockaddr_in6</code> and <code>sockaddr_storage</code> are slightly different on Windows than Mac and Linux. The size of the structures across platforms is the same (the <code>sa_family_t</code> member was shortened), it&#8217;s just that the Windows structures don&#8217;t begin with the length member. For example:</p>
<pre><code>// Linux and Mac
struct sockaddr_in6 {
    uint8_t      sin6_len;    /* Added in RFC 3493 */
    sa_family_t  sin6_family;
    ...
};
struct sockaddr_storage {
    uint8_t      ss_len;      /* Added in RFC 3493 */
    sa_family_t  ss_family;
    ...
};

// Windows
struct sockaddr_in6 {
    sa_family_t  sin6_family;
    ...
};
struct sockaddr_storage {
    sa_family_t  ss_family;
    ...
};</code></pre>
<p>I&#8217;ve never had a problem with this, because the size of <code>sockaddr_in6</code> is easily determined (<code>sizeof(sockaddr_in6)</code>) and I always end up casting <code>sockaddr_storage</code> to the specific type (<code>sockaddr_in</code> or <code>sockaddr_in6</code>) based on <code>ss_family</code>.</p>
<p>Besides the data structure differences, it&#8217;s important to remember that Microsoft added IPv6 support over multiple versions. Support first appeared in Windows 2000, but more of the extensions have been added over time. Most of the core functionality was present in XP (including multicast), but not everything is implemented as of Windows 7. It&#8217;s annoying, but I will say that what&#8217;s missing is easily replaced by using Winsock calls directly.</p>
<p>Here&#8217;s the breakdown of IPv6 socket extensions by Windows version:</p>
<table border="1" width="570">
<tbody><!-- Results table headers --></p>
<tr>
<th>Socket Extension</th>
<th>2K</th>
<th>XP</th>
<th>Vista</th>
<th>7</th>
<th>Comments</th>
</tr>
<tr>
<td>if_indextoname()</td>
<td></td>
<td></td>
<td>x</td>
<td>x</td>
<td>GetAdaptersAddresses() for XP</td>
</tr>
<tr>
<td>if_nametoindex()</td>
<td></td>
<td></td>
<td>x</td>
<td>x</td>
<td>GetAdaptersAddresses() for XP</td>
</tr>
<tr>
<td>if_nameindex()</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>GetAdaptersAddresses() (XP, later)</td>
</tr>
<tr>
<td>if_freenameindex()</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>getaddrinfo()</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td></td>
</tr>
<tr>
<td>getnameinfo()</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td></td>
</tr>
<tr>
<td>freeaddrinfo()</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td></td>
</tr>
<tr>
<td>gai_strerror()</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td></td>
</tr>
<tr>
<td>inet_pton()</td>
<td></td>
<td></td>
<td>x</td>
<td>x</td>
<td>WSAStringToAddress() (2000, XP)</td>
</tr>
<tr>
<td>inet_ntop()</td>
<td></td>
<td></td>
<td>x</td>
<td>x</td>
<td>WSAAddressToString() (2000, XP)</td>
</tr>
<tr>
<td>All IN6_IS_ADDR_* macros</td>
<td></td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>Ex: IN6_IS_ADDR_LOOPBACK()</td>
</tr>
<tr>
<td>struct sockaddr_storage</td>
<td></td>
<td>x</td>
<td>x</td>
<td>x</td>
<td></td>
</tr>
<tr>
<td>Multicast support</td>
<td></td>
<td>x</td>
<td>x</td>
<td>x</td>
<td></td>
</tr>
</tbody>
</table>
<p>As you can see, you may still have to call Winsock directly depending on what version of Windows you are targeting. In my opinion, programming IPv6 on Windows is a lot easier if you only support XP and later, but I know that&#8217;s not always possible.</p>
<p><strong>Summary</strong></p>
<p>Modern operating systems all support IPv6. However, for business reasons, Windows has a slightly older version of the socket API which requires special consideration. My goal was to enumerate those differences to help make the transition to IPv6 smoother. Writing cross-platform code can be a fun challenge at times, but it&#8217;s also a little tedious. Hopefully, this post helps ease the pain.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/02/28/cross-platform-ipv6-socket-programming/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Test if an Address is IPv4 or IPv6</title>
		<link>http://tdistler.com/2011/02/25/how-to-test-if-an-address-is-ipv4-or-ipv6</link>
		<comments>http://tdistler.com/2011/02/25/how-to-test-if-an-address-is-ipv4-or-ipv6#comments</comments>
		<pubDate>Fri, 25 Feb 2011 19:16:33 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[IPv6]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=785</guid>
		<description><![CDATA[Here&#8217;s a simple function using getaddrinfo() that will take an IP address and return the address family (AF_INET for IPv4, AF_INET6 for IPv6, etc). I works on both Linux and Windows. This function will also accept hostnames and return the address family of the first address returned. You can disable this feature (and the corresponding [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a simple function using <a title="getaddrinfo man page" href="http://linux.die.net/man/3/getaddrinfo" target="_blank">getaddrinfo()</a> that will take an IP address and return the address family (<code>AF_INET</code> for IPv4, <code>AF_INET6</code> for IPv6, etc). I works on both Linux and Windows. This function will also accept hostnames and return the address family of the first address returned. You can disable this feature (and the corresponding DNS lookup) by passing the AI_NUMERICHOST flag.<br />
<code>
<pre>
// Returns the address family of an address or hostname.
// AF_INET, AF_INET6, or -1 on error.
int getaddrfamily(const char *addr)
{
    struct addrinfo hint, *info =0;
    memset(&amp;hint, 0, sizeof(hint));
    hint.ai_family = AF_UNSPEC;
    // Uncomment this to disable DNS lookup
    //hint.ai_flags = AI_NUMERICHOST;
    int ret = getaddrinfo(addr, 0, &amp;hint, &amp;info);
    if (ret)
        return -1;
    int result = info-&gt;ai_family;
    freeaddrinfo(info);
    return result;
}</pre>
<p></code></p>
<p>See <a title="IETF RFC 3493" href="http://tools.ietf.org/html/rfc3493" target="_blank">RFC 3493</a> for more information on the latest socket API for dealing with IPv6.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/02/25/how-to-test-if-an-address-is-ipv4-or-ipv6/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Test An Audio Codec: A Practical Approach</title>
		<link>http://tdistler.com/2011/01/25/how-to-test-an-audio-codec-a-practical-approach</link>
		<comments>http://tdistler.com/2011/01/25/how-to-test-an-audio-codec-a-practical-approach#comments</comments>
		<pubDate>Wed, 26 Jan 2011 01:16:28 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[Did you know?]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=727</guid>
		<description><![CDATA[Recently, I was tasked with picking an AAC audio codec library for one of our products. There were several libraries I had to evaluate, and I needed some quantitative metrics for doing the comparison. I&#8217;m not what professionals call an &#8220;expert listener&#8221;, so I had to do the best with what I had. While creating [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2011/01/audio_waveform.jpg"><img class="alignright size-thumbnail wp-image-732" title="audio_waveform" src="http://tdistler.com/wp-content/uploads/2011/01/audio_waveform-150x150.jpg" alt="" width="150" height="150" /></a>Recently, I was tasked with picking an AAC audio codec library for one of our products. There were several libraries I had to evaluate, and I needed some quantitative metrics for doing the comparison. I&#8217;m not what professionals call an &#8220;expert listener&#8221;, so I had to do the best with what I had. While creating my test plan, I noticed that more people seemed interested in <em>how</em> I was doing testing rather than the actual results. So I decided to share my approach to audio codec testing.</p>
<p><strong>Note</strong>: <em>This is intended to be a pragmatic guide for engineers evaluating codecs. It is not a comprehensive treatment of the subject. The goal is to give readers a solid overview and some practical ideas</em>.</p>
<p><strong>Get Familiar with Psychoacoustics</strong></p>
<p><a title="Wikipedia: Psychoacoustics" href="http://en.wikipedia.org/wiki/Psychoacoustics" target="_blank">Psychoacoustics</a> is the study of how humans <em>perceive</em> sound. As you might expect, we humans don&#8217;t process sound in a perfect, linear fashion. The physical shape of the ear, the transfer function of the Basilar membrane, and the psychological interpretation of the data all affect how we perceive sound (and by extension, how &#8220;good&#8221; an audio codec sounds to us).</p>
<p>I highly recommend you start by reading this excerpt from <a title="EETimes: Psychoacoustics Part 1" href="http://www.eetimes.com/design/audio-design/4015872/Surround-Sound-Psychoacoustics--Part-1" target="_blank">Surround Sound: Psychoacoustics Part 1, by Tomlinson Holman</a> (he created <a title="Wikipedia: THX" href="http://en.wikipedia.org/wiki/THX" target="_blank">THX</a> for Lucasfilm).</p>
<p><strong>Understand the Codec</strong></p>
<p>Make sure you understand the codec you are testing; not necessarily the implementation, but what tools (i.e. methods) the codec uses for compression. Many codecs have different &#8220;profiles&#8221;, which describe what subset of available tools are used (e.g. <a title="MPEG-4 Part 3 Audio Preview" href="http://webstore.iec.ch/preview/info_isoiec14496-3%7Bed4.0%7Den.pdf" target="_blank">AAC</a>). You should also have some idea how each compression tool works and any short-comings it has. This will help guide you in selecting reference audio samples and knowing what artifacts to listen for.</p>
<p>For an introduction to modern audio compression, read <a title="EETimes: Audio Coding: An Introduction to Data Compression Part 1" href="http://www.eetimes.com/design/audio-design/4015827/Audio-Coding-An-Introduction-to-Data-Compression--Part-1" target="_blank">Audio Coding: An Introduction to Data Compression Part 1</a>, and <a title="EETimes: Audio Coding: An Introduction to Data Compression Part 2" href="http://www.eetimes.com/design/audio-design/4015828/Audio-Coding-An-Introduction-to-Data-Compression--Part-2" target="_blank">Part 2</a> (discusses MP3 and AAC). I actually suggest buying the book <a title="Amazon" href="http://www.amazon.com/Introduction-Compression-Kaufmann-Multimedia-Information/dp/012620862X/" target="_blank">&#8220;Introduction to Data Compression&#8221;</a>, by Khalid Sayood.</p>
<p><strong>Understand the API</strong></p>
<p>Make sure you actually read the codec documentation and look at any available code samples. This step has more to do with due-diligence than anything, as I haven&#8217;t seen a codec API we couldn&#8217;t work with, but you need to do this. This will also help you scope the work required to get a working encoder/decoder for future steps (if your lucky, the sample code can be used).</p>
<p><strong>Choose the Reference Audio Samples</strong></p>
<p>An effective test requires multiple audio samples with different characteristics. There are many types of artifacts a codec can introduce, and your choice of audio samples will dictate how easy they are to detect. It&#8217;s also important to pick samples that reflect the actual types of sound the codec to have to deal with. For example, if the final system will primarily be encoding speech, then you should choose more speech-oriented references as opposed to music samples.</p>
<p>Some characteristics you might consider:</p>
<ul>
<li><strong>Transients</strong> (snare drum): Sensitive to pre-echo and noise &#8220;smearing&#8221;.</li>
<li><strong>Tonal structure</strong> (clarinet, saxophone): Sensitive to noise and &#8220;roughness&#8221;.</li>
<li><strong>Natural speech</strong> (male and female voices of various languages): Sensitive to distortion and smearing of &#8220;attacks&#8221;.</li>
<li><strong>Complex sound</strong> (bag pipes): Stresses the codec.</li>
<li><strong>High bandwidth</strong> (bag pipes): Loss of high frequencies and program-modulated high frequency noise.</li>
</ul>
<p>It is also possible to use synthetic sounds and sweeps, but this is only recommended for the automated objective tests below.</p>
<p>As a basic guideline, you need 10-25 second &#8220;raw&#8221; samples recorded at the highest sample rate your system needs to work with. It is vital that the samples you choose have never been compressed with a lossy codec (mp3, AAC, etc)&#8230; that would severally limit the quality of your test. For sample rate and size, I suggest 48kHz 16-bit PCM, but a lower rate/size makes sense if the final system is limited in this area. It also makes sense to use a sample rate of 44.1kHz, since many quality audio samples can be ripped losslessly from CD. Just keep in mind that the objective PEAQ test mentioned below requires 48kHz 16-bit PCM, so up-sampling may be required.</p>
<p>The audio samples can be stored in whatever container format you want (raw, WAV, etc) as long as your codec test application can unpack it. This is important to keep in mind&#8230; <em>you don&#8217;t want to accidentally run the WAV header through the codec</em> (yes, I&#8217;ve done this). The container format is more of a practical issue, but it was worth mentioning.</p>
<p><strong>Generate Various Test Samples and Observe CPU Load</strong></p>
<p>This step is pretty straight-forward: wrap the codec in an application and encode the reference audio samples at different bit rates. You should choose bit rates that represent the full spectrum of bit rates that will be used in the final system. While you&#8217;re encoding, track the CPU usage on the codec and how many cores it&#8217;s using. You may even want to do a separate test running many encodes in parallel (this works nicely if the CPU usage is too low to measure accurately). Make sure to consider application overhead and disk I/O when making measurements.</p>
<p>After encoding, you need to decode back to raw PCM. Clearly label your files so you know what bit rate each one was encoded with. These decoded test samples are what we will be comparing to the original reference samples.</p>
<p><strong>Do a Subjective Test</strong></p>
<p>How you conduct your subjective testing will depend on several factors, such as time constraints, cost, and the required test precision. At the low end, you could simply listen to the test samples in a pair of headphones and judge the quality yourself. For a high precision test, you could do a full <a title="ITU BS.1116" href="http://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1116-1-199710-I!!PDF-E.pdf" target="_blank">ITU BS.1116</a> test using &#8220;expert listeners&#8221; in a controlled environment. While these examples represent the extremes, there are many permutations that can give you the desired quality of results.</p>
<p>The most common subjective test is called a &#8220;double-blind triple-stimulus with hidden reference&#8221; test. The listener hears three samples (commonly labeled A, B, and C) for a period of 10 to 25 seconds. A is always the original reference sample. The next two samples, B and C, are randomly assigned either the test sample from the codec or the original reference sample played again (called the &#8220;hidden reference&#8221;). The listener must then rate the difference between B and A, and C and A, not knowing which one is the test sample. The grading scale is:</p>
<ul>
<li>5.0 Imperceptible</li>
<li>4.0 Perceptible, but not annoying</li>
<li>3.0 Slightly annoying</li>
<li>2.0 Annoying</li>
<li>1.0 Very annoying</li>
</ul>
<p>Ideally, you would conduct several tests and average the results together. If you do the listening test yourself, your results will be limited to your listening skills and understanding of audio codec artifacts. Here&#8217;s a summary of factors that affect the quality of your results:</p>
<ul>
<li>The quality of the listener.</li>
<li>The choice of audio samples.</li>
<li>The number and duration of the testing.</li>
<li>The testing environment, including speaker/headphone quality, room design, and listener placement.</li>
<li>The quality of randomization of sample order to remove any correlation between samples.</li>
<li>Proper statistical analysis of the combined test results.</li>
</ul>
<p>A proper subjective test is both expensive and time consuming. It&#8217;s important to find the right balance for your particular needs.</p>
<p><strong>Do an Objective Test</strong></p>
<p>Evaluating a codec objectively requires testing methods that correlate well to actual human perception. You can&#8217;t simply measure the distortion introduced by the codec using traditional measurements like Signal-to-Noise ratio (S/N) and  Total-Harmonic-Distortion (THD), because they don&#8217;t correlate well to perceived audio  quality. Some distortion is imperceptible to the human ear, and codecs take advantage of this to increase the compression ratio.</p>
<p>Fortunately, the <a title="Wikipedia: International Telecommunications Union" href="http://en.wikipedia.org/wiki/International_Telecommunication_Union" target="_blank">ITU</a> has standardized an objective audio test called <a title="Wikipedia: PEAQ" href="http://en.wikipedia.org/wiki/PEAQ" target="_blank">PEAQ</a> (<a title="ITU: Perceptual Evaluation of Audio Quality" href="http://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1387-1-200111-I!!PDF-E.pdf" target="_blank">BS.1387</a>). The acronym stands for Perceptual Evaluation of Audio Quality. PEAQ uses software to model the entire human auditory system (including blood flow noise in the inner ear) to generate a set of metrics that are used to give a final &#8220;quality&#8221; score. The original reference signal is compared to a signal run through the codec, and the result is a real number between 0.0 and -4.0. The result is interpreted on the following scale:</p>
<ul>
<li> 0.0 = Imperceptible</li>
<li>-1.0 = Perceptible but not annoying</li>
<li>-2.0 = Slightly annoying</li>
<li>-3 .0= Annoying</li>
<li>-4.0 = Very annoying</li>
</ul>
<p>Obviously, values closer to zero are better.</p>
<p>The test was developed by a similar group of audio experts that developed BS.1116 (mentioned above) and the results have been validated against a long list of subjective tests done using expert listeners.</p>
<p>There are several free and commercial software packages available for doing PEAQ tests. The best free package I&#8217;ve found is <a title="McGill: AFsp PEAQ Software" href="http://www-mmsp.ece.mcgill.ca/Documents/Software/index.html" target="_blank">AFsp</a> from the McGill Telecommunications and Signal Processing Lab. There&#8217;s also <a title="Sourceforge: peaqb" href="http://sourceforge.net/projects/peaqb/" target="_blank">peaqb</a>, but there&#8217;s a comment that it gives incorrect results. AFsp worked great in my tests and included some helpful tools like <a title="AFsp: CompAudio" href="http://www-mmsp.ece.mcgill.ca/Documents/Software/Packages/AFsp/CompAudio.html" target="_blank">CompAudio</a> and <a title="AFsp: InfoAudio" href="http://www-mmsp.ece.mcgill.ca/Documents/Software/Packages/AFsp/InfoAudio.html" target="_blank">InfoAudio</a>.</p>
<p><strong>Summary</strong></p>
<p>Hopefully this post has given you a good starting point and some practical ideas for testing audio codecs. My goal was to provide a pragmatic approach with different options depending on what your actual evaluation needs are. This is in no way a comprehensive treatment of the subject; only an overview. I highly suggest reading some of the books I referenced if you&#8217;d like a deeper treatment of the subject. Either way, I hope you found this post helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/01/25/how-to-test-an-audio-codec-a-practical-approach/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CPU Profiling on Windows: Very Sleepy</title>
		<link>http://tdistler.com/2010/12/21/cpu-profiling-on-windows-very-sleepy</link>
		<comments>http://tdistler.com/2010/12/21/cpu-profiling-on-windows-very-sleepy#comments</comments>
		<pubDate>Tue, 21 Dec 2010 19:59:04 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=697</guid>
		<description><![CDATA[A colleague of mine found a pretty cool profiling tool for Windows called Very Sleepy. It&#8217;s simple, straight-forward, free, and it works&#8230; everything I like in a tool (this is why I like the Sysinternals stuff so much). It&#8217;s also got call-graph and 64-bit support. Definitely worth checking out.]]></description>
			<content:encoded><![CDATA[<p>A colleague of mine found a pretty cool profiling tool for Windows called <a title="Coders Notes: Very Sleepy" href="http://www.codersnotes.com/sleepy" target="_blank">Very Sleepy</a>. It&#8217;s simple, straight-forward, free, and it works&#8230; everything I like in a tool (this is why I like the <a title="Mircosoft Sysinternals" href="http://www.sysinternals.com" target="_blank">Sysinternals</a> stuff so much). It&#8217;s also got call-graph and 64-bit support. Definitely worth checking out.</p>
<p><a href="http://tdistler.com/wp-content/uploads/2011/01/very_sleepy_screenshot.jpg"><img class="aligncenter size-medium wp-image-698" title="very_sleepy_screenshot" src="http://tdistler.com/wp-content/uploads/2011/01/very_sleepy_screenshot-300x218.jpg" alt="Very Sleep Screen Shot" width="300" height="218" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/12/21/cpu-profiling-on-windows-very-sleepy/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ILM and GPU Programming</title>
		<link>http://tdistler.com/2010/10/07/ilm-and-gpu-programming</link>
		<comments>http://tdistler.com/2010/10/07/ilm-and-gpu-programming#comments</comments>
		<pubDate>Thu, 07 Oct 2010 16:15:49 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[Tech and Security]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=503</guid>
		<description><![CDATA[Some artists from Industrial Light &#38; Magic (ILM) gave the closing keynote at the GPU Technology Conference (GTC) in 2009&#8230; it&#8217; s well worth watching by itself (watch here). At GTC 2010, they presented a video talking about how the GPU and CUDA are helping to render effects faster. It&#8217;s a short video with lots [...]]]></description>
			<content:encoded><![CDATA[<p>Some artists from <a title="Industrial Light and Magic" href="http://www.ilm.com/" target="_blank">Industrial Light &amp; Magic</a> (ILM) gave the closing keynote at the <a title="GPU Technology Conference" href="http://www.nvidia.com/object/gpu_technology_conference.html" target="_blank">GPU Technology Conference</a> (GTC) in 2009&#8230; it&#8217; s well worth watching by itself (<a title="ILM Keynote at GTC 2009" href="http://us.download.nvidia.com/downloads/GTC%20videos/Day3%20Keynote/1200_nv_keynote_091002.mp4" target="_blank">watch here</a>). At GTC 2010, they presented a video talking about how the GPU and CUDA are helping to render effects faster. It&#8217;s a short video with lots of cool effects.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube-nocookie.com/v/8ZIL98Uhhcg?fs=1&amp;hl=en_US&amp;rel=0" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="640" height="385" src="http://www.youtube-nocookie.com/v/8ZIL98Uhhcg?fs=1&amp;hl=en_US&amp;rel=0" allowscriptaccess="always" allowfullscreen="true"></embed></object>ct&gt;</p>
<p><a title="ILM Promo GTC 2010" href="http://www.tdistler.com/media/videos/GTC_2010_ILM.3gp">Here&#8217;s</a> a copy of the video if it is ever removed (13MB, 3gp).</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/10/07/ilm-and-gpu-programming/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://us.download.nvidia.com/downloads/GTC%20videos/Day3%20Keynote/1200_nv_keynote_091002.mp4" length="504306567" type="video/mp4" />
		</item>
		<item>
		<title>Lua Quick Reference Sheet</title>
		<link>http://tdistler.com/2010/09/27/lua-quick-reference-sheet</link>
		<comments>http://tdistler.com/2010/09/27/lua-quick-reference-sheet#comments</comments>
		<pubDate>Mon, 27 Sep 2010 19:26:15 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=485</guid>
		<description><![CDATA[Here&#8217;s a nice 4 page reference for Lua 5.1. It was created by Thomas Lauer and can be downloaded from his website. I&#8217;ve reposted it here just-in-case&#8230; I&#8217;ve been bitten before. Lua Reference Card (PDF)]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/09/lua_logo1.gif"><img class="alignright size-full wp-image-489" title="lua_logo" src="http://tdistler.com/wp-content/uploads/2010/09/lua_logo1-e1285616733640.gif" alt="" width="100" height="99" /></a>Here&#8217;s a nice 4 page reference for Lua 5.1. It was created by <a title="Thomas Lauer" href="http://thomaslauer.com/" target="_blank">Thomas Lauer</a> and can be downloaded from his <a title="Lua Short Reference" href="http://thomaslauer.com/comp/Lua_Short_Reference" target="_blank">website</a>. I&#8217;ve reposted it here just-in-case&#8230; I&#8217;ve been bitten before.</p>
<p><a title="Lua Short Reference PDF" href="http://www.tdistler.com/media/docs/luarefv51.pdf">Lua Reference Card (PDF)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/09/27/lua-quick-reference-sheet/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++ Enums in Lua</title>
		<link>http://tdistler.com/2010/09/13/c-enums-in-lua</link>
		<comments>http://tdistler.com/2010/09/13/c-enums-in-lua#comments</comments>
		<pubDate>Mon, 13 Sep 2010 15:28:42 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=460</guid>
		<description><![CDATA[I&#8217;ve been working lately on embedding Lua 5.1.4 into a C++ application. I&#8217;m really impressed with Lua, and most things are pretty straight-forward. However, when it comes to mapping typed enumerations into Lua, I just haven&#8217;t found an easy way to do it. For example, let&#8217;s say you want to expose a C++ function into [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/09/lua_logo.gif"><img class="alignright size-thumbnail wp-image-462" title="lua_logo" src="http://tdistler.com/wp-content/uploads/2010/09/lua_logo-150x150.gif" alt="Lua" width="150" height="150" /></a>I&#8217;ve been working lately on embedding <a title="Lua Programming Language" href="http://www.lua.org/" target="_blank">Lua 5.1.4</a> into a C++ application. I&#8217;m really impressed with Lua, and most things are pretty straight-forward. However, when it comes to mapping typed enumerations into Lua, I just haven&#8217;t found an easy way to do it. For example, let&#8217;s say you want to expose a C++ function into Lua called <code>create()</code>, which takes an enumerated type as a parameter. In C++ this would look like:</p>
<pre><code>typedef enum _TYPE {
    TYPE_FOO = 0,
    TYPE_BAR,
    TYPE_BAZ,
    TYPE_MAX
} TYPE;

bool create(const TYPE type);</code></pre>
<p>To me, it makes the most sense to call <code>create()</code> from Lua with syntax like:</p>
<p><code>&gt; create(type.foo)</code></p>
<p>Ideally, we&#8217;d also like the following:</p>
<ol>
<li>The enumeration is const, and can&#8217;t be altered from Lua code.</li>
<li>The C++ implementation of <code>create()</code> could validate the type passed to it is the expected type.</li>
</ol>
<p>Unfortunately, this isn&#8217;t as straight-forward as everything else I&#8217;ve done with Lua.</p>
<h4>Solution (i.e. cut-to-the-chase and explain later)</h4>
<p>Okay, I&#8217;m a practical guy&#8230; download <strong><a title="lua_typed_enums.h Header File" href="/media/code/lua_typed_enums.h">lua_typed_enums.h</a></strong> and include it in your code. Then you can add the enums shown above to Lua by calling <code>add_enum_to_lua()</code>:</p>
<pre><code>add_enum_to_lua( L, "type",
    "foo", TYPE_FOO,
    "bar", TYPE_BAR,
    "baz", TYPE_BAZ,
    0 );</code></pre>
<p>Your enums are now available in Lua as:</p>
<p><code>type.foo<br />
type.bar<br />
type.baz</code></p>
<p>Now, your C++ code that takes TYPE as an input and returns a boolean would be written as follows:</p>
<pre><code>static int lua_create( lua_State *L )
{
    if( !check_enum_type( L, "type", -1 ) ) {
        /* error */
    }

    int value = get_enum_value( L, -1 );

    /* do something cool */

    lua_pushboolean( L, 1 );
    return (1);
}</code></pre>
<p>You can now call your <code>create()</code> method from Lua how we wanted:</p>
<p><code>&gt; create(type.bar)</code></p>
<p>Look at the comments in the header file if you want more info about using <code>add_enum_to_lua()</code>, <code>check_enum_type()</code>, and <code>get_enum_value()</code>.</p>
<h4>How it Works</h4>
<p>There&#8217;s no direct way to map the expected behavior of C-enums into Lua (const-ness with typing). What I did was to create a read-only Lua table representing the enumerated type and then make each value in that table have a defined type.</p>
<p>Let&#8217;s deal with the first task: making a read-only table. This is pretty well documented on the web, but I&#8217;ve included a drawing below that would have helped me a lot in the beginning. Let&#8217;s assume we want to represent our enum as a Lua table. We could visualize it as follows:</p>
<p><a href="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_unprotected.jpg"><img class="aligncenter size-full wp-image-472" title="lua_rotables_unprotected" src="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_unprotected.jpg" alt="" width="169" height="97" /></a></p>
<p>We could still use the <code>type.foo</code> syntax with this table, but a user could assign a new value to the enum like:</p>
<p><code>&gt; type.foo = 9</code></p>
<p>To prevent this, we need to deny write access to the table. The trick to doing this is to use a metatable and set the <code>__index</code> and <code>__newindex</code> values.</p>
<p><a href="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_untyped.jpg"><img class="aligncenter size-full wp-image-473" title="lua_rotables_untyped" src="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_untyped.jpg" alt="" width="361" height="145" /></a></p>
<p>So how does this work? When the user reads a value from the table (i.e. by using <code>type.foo</code>), Lua fails to find &#8220;foo&#8221; in the table. So it looks in the metatable for the <code>__index</code> key. If that is set to point to a table, then it will try to lookup the value in that table. In the case above, it finds the &#8220;foo&#8221; value and returns it like normal. However, if the user attempts to assign to type.foo, Lua follows the <code>__newindex</code> path, which causes a function to get called that does nothing but print an error&#8230; effectively, the write is denied. Here&#8217;s what happens:</p>
<p><code>&gt; type.foo = 9<br />
[string "?"]:1: Attempt to modify read-only table</code></p>
<p>Okay, cool&#8230; we&#8217;ve made read-only enumerations, but what about typing. Glad you asked! We add one more layer of abstraction, of course &lt;groaning&gt;:</p>
<p><a href="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_typed1.jpg"><img class="aligncenter size-full wp-image-475" title="lua_rotables_typed" src="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_typed1.jpg" alt="" width="553" height="181" /></a></p>
<p>Basically, we make each value a table that includes the <em>actual</em> value and a type (&#8220;type&#8221; in our example above). The <code>check_enum_type()</code> function looks at the &#8220;type&#8221; field in the table to make sure the correct type was passed to your function. The <code>get_enum_value()</code> function gets the &#8220;value&#8221; field&#8230; which is equal to the actual C-enum type you&#8217;d expect. From the Lua side, you can inspect the enums like:</p>
<p><code>&gt; print(type.foo.value)<br />
0<br />
&gt; print(type.foo.type)<br />
type</code></p>
<p>Explicitly, &#8220;type&#8221; is a read-only table with value &#8220;foo&#8221;. The value of &#8220;foo&#8221; is the table <code>{ value=0, type="type" }</code>. I hope this explanation helps. Obviously, I&#8217;ve been geeking out on Lua a little too much lately <img src='http://tdistler.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/09/13/c-enums-in-lua/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux: Parsing IP Address, MAC, and Gateway</title>
		<link>http://tdistler.com/2010/08/17/linux-parsing-ip-address-mac-and-gateway</link>
		<comments>http://tdistler.com/2010/08/17/linux-parsing-ip-address-mac-and-gateway#comments</comments>
		<pubDate>Tue, 17 Aug 2010 18:28:33 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=453</guid>
		<description><![CDATA[Yesterday, I needed to get my server&#8217;s network information for a Bash script I was writing. Here are the commands so I don&#8217;t forget. They were tested using Fedora 12. Get IP address: ifconfig eth0 &#124; awk '/inet / {print $2}' &#124; awk -F: '{print $2}&#8216; Get MAC address: ifconfig eth0 &#124; awk '/HWaddr/ {print [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/08/bash_cmd_prompt.jpg"><img class="alignright size-full wp-image-455" title="bash_cmd_prompt" src="http://tdistler.com/wp-content/uploads/2010/08/bash_cmd_prompt.jpg" alt="" width="102" height="102" /></a>Yesterday, I needed to get my server&#8217;s network information for a Bash script I was writing. Here are the commands so I don&#8217;t forget. They were tested using <a title="Fedora Linux" href="http://fedoraproject.org/" target="_blank">Fedora</a> 12.</p>
<p>Get IP address:<br />
<code>ifconfig eth0 | awk '/inet / {print $2}' | awk -F: '{print $2}</code>&#8216;</p>
<p>Get MAC address:<br />
<code>ifconfig eth0 | awk '/HWaddr/ {print $5}'</code></p>
<p>Get network gateway IP address:<br />
<code>route -n | awk '/^0.0.0.0/ {print $2}'</code></p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/08/17/linux-parsing-ip-address-mac-and-gateway/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IP Multicast to MAC-Layer Multicast Mapping</title>
		<link>http://tdistler.com/2010/08/16/ip-multicast-to-mac-layer-multicast-mapping</link>
		<comments>http://tdistler.com/2010/08/16/ip-multicast-to-mac-layer-multicast-mapping#comments</comments>
		<pubDate>Mon, 16 Aug 2010 21:38:22 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=445</guid>
		<description><![CDATA[Using the Tcpreplay tools to edit a Wireshark capture (*.pcap), I wanted to change the destination address to be multicast. I knew the IP multicast address I wanted (server IP address with the first octet changed to 239), but I had to change the MAC address also. Here&#8217;s the mapping, taken from a Microsoft TechNet [...]]]></description>
			<content:encoded><![CDATA[<p>Using the <a title="TCP Replay" href="http://tcpreplay.synfin.net/" target="_blank">Tcpreplay</a> tools to edit a <a title="Wireshark" href="http://www.wireshark.org/" target="_blank">Wireshark</a> capture (*.pcap), I wanted to change the destination address to be multicast. I knew the IP multicast address I wanted (server IP address with the first octet changed to 239), but I had to change the MAC address also.</p>
<p>Here&#8217;s the mapping, taken from a Microsoft TechNet <a title="Microsoft TechNet: Mapping IP Mulitcast to MAC_layer Multicast" href="http://technet.microsoft.com/en-us/library/cc957928.aspx" target="_blank">article</a>:</p>
<blockquote><p>To support IP multicasting, the Internet authorities have reserved the multicast address range of 01-00-5E-00-00-00 to 01-00-5E-7F-FF-FF for&#8230; media access control (MAC) addresses.</p></blockquote>
<p><a href="http://tdistler.com/wp-content/uploads/2010/08/ip_mac_multicast_mapping.gif"><img class="aligncenter size-full wp-image-446" title="ip_mac_multicast_mapping" src="http://tdistler.com/wp-content/uploads/2010/08/ip_mac_multicast_mapping.gif" alt="" width="525" height="160" /></a></p>
<blockquote><p>To map an IP multicast address to a MAC-layer multicast address, the low order 23 bits of the IP multicast address are mapped directly to the low order 23 bits in the MAC-layer multicast address. Because the first 4 bits of an IP multicast address are fixed according to the class D convention, there are 5 bits in the IP multicast address that do not map to the MAC-layer multicast address. Therefore, it is possible for a host to receive MAC-layer multicast packets for groups to which it does not belong. However, these packets are dropped by IP once the destination IP address is determined.</p>
<p>For example, the multicast address 224.192.16.1 becomes 01-00-5E-40-10-01.</p></blockquote>
<p>Happy hacking!</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/08/16/ip-multicast-to-mac-layer-multicast-mapping/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Audio Resampling Using FFMpeg (avcodec)</title>
		<link>http://tdistler.com/2010/07/22/audio-resampling-using-ffmpeg-avcodec</link>
		<comments>http://tdistler.com/2010/07/22/audio-resampling-using-ffmpeg-avcodec#comments</comments>
		<pubDate>Thu, 22 Jul 2010 19:01:38 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=427</guid>
		<description><![CDATA[FFMpeg provides many powerful features for processing audio and video. One cool thing it can do is resample an audio stream. This allows you to convert, say, a 44.1kHz audio stream down to 8kHz, or up to 48kHz. What&#8217;s more, FFMpeg can do the conversion to any arbitrary sample rate. This allows you to do [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/07/ffmpeg_logo.jpg"><img class="alignright size-full wp-image-433" title="ffmpeg_logo" src="http://tdistler.com/wp-content/uploads/2010/07/ffmpeg_logo.jpg" alt="" width="150" height="37" /></a><a title="FFMpeg" href="http://www.ffmpeg.org/" target="_blank">FFMpeg</a> provides many powerful features for processing audio and video. One cool thing it can do is resample an audio stream. This allows you to convert, say, a 44.1kHz audio stream down to 8kHz, or up to 48kHz. What&#8217;s more, FFMpeg can do the conversion to any arbitrary sample rate. This allows you to do cool things like smoothly changing the audio playback speed over time (see sample code below).</p>
<p>There are many pages describing how to resample audio using the ffmpeg command line application, but what about doing resampling in your own program? To do that, you need to use the avcodec library (<code>libavcodec.so</code> on Linux and <code>avcodec.dll</code> on Windows).</p>
<ol>
<li>Include <code>avcodec.h</code></li>
<li>Call <code>avcodec_init()</code> to initialize the FFMpeg library.</li>
<li>Create a resampling context using <code>av_resample_init()</code> that describes how you want the resampling done.</li>
<li>Call <code>av_resample()</code> to do the actual resampling on your audio buffer.</li>
<li>When you&#8217;re done with the resampling context, delete it with <code>av_resample_close()</code>.</li>
<li>Finally, link your application against <code>avcodec</code>, <code>avutil</code>, and <code><a title="zlib Library" href="http://www.zlib.net/" target="_blank">zlib</a></code> (it won&#8217;t work on Linux without this one).</li>
</ol>
<p>Here it is in pseudocode:</p>
<blockquote><p><code>#include "libavcodec/avcodec.h"</code></p>
<p><code>avcodec_init();</code></p>
<p><code>struct AVResampleContext* ctx = av_resample_init( ... );</code></p>
<p><code>av_resample( ctx, ... );</code></p>
<p><code> </code></p>
<p><code>av_resample_close( ctx );</code></p></blockquote>
<p>That&#8217;s it&#8230; seriously!</p>
<p><strong>Sample Code (Linux):</strong></p>
<p>Here&#8217;s a sample program I wrote that takes a raw 44.1kHz/16bit/mono audio file and plays it back using the <a title="Pulse Audio" href="http://pulseaudio.org/" target="_blank">pulseaudio</a> API. The catch is that it allows you to specify a &#8220;skew&#8221; parameter which will cause the audio to dynamically speed up and slow down (via resampling). The amount of resampling is controlled by a sine wave, which is what drives the speed changes.</p>
<p>Download:<strong> </strong><a title="Resample tar ball" href="http://www.tdistler.com/media/code/resample.tar.bz" target="_blank"><strong>resample.tar.bz</strong></a></p>
<p>To unpack and build, type:</p>
<blockquote><p><code>$ tar -xjvf resample.tar.bz<br />
$ make</code></p></blockquote>
<p>First, run the sample with no skew:</p>
<blockquote><p><code>$ ./resample audio_16b_44k_mono_pcm_raw 0</code></p></blockquote>
<p>Now, try it with a heavy skew:</p>
<blockquote><p><code>$ ./resample audio_16b_44k_mono_pcm_raw -10000</code></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/07/22/audio-resampling-using-ffmpeg-avcodec/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Video Tearing, V-Sync, and Triple-Buffering</title>
		<link>http://tdistler.com/2010/07/18/video-tearing-v-sync-and-triple-buffering</link>
		<comments>http://tdistler.com/2010/07/18/video-tearing-v-sync-and-triple-buffering#comments</comments>
		<pubDate>Sun, 18 Jul 2010 20:45:26 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=416</guid>
		<description><![CDATA[When rendering graphics or video to the screen, it&#8217;s important to understand the display process; in particular, vertical sync (v-sync). A common problem when starting out is an issue called &#8220;tearing&#8221;&#8230; where the video appears to be torn horizontally down the middle (see picture). I&#8217;ve been looking for a good explanation to share about why [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/07/v_sync.jpg"><img class="alignright size-full wp-image-419" title="v_sync" src="http://tdistler.com/wp-content/uploads/2010/07/v_sync.jpg" alt="" width="150" height="113" /></a>When rendering graphics or video to the screen, it&#8217;s important to understand the display process; in particular, vertical sync (v-sync). A common problem when starting out is an issue called &#8220;tearing&#8221;&#8230; where the video appears to be torn horizontally down the middle (see picture). I&#8217;ve been looking for a good explanation to share about why video tearing occurs and how to solve it (from a technical perspective). I found the following thread over at <a title="Hard Forum" href="http://hardforum.com" target="_blank">[H]ard|Forum</a>, which I think does a pretty good job.</p>
<p>For the thread &#8220;<a title="How VSync works, and why people loathe it" href="http://hardforum.com/showthread.php?s=9eb741eaa733ffb028c860e9805c04f5&amp;t=928593" target="_blank">How </a><a title="How VSync works, and why people loathe it" href="http://hardforum.com/showthread.php?s=9eb741eaa733ffb028c860e9805c04f5&amp;t=928593" target="_blank">VSync</a><a title="How VSync works, and why people loathe it" href="http://hardforum.com/showthread.php?s=9eb741eaa733ffb028c860e9805c04f5&amp;t=928593" target="_blank"> works, and why people loathe it</a>&#8220;:</p>
<blockquote><p>There is a technique called triple-buffering that solves this VSync problem. Lets go back to our 50FPS, 75Hz example. Frame 1 is in the frame buffer, and 2/3 of frame 2 are drawn in the back buffer. The refresh happens and frame 1 is grabbed for the first time. The last third of frame 2 are drawn in the back buffer, and the first third of frame 3 is drawn in the second back buffer (hence the term triple-buffering). The refresh happens, frame 1 is grabbed for the second time, and frame 2 is copied into the frame buffer and the first part of frame 3 into the back buffer. The last 2/3 of frame 3 are drawn in the back buffer, the refresh happens, frame 2 is grabbed for the first time, and frame 3 is copied to the frame buffer. The process starts over. This time we still got 2 frames, but in only 3 refresh cycles. That&#8217;s 2/3 of the refresh rate, which is 50FPS, exactly what we would have gotten without it. Triple-buffering essentially gives the video card someplace to keep doing work while it waits to transfer the back buffer to the frame buffer, so it doesn&#8217;t have to waste time. Unfortunately, triple-buffering isn&#8217;t available in every game, and in fact it isn&#8217;t too common. It also can cost a little performance to utilize, as it requires extra VRAM for the buffers, and time spent copying all of them around. However, triplebuffered VSync really is the key to the best experience as you eliminate tearing without the downsides of normal VSync (unless you consider the fact that your FPS is capped a downside&#8230; which is silly because you can&#8217;t see an FPS higher than your refresh anyway).</p></blockquote>
<p>If the thread is ever unavailable, you can download a PDF version <a title="PDF: How VSync works, and why people loathe it" href="http://tdistler.com/wp-content/uploads/2010/07/How-VSync-works-and-why-people-loathe-it.pdf" target="_blank">HERE</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/07/18/video-tearing-v-sync-and-triple-buffering/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ThreadNinja: Finding Rogue POSIX Threads</title>
		<link>http://tdistler.com/2010/07/08/threadninja-finding-rogue-posix-threads</link>
		<comments>http://tdistler.com/2010/07/08/threadninja-finding-rogue-posix-threads#comments</comments>
		<pubDate>Fri, 09 Jul 2010 02:10:04 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=277</guid>
		<description><![CDATA[What Is It? ThreadNinja is a Linux library my team created that tracks pthread_create() and pthread_join() calls in an application. It prints a stacktrace where each thread is created and where it is joined. Any rogue (unjoined) threads are reported when the application exits. ThreadNinja is unobtrusive: it does NOT have to be compiled into [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/05/tux-ninja.jpg"><img class="alignright size-thumbnail wp-image-278" title="tux-ninja" src="http://tdistler.com/wp-content/uploads/2010/05/tux-ninja-150x150.jpg" alt="Tux Ninja" width="150" height="150" /></a><strong>What Is It?</strong></p>
<p>ThreadNinja is a Linux library my team created that tracks <code>pthread_create()</code> and <code>pthread_join()</code> calls in an application. It prints a stacktrace where each thread is created and where it is joined. Any rogue (unjoined) threads are reported when the application exits. ThreadNinja is <em>unobtrusive</em>: it does NOT have to be compiled into the code. This means you can use it on applications you didn&#8217;t compile.</p>
<p>We found it useful and thought we&#8217;d share it. It&#8217;s be no means production code&#8230; just a tool. Hack on it, expand it, change it&#8230; whatever. It&#8217;s pretty small, so it should be easy to dive right in. We&#8217;ve released it under the <a title="BSD License Page" href="http://www.opensource.org/licenses/bsd-license.php" target="_blank">BSD license</a>.</p>
<p><strong>Cut To The Chase</strong></p>
<p>You can checkout the source code from <a title="Thread Ninja Project on Google Code" href="http://code.google.com/p/threadninja/" target="_blank">Google Code</a>, or download the version 1.0 tarball directly (<a title="Thread Ninja Source Tarball" href="http://www.tdistler.com/media/code/threadninja.tar.gz" target="_blank">threadninja.tar.gz</a>).</p>
<p>To build ThreadNinja, simply untar it and call <code>make</code>:<br />
<code>&gt; tar -zxf threadninja.tar.gz<br />
&gt; make</code></p>
<p>Now, simply use <code>LD_PRELOAD</code> to run the application:</p>
<p><code>&gt; LD_PRELOAD=/path/to/threadninja/build/libthreadninja.so.1 TheApplication</code></p>
<p>If you don&#8217;t see function names in the stacktraces that are generated, then the application needs to be compiled with debug symbols. For my test app, I had to compile with the <code>-rdynamic</code> option:</p>
<p><code>&gt; ﻿g++ -Wall -rdynamic main.cpp -lpthread</code></p>
<p>This causes the global symbol table to be included in the executable, which contains all the application&#8217;s function names. For more info, look at the <code>--export-dynamic</code> option on the <a title="GNU Linker man page" href="http://linux.die.net/man/1/ld" target="_blank">GNU linker (ld) man page</a>.</p>
<p><strong>The Story Behind ThreadNinja</strong></p>
<p>My team was assigned to stabilize a large video application that runs as a Linux-based appliance. The application consisted of 100,000+ of lines to code that was a tangle of build warnings, circular references, and many creative hacks. Our particular task was to fix a persistent set of seg-faults and memory leaks.<span id="more-277"></span></p>
<p>One of the first things we noticed was that the application didn&#8217;t shutdown properly. The shutdown logic was something akin to: signal components to exit, sleep 2 seconds, call Release() a couple times to clean up extra ref-counts, sleep 2 seconds, and then just call exit() to get the process to terminate (bypassing the remaining clean up code). Of course, this renders <a title="Valgrind" href="http://valgrind.org/" target="_blank">Valgrind</a> useless when trying to find memory leaks, because the automatic memory cleanup code gets bypassed during the process abort.</p>
<p>As a result, our first priority was to get the app to shutdown cleanly. The first issue we ran into was that <code>pthread_join()</code> blocked indefinitely because threads were failing to terminate. We tried using GDB to track the threads, but many hundreds of threads were being created and destroyed dynamically. We needed a way to let the application run for hours, allow 1000+ threads to live and die, and still be able to track rogue threads. Hence, ThreadNinja was born.</p>
<p><strong>How It Works</strong></p>
<p>Through the magic of <code><a title="LD_PRELOAD" href="http://linux.die.net/man/8/ld.so" target="_blank">LD_PRELOAD</a></code>, ThreadNinja &#8220;injects&#8221; itself between all calls to <code>pthread_create()</code> and <code>pthread_join()</code>. This happens because <code>LD_PRELOAD</code> instructs the loader to load ThreadNinja into memory first, before other libraries (in this case, before the pthread library). The result is that ThreadNinja&#8217;s implementation of <code>pthread_create()</code> and <code>pthread_join()</code> are used by the application instead of pthread&#8217;s own implementation. What ThreadNinja does is track the calls to these methods and then pass the call on to the &#8220;real&#8221; pthread implementation. From the application&#8217;s point-of-view, the behavior of the thread methods are the same&#8230; the tracking is transparent.</p>
<p><strong>Output</strong></p>
<p>Each time <code>pthread_create()</code> is called, a stacktrace and timestamp are printed to stdout:</p>
<p><code>Thread Created: 3047947120<br />
[bt] Thu Jul  8 16:31:23 2010</code></p>
<p><code>[bt] ./a.out(StartService(unsigned long*, int))<br />
[bt] ./a.out(Initialize())<br />
[bt] ./a.out(main+0xb) [0x80489fa]<br />
[bt] /lib/libc.so.6(__libc_start_main+0xe6) [0xb5bbb6]<br />
[bt] ./a.out() [0x8048811]</code></p>
<p>The first line (&#8220;Thread Created&#8221;) gives the value of the <code>pthread_t</code> handle, so you can later track where rogue threads where created. The next line is the time when the create happened. The remaining lines are the call stack that led to the <code>pthread_create()</code> call.</p>
<p>Each time <code>pthread_join()</code> is called, similar information is printed to stdout:</p>
<p><code>Thread Joined: 3047947120<br />
[bt] Thu Jul  8 16:31:31 2010</code></p>
<p><code>[bt] ./a.out(Terminate())<br />
[bt] ./a.out(main+0x10) [0x80489ff]<br />
[bt] /lib/libc.so.6(__libc_start_main+0xe6) [0xb5bbb6]<br />
[bt] ./a.out() [0x8048811]</code></p>
<p>When the application terminates (cleanly or uncleanly), a summary of the current state of the application threads is printed:</p>
<p><code>exit_handler()<br />
[Thread Summary]<br />
Total Created: 573<br />
Total Joined: 568<br />
Total Running: 5</code></p>
<p>In this case, you&#8217;ll notice that 5 threads were never joined on.</p>
<p><strong>Limitations</strong></p>
<p>ThreadNinja only tracks calls to <code>pthread_create()</code> and <code>pthread_join(</code>). This means calls like <code>system()</code>, <code>exec()</code>, and <code>fork()</code> are not tracked. Also, calls to <code>pthread_cancel()</code> are not tracked. We had started adding code to track pthread mutexes and stuff, but it turned out we didn&#8217;t need it. Feel free to add support for all this stuff and submit changes to the Google code site.</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/07/08/threadninja-finding-rogue-posix-threads/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>High-performance Timing on Linux / Windows</title>
		<link>http://tdistler.com/2010/06/27/high-performance-timing-on-linux-windows</link>
		<comments>http://tdistler.com/2010/06/27/high-performance-timing-on-linux-windows#comments</comments>
		<pubDate>Mon, 28 Jun 2010 05:15:55 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=350</guid>
		<description><![CDATA[High-performance timing is hard… no doubt about it. I can’t tell you how many times I’ve seen high-performance timing code done wrong. Timing is one of those things where a little knowledge can be problematic; the code may work, but it either won’t perform or will exhibit “unexplained” behavior. The purpose of this post is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/06/melting_clock.jpg"><img class="alignright size-full wp-image-352" title="melting_clock" src="http://tdistler.com/wp-content/uploads/2010/06/melting_clock.jpg" alt="Melting Clock" width="96" height="96" /></a>High-performance timing is hard… no doubt about it. I can’t tell you how many times I’ve seen high-performance timing code done wrong. Timing is one of those things where a little knowledge can be problematic; the code may work, but it either won’t perform or will exhibit “unexplained” behavior. The purpose of this post is to explain a foundational component to getting timing right: <em>the clock</em>. I won’t focus on theory… this post is meant to be pragmatic.</p>
<p><em>Note</em>: I’m talking here about interval timing (i.e. accurately measuring the duration between 2 events). This is different than synchronizing different clocks or maintaining accurate wall time.</p>
<p><strong>Anatomy of the Clock</strong></p>
<p>The first mistake most people make when doing timing is to use functions like <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/gettimeofday.html" target="_blank">gettimeofday()</a></code>, <code><a title="MSDN: GetSystemTime" href="http://msdn.microsoft.com/en-us/library/ms724390(VS.85).aspx" target="_blank">GetSystemTime()</a></code>, etc. These functions return what is called &#8220;wall time&#8221;… time that corresponds to a calendar date/time. These clocks suffer from the follow limitations:</p>
<ol>
<li>They have a low resolution: “High-performance” timing, by my definition, requires clock resolutions into the microseconds or better.</li>
<li>They can jump forwards and backwards in time: Computer clocks all tick at slightly different rates, which causes the time to drift. Most systems have NTP enabled which periodically adjusts the system clock to keep them in sync with “actual” time. The adjustment can cause the clock to suddenly jump forward (artificially inflating your timing numbers) or jump backwards (causing your timing calculations to go negative or hugely positive).</li>
</ol>
<p>For interval timing, all that’s needed for a clock is a simple counter that increments at a stable rate. For high-performance timing, the rate this counter increments should be high. A related constraint is that the counter must be monotonic (can never “tick” backwards&#8230; ever). The counter may overflow and wrap back to 0, but using unsigned math in your timing calculations can compensate for that (see example below).</p>
<p>Something to note: since we are usually measuring short durations, the drift of the clock is so small that we aren&#8217;t concerned by it (what matters is the drift between successive reads, not total drift over time).<span id="more-350"></span></p>
<p><strong>Using the Clock</strong></p>
<p>To use the clock, you need access to 2 pieces of information: the clock value, and the rate (frequency) at which it increments. Once you have that information, it’s trivial to calculate the duration between 2 successive reads of the clock.</p>
<p>For example, consider the following:</p>
<p>-        <code>start</code> equals the clock value at the beginning of the interval to measure.</p>
<p>-        <code>end</code> equals the clock value at the end of the interval.</p>
<p>-        <code>frequency</code> equals the frequency that the clock increments per second.</p>
<p>Calculating the duration of the interval (in seconds) is as simple as:</p>
<p><code>duration = (end – start) / frequency</code></p>
<p><code>duration</code> will equal the floating-point interval time in seconds (e.g. 0.000237 = 237us).</p>
<p>A common use case I’ve seen is wanting to measure the duration between successive calls to a function. Here’s one way to implement that:</p>
<pre><code>float freq = (float) get_frequency();

Foo()
{
    unsigned now = read_clock();
    float duration = (float)(now – last) / (float)freq;
    last = now;

    /* Your code here */
}
</code></pre>
<p>It is important to use unsigned variables for <code>now</code> and <code>last</code> or your calculations will go haywire if the clock ever wraps back to 0. Consider what happens if <code>now</code> is less than <code>last</code>. Using unsigned variables allows the math operation to underflow, which produces the correct result. If you don&#8217;t believe me, just write some test code and see for yourself&#8230; it&#8217;s an important concept to understand.</p>
<p><strong>Don’t Use RDTSC As Your Clock</strong></p>
<p>I’m dismayed by how many forum posts suggest that newbie’s use <a title="Wikipedia: RDTSC" href="http://en.wikipedia.org/wiki/RDTSC" target="_blank">RDTSC</a> for timing. Don’t get me wrong; the TSC isn’t bad in-and-of-itself. It’s just way too hard to get timing right with it unless you’re an expert… and if you’re reading this, chances are you aren’t <img src='http://tdistler.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Stick to the higher level API’s I present below.</p>
<p>Even if you are an expert, I still suggest avoiding RDTSC for the following reasons:</p>
<ol>
<li>It’s processor core specific: Using RDTSC will give different values on different processor cores. This causes non-monotonic clock behavior as a thread is migrated across cores during execution (i.e. the clock can tick backwards on two successive reads). Conversely, the clock may also appear to jump forwards if the thread moves to a different core.</li>
<li>It doesn’t always tick at the same rate: On some systems, the clock frequency will vary as the CPU load changes. This is due to power saving features in the processor that throttle down the clock speed when the load is low (e.g. Intel SpeedStep).</li>
<li>It’s unnecessary: there are better alternatives to RDTSC that are readily available (<a title="Wikipedia: High Precision Event Timer" href="http://en.wikipedia.org/wiki/High_Precision_Event_Timer" target="_blank">HPET</a> and <a title="Wikipedia: Advanced Programmable Interrupt Controller" href="http://en.wikipedia.org/wiki/Advanced_Programmable_Interrupt_Controller" target="_blank">APIC</a>).</li>
</ol>
<p>“<a title="Game Timing and Multicore Processors" href="http://msdn.microsoft.com/en-us/library/ee417693(VS.85).aspx" target="_blank">Game Timing and Multicore Processors</a>” has more info, though it’s centered around Windows.</p>
<p>“<a title="Guidelines For Providing Multimedia Support" href="http://www.microsoft.com/whdc/system/sysinternals/mm-timer.mspx" target="_blank">Guidelines For Providing Multimedia Support</a>” has a good summary of the hardware clocks on the PC platform, and justification for the creation of the HPET.</p>
<p>A more technical look into the past problems with RDTSC can be found in <a title="Email from Rick Brunner" href="http://lkml.org/lkml/2005/11/4/173" target="_blank">this email from Rick Brunner (AMD Fellow)</a>.</p>
<p>If you&#8217;re having trouble sleeping, you can look at <a title="Intel: HPET Design" href="http://www.intel.com/hardwaredesign/hpetspec_1.pdf" target="_blank">Intel’s HPET design document</a>.</p>
<p><strong>Linux Clock</strong></p>
<p>POSIX.1b defines realtime clock methods that you’ll find on most *NIX systems (the full spec can be viewed <a title="POSIX Specification 2008" href="http://www.opengroup.org/onlinepubs/9699919799/" target="_blank">HERE</a>). Specifically, you want to use <code>clock_getres()</code> and <code>clock_gettime()</code>. <code>clock_getres()</code> returns the resolution (frequency) of the clock, and <code>clock_gettime()</code> returns the current value of the clock. Most systems implement the <code>CLOCK_MONOTONIC</code> type, which provides a frequency-stable, monotonically-increasing counter. The resolution of <code>CLOCK_MONOTONIC</code> is high on the 2.6 kernel, in my experience. I recommend using this clock when building a high-performance timing solutions on Linux.</p>
<p>The methods are defined in <code>time.h</code>, and you need to link against librt (pass ‘-lrt’ to gcc). The prototypes for the functions are:</p>
<p><code>int clock_getres(clockid_t <em>clock_id</em>, struct timespec *<em>res</em>);</code><br />
<code>int clock_gettime(clockid_t <em>clock_id</em>, struct timespec *<em>tp</em>);</code></p>
<p>A detailed description of these methods can be found <a href="http://www.opengroup.org/onlinepubs/000095399/functions/clock_getres.html" target="_blank">HERE</a>.</p>
<p>I also suggest looking at <code><a href="http://www.opengroup.org/onlinepubs/000095399/functions/clock_nanosleep.html" target="_blank">clock_nanosleep()</a></code>, but that’s a separate topic.</p>
<p><strong>Windows Clock</strong></p>
<p>On Windows, <code><a href="http://msdn.microsoft.com/en-us/library/ms644905(VS.85).aspx" target="_blank">QueryPerformanceFrequency()</a></code> and <code><a href="http://msdn.microsoft.com/en-us/library/ms644904(v=VS.85).aspx" target="_blank">QueryPerformanceCounter()</a></code> are the obvious choice. <code>QueryPerformanceFrequency()</code> returns (surprise!) the frequency of the counter. <code>QueryPerformanceCounter()</code> returns the current value of the counter. Just like <code>CLOCK_MONOTONIC</code> on Linux, the Windows performance counter is a high-frequency, stable, monotonically-increasing counter.</p>
<p>The methods are defined in <code>windows.h</code>. The prototypes are:</p>
<p><code>BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);<br />
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)</code>;</p>
<p><strong>Windows Timing Errata</strong></p>
<p><em>Note</em>: The follow items do NOT affect the resolution of the Window’s performance counter, but I think it’s still important to know when doing timing on Windows.</p>
<p>One problem you may run into on Windows is that the default system clock interval defaults to 10 or 15ms (depending of the OS version). This clock is what drives all the timers and sleep functions for that platform. What this means is that, left to the default, your timers will trigger 5 to 7.5ms late, on average.</p>
<p>You can fix this by increasing the system clock resolution to 2ms (I remember reading a tech article by Microsoft saying that 2ms gave better system performance than 1ms, but I can’t find it for the life of me). You do this by using the <code>timeGetDevCaps()</code>, <code>timeBeginPeriod()</code> and <code>timeEndPeriod()</code>. Sample code can be found <a title="Windows Multimedia Timers" href="http://msdn.microsoft.com/en-us/library/dd743626(v=VS.85).aspx" target="_blank">HERE</a>. You have to include <code>mmsystem.h</code> and link against <code>Winmm.lib</code>.</p>
<p>I feel it necessary to note that increasing the system clock interval negatively affects power consumption. The Windows 7 blog as an interesting breakdown of “<a title="Windows 7 Energy Efficiency" href="http://blogs.msdn.com/b/e7/archive/2009/01/06/windows-7-energy-efficiency.aspx" target="_blank">Windows 7 Energy Efficiency</a>”. Specifically, they noticed a 10% drop in battery life when the clock resolution was set to 1ms using <code>timeBeginPeriod()</code>.</p>
<p>Maybe this last section belongs in a separate post, but whatever&#8230; <img src='http://tdistler.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/06/27/high-performance-timing-on-linux-windows/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Macros with Variable Argument Lists</title>
		<link>http://tdistler.com/2010/06/21/macros-with-variable-argument-lists</link>
		<comments>http://tdistler.com/2010/06/21/macros-with-variable-argument-lists#comments</comments>
		<pubDate>Mon, 21 Jun 2010 22:46:39 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=325</guid>
		<description><![CDATA[In C/C++, macros that take a variable number of arguments (called variadic macros) can be very useful. Having printf-style macros just makes certain things easier to read and understand. Below I&#8217;ll describe how to do this in a way that works on Windows and Linux, as well as supports empty argument lists. Example Consider the [...]]]></description>
			<content:encoded><![CDATA[<p>In C/C++, macros that take a variable number of arguments (called <a title="Variadic Macros" href="http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html" target="_blank">variadic macros</a>) can be very useful. Having printf-style macros just makes certain things easier to read and understand. Below I&#8217;ll describe how to do this in a way that works on Windows and Linux, as well as supports empty argument lists.</p>
<p><strong>Example</strong></p>
<p><strong> </strong>Consider the following log method:</p>
<p><code>void WriteLog( const LOG_LEVEL level, const char* file, const int line, const char* format, ... );</code></p>
<p>Pretty straight-forward: it allows you to specify the log level (NOTICE, WARNING, ERROR, etc), a file name and line number, and a user-defined description in &#8220;printf&#8221; format. To log a warning message, you would type:</p>
<p><code>WriteLog( LL_WARNING, __FILE__, __LINE__, "[WARNING] Failed to import descriptor '%s:%i'!", _descriptor, _id );</code></p>
<p>The entry in the log file would look like:</p>
<p><code>Core.cpp:715 [WARNING] Failed to import descriptor 'timing-engine'!</code></p>
<p><strong>Creating a Variadic Macro</strong></p>
<p>Calling <code>WriteLog</code> directly works fine, but it&#8217;s pretty verbose and annoying to use. One way to make it simpler is to wrap <code>WriteLog</code> with a variadic macro:</p>
<p><code> #define LOG_WARNING( format, ... ) \\<br />
WriteLog( LL_WARNING, __FILE__, __LINE__, "[WARNING] " format, ##__VA_ARGS__ );</code></p>
<p>Then the example above would become:</p>
<p><code>LOG_WARNING( "Failed to import descriptor '%s:%i'!", _descriptor, _id );</code></p>
<p>The macro automatically fills in the file and line number where the log message was generated, and the log level is specified by the macro name (<code>LOG_WARNING</code>). This is much more straight-forward and I believe it makes the code easier to read.</p>
<p>Notice that <code>__VA_ARGS__</code> is used to get the variable argument list and pass it to <code>WriteLog</code>. During compilation, the preprocessor replaces <code>__VA_ARGS__</code> with the comma-separated list of  arguments. The &#8216;<code>##</code>&#8216; that prefixes <code>__VA_ARGS__</code> is vital if you want your macro to work like you expect. Without it, you would be <em>required</em> to have at least one argument after the format string. &#8217;<code>##</code>&#8216; has a special meaning in this case: it causes the preceding comma to be deleted if there are no variable arguments. Without this, the following line would generate a syntax error:</p>
<p><code>LOG_WARNING( "This would cause a syntax error" );</code></p>
<p>Prefixing <code>__VA_ARGS__</code> with &#8216;<code>##</code>&#8216; allows the above code to work just fine.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/06/21/macros-with-variable-argument-lists/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stop Stealing My File Descriptors!</title>
		<link>http://tdistler.com/2010/06/18/stop-stealing-my-file-descriptors</link>
		<comments>http://tdistler.com/2010/06/18/stop-stealing-my-file-descriptors#comments</comments>
		<pubDate>Fri, 18 Jun 2010 21:48:43 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=313</guid>
		<description><![CDATA[We ran into a weird problem the other day where our Linux video display appliance would lose audio support when the process was restarted. The audio was supposed to play through a custom joystick-keyboard that was attached via USB (the keyboard is used by security guards to PTZ cameras, control monitors, etc). The audio could [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/06/sherlock_tux.jpg"><img class="alignright size-thumbnail wp-image-319" title="sherlock_tux" src="http://tdistler.com/wp-content/uploads/2010/06/sherlock_tux-150x150.jpg" alt="Sherlock Tux" width="150" height="150" /></a>We ran into a weird problem the other day where our Linux video display appliance would lose audio support when the process was restarted. The audio was supposed to play through a custom joystick-keyboard that was attached via USB (the keyboard is used by security guards to PTZ cameras, control monitors, etc). The audio could be heard just fine when the box first booted, but if the application restarted audio would be lost.</p>
<p>Looking at the logs, we found that our audio pipeline was failing to open <code>/dev/dsp</code> on the restart. We then used <code>lsof</code> to list the open file descriptors to see which process currently held <code>/dev/dsp</code>:</p>
<p><code># lsof | grep /dev/dsp<br />
ntpd   18857    root   16u    CHR     14,3    180099 /dev/dsp<br />
</code></p>
<p>What!?!?&#8230; why the heck is NTP opening the sound device and how did it steal it from us??? After some discussion we started remembering a problem in the past with <code>ntpd</code> stealing our SNMP diagnostics port. This just didn&#8217;t make any sense.</p>
<p>Digging into our appliance code, we found this line:</p>
<p><code>system( "service ntpd restart" );</code></p>
<p>This would be called each time we were notified by the security system that the NTP server address had changed (which fired once each time the process was started so we could get the initial address). But this still didn&#8217;t explain why NTP took over ownership of our file descriptors on restart.</p>
<p>Long story short: <code>system()</code> is implemented as <code>fork()</code> followed by <code>execv()</code>. By default, <code>fork()</code> gives a copy of the parent&#8217;s file descriptors to the child process (i.e. the <code>ntpd</code> child process got a copy of the <code>/dev/dsp</code> file descriptor). To prevent this, you have to set the <code>FD_CLOEXEC</code> flag on the file desciptors you don&#8217;t want copied.</p>
<p>For example:</p>
<p><code>fd = open( "/dev/dsp", O_RDWR );<br />
fcntl( fd, F_SETFD, FD_CLOEXEC );</code></p>
<p><strong>Conclusion</strong>: setting the <code>FD_CLOEXEC</code> flag on the <code>/dev/dsp</code> file descriptor fixed the problem for audio. However, most of the other file desciptors still got owned by <code>ntpd</code>. Did we go back and set the <code>FD_CLOEXEC</code> flag on all file descriptors, you ask? Nope. It turns out we had a script monitoring the NTP config file and restarting ntpd for us when the file got updated&#8230; we just had to update the config file and remove the <code>system( "service ntpd restart" )</code> call.</p>
<p>Oh, and the reason audio worked on first boot but not subsequent restarts was due to a weird race condition around when <code>/dev/dsp</code> got opened.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/06/18/stop-stealing-my-file-descriptors/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

