<?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>Jean&#039;s Page &#187; Jean</title>
	<atom:link href="http://jeanbruenn.info/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeanbruenn.info</link>
	<description>so what?</description>
	<lastBuildDate>Fri, 13 Apr 2012 20:50:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>New Lunar Linux Frontpage and my lunar blog posts moving</title>
		<link>http://jeanbruenn.info/2012/01/06/new-lunar-linux-frontpage-and-my-lunar-blog-posts-moving/</link>
		<comments>http://jeanbruenn.info/2012/01/06/new-lunar-linux-frontpage-and-my-lunar-blog-posts-moving/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 12:51:56 +0000</pubDate>
		<dc:creator>Jean</dc:creator>
				<category><![CDATA[lunar linux]]></category>

		<guid isPermaLink="false">http://jeanbruenn.info/?p=1189</guid>
		<description><![CDATA[Hey, due to striker&#8217;s migration from Joomla to WordPress yesterday, all my lunar related posts will now belong to my devblog at lunar linux. Jean]]></description>
			<content:encoded><![CDATA[<p>Hey,</p>
<p>due to striker&#8217;s <a href="http://www.lunar-linux.org/2012/01/06/new-look/">migration from Joomla to WordPress</a> yesterday, all my lunar related posts will now belong to <a href="http://wdp.blogs.lunar-linux.org/">my devblog at lunar linux</a>. </p>
<p>Jean</p>
]]></content:encoded>
			<wfw:commentRss>http://jeanbruenn.info/2012/01/06/new-lunar-linux-frontpage-and-my-lunar-blog-posts-moving/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upscaling in Avisynth &#8211; Comparison of resizers</title>
		<link>http://jeanbruenn.info/2011/10/30/upscaling-in-avisynth-comparison-of-resizers/</link>
		<comments>http://jeanbruenn.info/2011/10/30/upscaling-in-avisynth-comparison-of-resizers/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 20:05:27 +0000</pubDate>
		<dc:creator>Jean</dc:creator>
				<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://jeanbruenn.info/?p=1106</guid>
		<description><![CDATA[I made this tests because I was searching for a pretty good upscaler. Checking pictures manually is a very subjective thing and so I wanted a way to &#8220;calculate&#8221; how good a/an scaler/upscaler is. The easiest approach is to check, how similar the upscaled variant is to the original variant. Which is, what my tests [...]]]></description>
			<content:encoded><![CDATA[<p>I made this tests because I was searching for a pretty good upscaler. Checking pictures manually is a very subjective thing and so I wanted a way to &#8220;calculate&#8221; how good a/an scaler/upscaler is. The easiest approach is to check, how similar the upscaled variant is to the original variant. Which is, what my tests do.</p>
<p><span id="more-1106"></span></p>
<ol>
<li><a href="#usedsoftware">used software/material</a></li>
<li><a href="#preparation">preparation</a></li>
<li><a href="#execution">execution</a></li>
<li><a href="#results">results</a>
<ol>
<li><a href="#testcase1">testcase1 &#8211; big buck bunny 1920&#215;1080 &raquo; lanczos 854&#215;480 &raquo; 1920&#215;1080</a></li>
<li><a href="#testcase2">testcase2 &#8211; sintel 1920&#215;818 &raquo; lanczos 1126&#215;480 &raquo; 1920&#215;1080</a></li>
<li><a href="#testcase3">testcase3 &#8211; elephants dream 1920&#215;1080 &raquo; bicubic 640&#215;360 &raquo; 1920&#215;1080</a></li>
<li><a href="#result">overall result</a></li>
<li><a href="#visual">visual results</a></li>
</ol>
</li>
<li><a href="#conclusion">conclusion</a></li>
</ol>
<p><a name="usedsoftware">&nbsp;</a><br />
<strong>used software/material</strong><br />
MPlayer, Avisynth, Bash, Gimp, ImageMagick, OpenMovie Sintel, OpenMovie Big Buck Bunny, OpenMovie Elephants Dream</p>
<p><a name="preparation">&nbsp;</a><br />
<strong>preparation</strong><br />
I took screenshots of a movie, stored the original highres image and created a lowscaled version of it. Then I created upscaled (to the same resolution as the highres image) variants of that lowscaled variant. And finally I compared the upscaled variant with the original highres variant.</p>
<p><a name="execution">&nbsp;</a><br />
<strong>execution</strong><br />
To create screenshots I have written a little Bashscript which gets screenshots using mplayer. The quality of the jpegs is set to 100 to have &#8220;lossless&#8221; images (more or less). The script needs ffmpeg to get the duration of the movie (pretty sure that might work with mplayer aswell, just didn&#8217;t find out how to easily parse that):</p>
<pre>#!/bin/bash

infile=$1;
amount=$2;

# getting the length of the movie in seconds
ffmpeg -i "$infile" 2>/tmp/video.log
h=$(grep Duration /tmp/video.log | awk '{ print $2 }' | cut -d: -f1);
m=$(grep Duration /tmp/video.log | awk '{ print $2 }' | cut -d: -f2);
s=$(echo "($h * 60 * 60) + ($m * 60) - 60" | bc);

for (( x=1; x<=$amount; x++)); do
  stime=$(echo "$x * ($s / $amount)" | bc);
  echo $stime;
  tmp=$(mplayer -frames 1 -ss $stime -vo jpeg:quality=100:outdir=screens $infile > /dev/null);
  mv screens/00000001.jpg screens/$x.jpg
done</pre>
<p>Then I&#8217;ve used gimp to create low-res variants of that screens &#8211; For the first two testcases I used lanczos and downscaled to a height of 480px. For the third testcase I used bicubic and downscaled to a height of 360px.</p>
<p>Then I&#8217;ve used lots of avisynth scripts to do the upscaling. An example for blackman and nnedi3:</p>
<pre>source = ImageSource("3.jpg").Trim(0,-1)
us3 = BlackmanResize(source, 1920, 1080)
us13 = nnedi3_rpow2(source, rfactor=4, cshift="spline36resize", fwidth=1920, fheight=1080)

#ImageWriter(us3, file="3_blackman", type="jpeg")
ImageWriter(us13, file="3_nnedi3", type="jpeg")</pre>
<p>The resulting upscaled image I&#8217;ve compared to the original image using ImageMagick:</p>
<pre>convert originalimage.jpg upscaledimage.jpg -fx "abs(u[0]-u[1])" pgm:- \
  | identify -verbose pgm:- \
  | grep -E "mean|max|devi"</pre>
<p><a name="results">&nbsp;</a><br />
<strong>results</strong></p>
<p><a name="testcase1">&nbsp;</a><br />
<em>Big Buck Bunny</em></p>
<p>1920&#215;1080 &raquo; (lanczos) 854&#215;480 &raquo; 1920&#215;1080</p>
<table cellspacing="5" cellpadding="3" border="0" style="font-size: 10px;" class="video">
<tr>
<td><b>screenthumbnail</b></td>
<td><b>method used</b></td>
<td><b>peak</b></td>
<td><b>average</b></td>
<td><b>standard deviation</b></td>
<td><b>filesize</b></td>
</tr>
<tr>
<td rowspan="14" style="vertical-align: top;"><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/1.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_1.jpg' height='60' alt='1' class='ngg-singlepic ngg-none' /></a></td>
<td>original</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>640K</td>
</tr>
<tr>
<td>bicubicResize</td>
<td>63 (0.247059)</td>
<td>1.39138 (0.0054564)</td>
<td>2.02799 (0.00795292)</td>
<td>564K</td>
</tr>
<tr>
<td>bilinearResize</td>
<td>66 (0.258824)</td>
<td>1.41046 (0.00553122)</td>
<td>2.1246 (0.00833176)</td>
<td>568K</td>
</tr>
<tr>
<td>blackmanResize</td>
<td>60 (0.235294)</td>
<td>1.32716 (0.00520453)</td>
<td>1.7842 (0.00699688)</td>
<td>584K</td>
</tr>
<tr>
<td>lanczosResize</td>
<td>59 (0.231373)</td>
<td>1.32695 (0.00520371)</td>
<td>1.76561 (0.00692397)</td>
<td>588K</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>58 (0.227451)</td>
<td>1.31528 (0.00515796)</td>
<td>1.73246 (0.00679397)</td>
<td>592K</td>
</tr>
<tr>
<td>pointresize</td>
<td>138 (0.541176)</td>
<td>1.93816 (0.00760062)</td>
<td>3.38685 (0.0132818)</td>
<td>688K</td>
</tr>
<tr>
<td>sincresize</td>
<td>97 (0.380392)</td>
<td>1.94942 (0.00764479)</td>
<td>3.12623 (0.0122597)</td>
<td>712K</td>
</tr>
<tr>
<td>spline16resize</td>
<td>60 (0.235294)</td>
<td>1.34655 (0.0052806)</td>
<td>1.85531 (0.00727572)</td>
<td>580K</td>
</tr>
<tr>
<td>spline36resize</td>
<td>58 (0.227451)</td>
<td>1.32948 (0.00521366)</td>
<td>1.78602 (0.00700402)</td>
<td>584K</td>
</tr>
<tr>
<td>spline64resize</td>
<td>59 (0.231373)</td>
<td>1.3242 (0.00519292)</td>
<td>1.77446 (0.00695865)</td>
<td>584K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36)</td>
<td>59 (0.231373)</td>
<td>1.34151 (0.00526083)</td>
<td>1.76169 (0.00690858)</td>
<td>616K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td>56 (0.219608)</td>
<td>1.34097 (0.0052587)</td>
<td>1.76592 (0.00692518)</td>
<td>620K</td>
</tr>
<tr>
<td>spline36resize(hq4x)</td>
<td>81 (0.317647)</td>
<td>1.61154 (0.00631977)</td>
<td>2.08531 (0.00817769)</td>
<td>568K</td>
</tr>
<tr>
<td><b>screenthumbnail</b></td>
<td><b>method used</b></td>
<td><b>peak</b></td>
<td><b>average</b></td>
<td><b>standard deviation</b></td>
<td><b>filesize</b></td>
</tr>
<tr>
<td rowspan="14" style="vertical-align: top;"><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/2.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_2.jpg' height='60' alt='2' class='ngg-singlepic ngg-none' /></a></td>
<td>original</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>1100K</td>
</tr>
<tr>
<td>bicubicresize</td>
<td>131 (0.513725)</td>
<td>2.01965 (0.0079202)</td>
<td>2.58451 (0.0101353)</td>
<td>716K</td>
</tr>
<tr>
<td>bilinearresize</td>
<td>129 (0.505882)</td>
<td>2.06215 (0.00808685)</td>
<td>2.66154 (0.0104374)</td>
<td>724K</td>
</tr>
<tr>
<td>blackmanresize</td>
<td>128 (0.501961)</td>
<td>1.92173 (0.0075362)</td>
<td>2.37666 (0.00932023)</td>
<td>744K</td>
</tr>
<tr>
<td>lanczosresize</td>
<td>128 (0.501961)</td>
<td>1.91967 (0.0075281)</td>
<td>2.36059 (0.00925722)</td>
<td>752K</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>128 (0.501961)</td>
<td>1.89933 (0.00744836)</td>
<td>2.33001 (0.00913729)</td>
<td>756K</td>
</tr>
<tr>
<td>pointresize</td>
<td>173 (0.678431)</td>
<td>3.04469 (0.01194)</td>
<td>3.97362 (0.0155828)</td>
<td>924K</td>
</tr>
<tr>
<td>sincresize</td>
<td>167 (0.654902)</td>
<td>2.94485 (0.0115484)</td>
<td>3.62896 (0.0142312)</td>
<td>920K</td>
</tr>
<tr>
<td>spline16resize</td>
<td>128 (0.501961)</td>
<td>1.95451 (0.00766474)</td>
<td>2.44045 (0.00957039)</td>
<td>740K</td>
</tr>
<tr>
<td>spline36resize</td>
<td>128 (0.501961)</td>
<td>1.92393 (0.00754484)</td>
<td>2.37922 (0.00933026)</td>
<td>744K</td>
</tr>
<tr>
<td>spline64resize</td>
<td>129 (0.505882)</td>
<td>1.91636 (0.00751512)</td>
<td>2.36858 (0.00928855)</td>
<td>744K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36)</td>
<td>119 (0.466667)</td>
<td>1.94348 (0.00762151)</td>
<td>2.34163 (0.00918287)</td>
<td>776K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td>112 (0.439216)</td>
<td>1.94203 (0.00761579)</td>
<td>2.34288 (0.00918778)</td>
<td>776K</td>
</tr>
<tr>
<td>spline36resize(hq4x)</td>
<td>122 (0.478431)</td>
<td>2.19204 (0.00859625)</td>
<td>2.6589 (0.0104271)</td>
<td>744K</td>
</tr>
<tr>
<td><b>screenthumbnail</b></td>
<td><b>method used</b></td>
<td><b>peak</b></td>
<td><b>average</b></td>
<td><b>standard deviation</b></td>
<td><b>filesize</b></td>
</tr>
<tr>
<td rowspan="14" style="vertical-align: top;"><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/3.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_3.jpg' height='60' alt='3' class='ngg-singlepic ngg-none' /></a></td>
<td>original</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>732K</td>
</tr>
<tr>
<td>bicubicresize</td>
<td>49 (0.192157)</td>
<td>1.32602 (0.00520009)</td>
<td>1.51821 (0.00595376)</td>
<td>572K</td>
</tr>
<tr>
<td>bilinearresize</td>
<td>53 (0.207843)</td>
<td>1.33697 (0.00524301)</td>
<td>1.57944 (0.0061939)</td>
<td>572K</td>
</tr>
<tr>
<td>blackmanresize</td>
<td>43 (0.168627)</td>
<td>1.29434 (0.00507583)</td>
<td>1.3829 (0.00542314)</td>
<td>592K</td>
</tr>
<tr>
<td>lanczosresize</td>
<td>41 (0.160784)</td>
<td>1.29722 (0.00508715)</td>
<td>1.37439 (0.00538977)</td>
<td>596K</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>41 (0.160784)</td>
<td>1.28806 (0.00505121)</td>
<td>1.35241 (0.00530357)</td>
<td>596K</td>
</tr>
<tr>
<td>pointresize</td>
<td>144 (0.564706)</td>
<td>1.86225 (0.00730295)</td>
<td>2.74764 (0.010775)</td>
<td>692K</td>
</tr>
<tr>
<td>sincresize</td>
<td>110 (0.431373)</td>
<td>1.85213 (0.00726325)</td>
<td>2.47998 (0.00972541)</td>
<td>708K</td>
</tr>
<tr>
<td>spline16resize</td>
<td>44 (0.172549)</td>
<td>1.306 (0.00512158)</td>
<td>1.42527 (0.00558931)</td>
<td>584K</td>
</tr>
<tr>
<td>spline36resize</td>
<td>43 (0.168627)</td>
<td>1.29596 (0.00508218)</td>
<td>1.38413 (0.00542798)</td>
<td>588K</td>
</tr>
<tr>
<td>spline64resize</td>
<td>42 (0.164706)</td>
<td>1.29306 (0.00507082)</td>
<td>1.37745 (0.00540178)</td>
<td>592K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36)</td>
<td>39 (0.152941)</td>
<td>1.30354 (0.00511192)</td>
<td>1.36729 (0.00536193)</td>
<td>620K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td>39 (0.152941)</td>
<td>1.30032 (0.00509928)</td>
<td>1.36227 (0.00534222)</td>
<td>624K</td>
</tr>
<tr>
<td>spline36resize(hq4x)</td>
<td>77 (0.301961)</td>
<td>1.52609 (0.00598468)</td>
<td>1.58047 (0.00619794)</td>
<td>572K</td>
</tr>
</table>
<p><a name="testcase2">&nbsp;</a><br />
<em>Sintel</em></p>
<p>1920&#215;818 &raquo; (lanczos) 1126&#215;480 &raquo; 1920&#215;1080</p>
<table cellspacing="5" cellpadding="3" border="0" style="font-size: 10px;" class="video">
<tr>
<td><b>screenthumbnail</b></td>
<td><b>method used</b></td>
<td><b>peak</b></td>
<td><b>average</b></td>
<td><b>standard deviation</b></td>
<td><b>filesize</b></td>
</tr>
<tr>
<td rowspan="15" style="vertical-align: top;"><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/1_0.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_1_0.jpg' height='40' alt='1_0' class='ngg-singlepic ngg-none' /></a></td>
</tr>
<tr>
<td>original</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>620K</td>
</tr>
<tr>
<td>bicubicresize</td>
<td>76 (0.298039)</td>
<td>1.22795 (0.00481549)</td>
<td>1.64521 (0.00645182)</td>
<td>444K</td>
</tr>
<tr>
<td>bilinearresize</td>
<td>78 (0.305882)</td>
<td>1.22377 (0.0047991)</td>
<td>1.66566 (0.00653199)</td>
<td>440K</td>
</tr>
<tr>
<td>blackmanresize</td>
<td>72 (0.282353)</td>
<td>1.23057 (0.00482575)</td>
<td>1.57433 (0.00617384)</td>
<td>464K</td>
</tr>
<tr>
<td>lanczosresize</td>
<td>71 (0.278431)</td>
<td>1.2383 (0.00485609)</td>
<td>1.57933 (0.00619346)</td>
<td>468K</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>70 (0.27451)</td>
<td>1.24825 (0.00489511)</td>
<td>1.59137 (0.00624068)</td>
<td>472K</td>
</tr>
<tr>
<td>pointresize</td>
<td>106 (0.415686)</td>
<td>1.48345 (0.00581747)</td>
<td>2.42587 (0.00951323)</td>
<td>508K</td>
</tr>
<tr>
<td>sincresize</td>
<td>88 (0.345098)</td>
<td>1.47682 (0.00579147)</td>
<td>2.15301 (0.00844318)</td>
<td>492K</td>
</tr>
<tr>
<td>spline16resize</td>
<td>73 (0.286275)</td>
<td>1.2257 (0.00480666)</td>
<td>1.58467 (0.00621438)</td>
<td>460K</td>
</tr>
<tr>
<td>spline36resize</td>
<td>72 (0.282353)</td>
<td>1.23204 (0.00483153)</td>
<td>1.57656 (0.00618259)</td>
<td>464K</td>
</tr>
<tr>
<td>spline64resize</td>
<td>71 (0.278431)</td>
<td>1.23371 (0.00483806)</td>
<td>1.57686 (0.00618377)</td>
<td>464K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36)</td>
<td>70 (0.27451)</td>
<td>1.2102 (0.00474587)</td>
<td>1.53526 (0.00602061)</td>
<td>484K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td>76 (0.298039)</td>
<td>1.20684 (0.00473269)</td>
<td>1.53277 (0.00601086)</td>
<td>484K</td>
</tr>
<tr>
<td>spline36resize(hq4x)</td>
<td>77 (0.301961)</td>
<td>1.4199 (0.00556825)</td>
<td>1.62984 (0.00639155)</td>
<td>416K</td>
</tr>
<tr>
<td><b>screenthumbnail</b></td>
<td><b>method used</b></td>
<td><b>peak</b></td>
<td><b>average</b></td>
<td><b>standard deviation</b></td>
<td><b>filesize</b></td>
</tr>
<tr>
<td rowspan="15" style="vertical-align: top;"><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/2_0.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_2_0.jpg' height='40' alt='2_0' class='ngg-singlepic ngg-none' /></a></td>
</tr>
<tr>
<td>original</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>1200K</td>
</tr>
<tr>
<td>bicubicresize</td>
<td>68 (0.266667)</td>
<td>3.90677 (0.0153207)</td>
<td>4.63845 (0.01819)</td>
<td>756K</td>
</tr>
<tr>
<td>bilinearresize</td>
<td>72 (0.282353)</td>
<td>3.93428 (0.0154286)</td>
<td>4.70239 (0.0184407)</td>
<td>772K</td>
</tr>
<tr>
<td>blackmanresize</td>
<td>70 (0.27451)</td>
<td>3.75073 (0.0147087)</td>
<td>4.45619 (0.0174752)</td>
<td>824K</td>
</tr>
<tr>
<td>lanczosresize</td>
<td>69 (0.270588)</td>
<td>3.77025 (0.0147853)</td>
<td>4.47537 (0.0175505)</td>
<td>832K</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>70 (0.27451)</td>
<td>3.80719 (0.0149302)</td>
<td>4.51547 (0.0177077)</td>
<td>832K</td>
</tr>
<tr>
<td>pointresize</td>
<td>141 (0.552941)</td>
<td>5.41135 (0.021221)</td>
<td>7.10313 (0.0278554)</td>
<td>992K</td>
</tr>
<tr>
<td>sincresize</td>
<td>113 (0.443137)</td>
<td>5.13697 (0.020145)</td>
<td>6.00752 (0.0235589)</td>
<td>880K</td>
</tr>
<tr>
<td>spline16resize</td>
<td>70 (0.27451)</td>
<td>3.76273 (0.0147558)</td>
<td>4.47469 (0.0175478)</td>
<td>812K</td>
</tr>
<tr>
<td>spline36resize</td>
<td>70 (0.27451)</td>
<td>3.75862 (0.0147397)</td>
<td>4.46286 (0.0175014)</td>
<td>820K</td>
</tr>
<tr>
<td>spline64resize</td>
<td>70 (0.27451)</td>
<td>3.7603 (0.0147463)</td>
<td>4.46454 (0.017508)</td>
<td>824K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36)</td>
<td>75 (0.294118)</td>
<td>3.69705 (0.0144982)</td>
<td>4.36505 (0.0171178)</td>
<td>836K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td>72 (0.282353)</td>
<td>3.68776 (0.0144618)</td>
<td>4.35658 (0.0170846)</td>
<td>836K</td>
</tr>
<tr>
<td>spline36resize(hq4x)</td>
<td>68 (0.266667)</td>
<td>3.9761 (0.0155926)</td>
<td>4.64142 (0.0182016)</td>
<td>760K</td>
</tr>
<tr>
<td><b>screenthumbnail</b></td>
<td><b>method used</b></td>
<td><b>peak</b></td>
<td><b>average</b></td>
<td><b>standard deviation</b></td>
<td><b>filesize</b></td>
</tr>
<tr>
<td rowspan="15" style="vertical-align: top;"><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/3_0.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_3_0.jpg' height='40' alt='3_0' class='ngg-singlepic ngg-none' /></a></td>
</tr>
<tr>
<td>original</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>652K</td>
</tr>
<tr>
<td>bicubicresize</td>
<td>102 (0.4)</td>
<td>1.61719 (0.00634193)</td>
<td>3.41673 (0.013399)</td>
<td>516K</td>
</tr>
<tr>
<td>bilinearresize</td>
<td>113 (0.443137)</td>
<td>1.62747 (0.00638224)</td>
<td>3.50645 (0.0137508)</td>
<td>516K</td>
</tr>
<tr>
<td>blackmanresize</td>
<td>103 (0.403922)</td>
<td>1.57874 (0.00619113)</td>
<td>3.1816 (0.0124769)</td>
<td>544K</td>
</tr>
<tr>
<td>lanczosresize</td>
<td>107 (0.419608)</td>
<td>1.58978 (0.00623445)</td>
<td>3.1924 (0.0125192)</td>
<td>548K</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>118 (0.462745)</td>
<td>1.60308 (0.00628658)</td>
<td>3.20413 (0.0125652)</td>
<td>552K</td>
</tr>
<tr>
<td>pointresize</td>
<td>212 (0.831373)</td>
<td>2.33259 (0.00914742)</td>
<td>5.96943 (0.0234095)</td>
<td>612K</td>
</tr>
<tr>
<td>sincresize</td>
<td>141 (0.552941)</td>
<td>2.18924 (0.00858526)</td>
<td>4.94182 (0.0193797)</td>
<td>588K</td>
</tr>
<tr>
<td>spline16resize</td>
<td>102 (0.4)</td>
<td>1.58086 (0.00619945)</td>
<td>3.22538 (0.0126486)</td>
<td>536K</td>
</tr>
<tr>
<td>spline36resize</td>
<td>104 (0.407843)</td>
<td>1.58196 (0.00620377)</td>
<td>3.18951 (0.0125079)</td>
<td>544K</td>
</tr>
<tr>
<td>spline64resize</td>
<td>106 (0.415686)</td>
<td>1.58257 (0.00620615)</td>
<td>3.18302 (0.0124824)</td>
<td>544K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36)</td>
<td>99 (0.388235)</td>
<td>1.52185 (0.00596802)</td>
<td>2.96699 (0.0116352)</td>
<td>560K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td>101 (0.396078)</td>
<td>1.52184 (0.00596802)</td>
<td>2.98155 (0.0116923)</td>
<td>560K</td>
</tr>
<tr>
<td>spline36resize(hq4x)</td>
<td>106 (0.415686)</td>
<td>1.80159 (0.00706505)</td>
<td>3.38661 (0.0132808)</td>
<td>496K</td>
</tr>
</table>
<p><em>Averaged</em></p>
<table cellspacing="5" cellpadding="3" border="0" class="video">
<tr>
<td><b>method</b></td>
<td><b>average peak</b></td>
<td><b>average mean</b></td>
<td><b>average standard deviatation</b></td>
</tr>
<tr>
<td>bicubicresize</td>
<td>81.5</td>
<td>1.91</td>
<td>2.63</td>
</tr>
<tr>
<td>bilinearresize</td>
<td>85.16</td>
<td>1.93</td>
<td>2.70</td>
</tr>
<tr>
<td>blackmanresize</td>
<td>79.33</td>
<td>1.85</td>
<td>2.45</td>
</tr>
<tr>
<td>lanczosresize</td>
<td>79.16</td>
<td>1.85</td>
<td>2.45</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>80.83</td>
<td>1.86</td>
<td>2.45</td>
</tr>
<tr>
<td class="lightred">pointresize</td>
<td class="lightred">152.33</td>
<td class="lightred">2.67</td>
<td class="lightred">4.26</td>
</tr>
<tr>
<td class="lightred">sincresize</td>
<td class="lightred">119.33</td>
<td class="lightred">2.59</td>
<td class="lightred">3.72</td>
</tr>
<tr>
<td>spline16resize</td>
<td>79.5</td>
<td>1.86</td>
<td>2.5</td>
</tr>
<tr>
<td>spline36resize</td>
<td>79.16</td>
<td>1.85</td>
<td>2.46</td>
</tr>
<tr>
<td>spline64resize</td>
<td>79.5</td>
<td>1.85</td>
<td>2.45</td>
</tr>
<tr>
<td class="lightgreen">nnedi3 (cshift=spline36)</td>
<td class="lightgreen">76.83</td>
<td class="lightgreen">1.83</td>
<td class="lightgreen">2.38</td>
</tr>
<tr>
<td class="lightgreen">nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td class="lightgreen">76</td>
<td class="lightgreen">1.83</td>
<td class="lightgreen">2.39</td>
</tr>
<tr>
<td>spline36resize(hq4x)</td>
<td>88.5</td>
<td>2.08</td>
<td>2.66</td>
</tr>
</table>
<p><a name="testcase3">&nbsp;</a><br />
<em>Elephants Dream</em></p>
<p>1920&#215;1080 &raquo; (bicubic) 640&#215;360 &raquo; 1920&#215;1080</p>
<table cellspacing="5" cellpadding="3" border="0" style="font-size: 10px;" class="video">
<tr>
<td><b>screenthumbnail</b></td>
<td><b>method used</b></td>
<td><b>peak</b></td>
<td><b>average</b></td>
<td><b>standard deviation</b></td>
<td><b>filesize</b></td>
</tr>
<tr>
<td rowspan="10" style="vertical-align: top;"><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/1_1.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_1_1.jpg' height='40' alt='1_1' class='ngg-singlepic ngg-none' /></a></td>
</tr>
<tr>
<td>original</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>696K</td>
</tr>
<tr>
<td>blackmanresize</td>
<td>182 (0.713725)</td>
<td>5.15758 (0.0202258)</td>
<td>9.2996 (0.036469)</td>
<td>672K</td>
</tr>
<tr>
<td>lanczosresize</td>
<td>181 (0.709804)</td>
<td>5.17115 (0.020279)</td>
<td>9.25688 (0.0363015)</td>
<td>676K</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>180 (0.705882)</td>
<td>5.19959 (0.0203906)</td>
<td>9.21027 (0.0361187)</td>
<td>684K</td>
</tr>
<tr>
<td>spline16resize</td>
<td>183 (0.717647)</td>
<td>5.21444 (0.0204488)</td>
<td>9.46563 (0.0371201)</td>
<td>672K</td>
</tr>
<tr>
<td>spline36resize</td>
<td>182 (0.713725)</td>
<td>5.1683 (0.0202678)</td>
<td>9.30998 (0.0365097)</td>
<td>672K</td>
</tr>
<tr>
<td>spline64resize</td>
<td>182 (0.713725)</td>
<td>5.16437 (0.0202524)</td>
<td>9.28429 (0.036409)</td>
<td>672K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36)</td>
<td>174 (0.682353)</td>
<td>4.71817 (0.0185026)</td>
<td>8.52777 (0.0334422)</td>
<td>724K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td>176 (0.690196)</td>
<td>4.70834 (0.0184641)</td>
<td>8.60432 (0.0337424)</td>
<td>732K</td>
</tr>
<tr>
<td><b>screenthumbnail</b></td>
<td><b>method used</b></td>
<td><b>peak</b></td>
<td><b>average</b></td>
<td><b>standard deviation</b></td>
<td><b>filesize</b></td>
</tr>
<tr>
<td rowspan="10" style="vertical-align: top;"><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/2_1.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_2_1.jpg' height='40' alt='2_1' class='ngg-singlepic ngg-none' /></a></td>
</tr>
<tr>
<td>original</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>328K</td>
</tr>
<tr>
<td>blackmanresize</td>
<td>62 (0.243137)</td>
<td>1.10186 (0.00432103)</td>
<td>1.69206 (0.00663553)</td>
<td>496K</td>
</tr>
<tr>
<td>lanczosresize</td>
<td>63 (0.247059)</td>
<td>1.10822 (0.00434597)</td>
<td>1.68183 (0.0065954)</td>
<td>676K</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>62 (0.243137)</td>
<td>1.11478 (0.00437168)</td>
<td>1.67341 (0.00656238)</td>
<td>504K</td>
</tr>
<tr>
<td>spline16resize</td>
<td>62 (0.243137)</td>
<td>1.10619 (0.00433802)</td>
<td>1.73069 (0.00678702)</td>
<td>488K</td>
</tr>
<tr>
<td>spline36resize</td>
<td>62 (0.243137)</td>
<td>1.10259 (0.00432386)</td>
<td>1.69271 (0.00663806)</td>
<td>496K</td>
</tr>
<tr>
<td>spline64resize</td>
<td>63 (0.247059)</td>
<td>1.10177 (0.00432066)</td>
<td>1.68822 (0.00662046)</td>
<td>496K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36)</td>
<td>56 (0.219608)</td>
<td>1.08019 (0.00423605)</td>
<td>1.54706 (0.00606689)</td>
<td>524K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td>52 (0.203922)</td>
<td>1.07437 (0.00421321)</td>
<td>1.53682 (0.00602673)</td>
<td>524K</td>
</tr>
<tr>
<td><b>screenthumbnail</b></td>
<td><b>method used</b></td>
<td><b>peak</b></td>
<td><b>average</b></td>
<td><b>standard deviation</b></td>
<td><b>filesize</b></td>
</tr>
<tr>
<td rowspan="10" style="vertical-align: top;"><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/3_1.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_3_1.jpg' height='40' alt='3_1' class='ngg-singlepic ngg-none' /></a></td>
</tr>
<tr>
<td>original</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>648K</td>
</tr>
<tr>
<td>blackmanresize</td>
<td>131 (0.513725)</td>
<td>3.69918 (0.0145066)</td>
<td>6.33968 (0.0248615)</td>
<td>688K</td>
</tr>
<tr>
<td>lanczosresize</td>
<td>128 (0.501961)</td>
<td>3.70108 (0.014514)</td>
<td>6.31411 (0.0247612)</td>
<td>696K</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>127 (0.498039)</td>
<td>3.72408 (0.0146042)</td>
<td>6.30599 (0.0247294)</td>
<td>700K</td>
</tr>
<tr>
<td>spline16resize</td>
<td>132 (0.517647)</td>
<td>3.74263 (0.014677)</td>
<td>6.43383 (0.0252307)</td>
<td>684K</td>
</tr>
<tr>
<td>spline36resize</td>
<td>129 (0.505882)</td>
<td>3.7027 (0.0145204)</td>
<td>6.3419 (0.0248702)</td>
<td>688K</td>
</tr>
<tr>
<td>spline64resize</td>
<td>129 (0.505882)</td>
<td>3.70227 (0.0145187)</td>
<td>6.33526 (0.0248442)</td>
<td>688K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36)</td>
<td>127 (0.498039)</td>
<td>3.39755 (0.0133237)</td>
<td>5.79667 (0.022732)</td>
<td>736K</td>
</tr>
<tr>
<td>nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td>125 (0.490196)</td>
<td>3.39746 (0.0133234)</td>
<td>5.7985 (0.0227392)</td>
<td>740K</td>
</tr>
</table>
<p><a name="result">&nbsp;</a><br />
<em>Averaged #2</em></p>
<p>first average result + picture 1 result + picture 2 result + picture 3 result / 4</p>
<table cellspacing="5" cellpadding="3" border="0" class="video">
<tr>
<td><b>method</b></td>
<td><b>average peak</b></td>
<td><b>average mean</b></td>
<td><b>average standard deviatation</b></td>
</tr>
<tr>
<td>blackmanresize</td>
<td>113.58</td>
<td>2.95</td>
<td>4.94</td>
</tr>
<tr>
<td>lanczosresize</td>
<td>112.79</td>
<td>2.95</td>
<td>4.92</td>
</tr>
<tr>
<td>lanczos4resize</td>
<td>112.45</td>
<td>2.97</td>
<td>4.90</td>
</tr>
<tr>
<td class="lightred">spline16resize</td>
<td class="lightred">114.12</td>
<td class="lightred">2.98</td>
<td class="lightred">5.03</td>
</tr>
<tr>
<td>spline36resize</td>
<td>113.04</td>
<td>2.95</td>
<td>4.95</td>
</tr>
<tr>
<td>spline64resize</td>
<td>113.37</td>
<td>2.95</td>
<td>4.93</td>
</tr>
<tr>
<td class="lightgreen">nnedi3 (cshift=spline36)</td>
<td class="lightgreen">108.45</td>
<td class="lightgreen">2.75</td>
<td class="lightgreen">4.56</td>
</tr>
<tr>
<td class="lightgreen">nnedi3 (cshift=spline36, pscnr=4, etype=1)</td>
<td class="lightgreen">107.25</td>
<td class="lightgreen">2.75</td>
<td class="lightgreen">4.58</td>
</tr>
</table>
<p><a name="visual">&nbsp;</a><br />
<strong>visual results</strong><br />
At the top of this long article I already explained that visual results are very subjective; that is because things look differently on different screens (tft/crt/etc), also due to different brightness and similar settings. However, sometimes the visual difference is obvious. Here are some examples:</p>
<table cellspacing="5" cellpadding="3" border="0">
<tr>
<td>original<br /><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/original.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_original.jpg' alt='original' class='ngg-singlepic ngg-none' /></a></td>
<td>lanczos<br /><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/lanczos.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_lanczos.jpg' alt='lanczos' class='ngg-singlepic ngg-none' /></a></td>
</tr>
<tr>
<td>spline36<br /><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/spline36.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_spline36.jpg' alt='spline36' class='ngg-singlepic ngg-none' /></a></td>
<td>nnedi3<br /><a rel="lightbox[]" href='http://jeanbruenn.info/wp-content/gallery/video_upscale/nnedi_pscrn.jpg' title=''><img src='http://jeanbruenn.info/wp-content/gallery/video_upscale/thumbs/thumbs_nnedi_pscrn.jpg' alt='nnedi_pscrn' class='ngg-singlepic ngg-none' /></a></td>
</tr>
</table>
<p><a name="conclusion">&nbsp;</a><br />
<strong>Conclusion</strong><br />
What we can see, looking at the numbers, is that the higher the resolution of your source (or better, the more details the source has) the better upscaling works. If your source is too blurry, upscaling won&#8217;t work as good as it could. All scalers perform quite good (except for point and sinc, but that was to be expected). Spline16 performs worse than spline36 and spline64, for upscaling spline36 performs better than spline64. Lanczos and spline are quite similar the difference is very minimal, according to the numbers, lanczos performs better than spline; overall best resizer for upscaling is nnedi3. Another thing which you can see in the visual results above is that the nnedi3 image doesn&#8217;t have the stairs-effect.</p>
<p>If you have to decide which resizer (in avisynth) to use for upscaling, go this route:</p>
<pre>nnedi3 > lanczos/lanczos4 > spline36 > everything else</pre>
]]></content:encoded>
			<wfw:commentRss>http://jeanbruenn.info/2011/10/30/upscaling-in-avisynth-comparison-of-resizers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Stereo to (fake-)Surround</title>
		<link>http://jeanbruenn.info/2011/10/22/stereo-to-fake-surround/</link>
		<comments>http://jeanbruenn.info/2011/10/22/stereo-to-fake-surround/#comments</comments>
		<pubDate>Sat, 22 Oct 2011 18:48:56 +0000</pubDate>
		<dc:creator>Jean</dc:creator>
				<category><![CDATA[audio]]></category>

		<guid isPermaLink="false">http://jeanbruenn.info/?p=1077</guid>
		<description><![CDATA[Before I re-created my blog, I&#8217;ve written two articles about a pseudo-possibility for a stereo to surround conversation. I merged both and rewrote the article and hopefully this will help some people. Please note that I&#8217;m not an audio-engineer and that I might miss the needed background, this article is based on information I found [...]]]></description>
			<content:encoded><![CDATA[<p>Before I re-created my blog, I&#8217;ve written two articles about a pseudo-possibility for a stereo to surround conversation. I merged both and rewrote the article and hopefully this will help some people. Please note that I&#8217;m not an audio-engineer and that I might miss the needed background, this article is based on information I found in the world wide web, my personal taste and things I&#8217;ve noticed by research/trying. All sources I&#8217;ve used are linked at the bottom of this article.<br />
<span id="more-1077"></span><br />
<b>note</b>: this article is work in progress. I might change a few things. I re-added Jay&#8217;s comment because it contains useful information. Hope he&#8217;s fine with that <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>In a perfect world five dot one (5.1) would mean, that we&#8217;ll have sounds from behind (rear/surround speakers), sounds from the left and right (front left, front right speaker) vocals from the front (center speaker) and bass from the LFE channel (subwoofer). Notice that the “positional” estimation is important. So if we watch a movie, and someone is obviously speaking behind someone, we should hear that sound from the back (from the rear speakers). “Vocals” as in Speech should come from all directions, so if someone is talking on the left → the left speaker should output that. At least, that&#8217;s how I would (mis)-understand “Surround”.</p>
<p>As we aren&#8217;t in a perfect world, this is somewhat different. I checked the 6-channel sound files of a few dvds and the one of the openmovie sintel. The front left and right channels aren&#8217;t containing ANY vocals or they&#8217;re sounding like in a big hall, very quiet not easy to hear. First I thought it is related to the &#8220;haas&#8221;-effect, which says, what you hear first, tells you where the sound comes from. So if you hear something from front-left first (doesn&#8217;t matter whether vocal or not – might be some high tone) you&#8217;re thinking the vocals are coming from the left. I cannot tell if that is true. I found a small post in doom9 forums which might explain that behavior. http://forum.doom9.org/showthread.php?p=717044#post717044 ← that&#8217;s, why you&#8217;ll sometimes think there aren&#8217;t any vocals on the left and right channel. That&#8217;s because they&#8217;re just containing the difference as the center-channel contains the sum. </p>
<p>While trying around doing such upconversations it turned out (a few people on the net reported similar results) that it seems to be easier/better to do that conversation in steps, e.g.: stereo → quadrophonic → surround instead of stereo → surround. But: That might be personal taste.</p>
<p>Anyway. We have a stereo file, 48kHz, 16Bit. Due to it beeing stereo, we know it has 2 channels: left and right. We can create one additional channel out of them without much trouble. The center-channel. That channel is a mix of the left and the right channel with 50% volume of each:</p>
<pre>    sox -S -V -c 2 source.wav -c 1 combined.wav mixer 0.5,0.5
    normalize combined.wav</pre>
<p>That channel can be used now to create the new left and right channels. We&#8217;re inverting the specific channel, so that they&#8217;ll only contain the differences:</p>
<pre>    sox -S -V -c 2 stereo.wav -c 1 sleft.wav mixer -l
    sox -S -V -c 2 stereo.wav -c 1 sright.wav mixer -r
    sox -S -V -M -c 1 -v -1 sright.wav -c 1 center.wav -c 1 right.wav
    normalize right.wav
    sox -S -V -M -c 1 -v -1 sleft.wav -c 1 center.wav -c 1 left.wav
    normalize left.wav</pre>
<p>The “-v -1” causes an invert. The -M is used to merge both files (the inverted left / right and the center channel) that way, only the differences are left. Now we can over to our “surround” part. Let&#8217;s first talk about frequencies:</p>
<p>Most of the information I found about frequencies aren&#8217;t identical. While one says deep bass is between 20 and 60 Hz another says it&#8217;s between 20 and 40 Hz. Deep high tones between 3 and 12 kHz, another says between 2 and 3.5 kHz. Here, a simplified variant (which might not be correct)</p>
<ul>
<li><em>20 Hz &#8211; 20 kHz</em> human hear-able range (the older, the lower the max., likely you&#8217;ll hear up to a max. of 16 to 18 kHz)</li>
<li><em>80 Hz &#8211; 12 kHz</em> voice / speech (there are also pages telling it&#8217;s up to 8 kHz)</li>
<li><em>300 Hz &#8211; 3,4 kHz</em> voice / speech on analog phones</li>
<li><em>20 Hz &#8211; 200 Hz</em> bass</li>
<li><em>200 Hz &#8211; 2 kHz</em> middles</li>
<li><em>2 kHz &#8211; 12 kHz</em> high tones</li>
<li><em>12 kHz &#8211; 20 kHz</em> upper high tones</li>
</ul>
<p>20 Hz – 80 or 100 Hz bass which you can&#8217;t locate (so for this frequencies it shouldn&#8217;t matter, where the subwoofer is located)</p>
<p>You&#8217;ll see, that&#8217;s not as easy as one might think. However, let&#8217;s take a look at some speakers. Averaged and rounded results of a few speakers I took a look at:</p>
<ul>
<li><em>high tone speakers (7):</em> 2000 (2342) Hz – 20 kHz (21285)</li>
<li><em>middle tone speakers (5):</em> 400 (375) Hz – 13 kHz (12800)</li>
<li><em>deep/low tone speakers (30):</em> 40 (39) Hz – 6 kHz (5961)</li>
<li><em>subwoofer (9):</em> 40 (35) Hz – 200 Hz (232) ← the expensive ones I checked, range to 120 Hz and 150 Hz</li>
</ul>
<p>All these frequencies might help us with our surround audio file. For example: The real low frequencies are there for the subwoofer, we don&#8217;t need them on every speaker. To reduce the “load” of our other speakers, we&#8217;ll limit the frequencies. Then: The center-speaker should be optimized for our vocals. Thus it shouldn&#8217;t contain too high frequencies to not cause distortion there. We&#8217;ll need a frequency filter again. Our rear-speakers won&#8217;t benefit from high frequencies. So&#8230; With all the above kept in mind, my suggestion is:</p>
<ul>
<li><em>front left, right:</em> 80 Hz &#8211; 20 kHz</li>
<li><em>center:</em> 80 Hz &#8211; 12 kHz</li>
<li><em>surround left, right:</em> 100 Hz &#8211; 6 kHz</li>
<li><em>lfe:</em> 20 Hz &#8211; 200 Hz</li>
</ul>
<p>The next step would be to create the other channels and to add the frequency-limitations.</p>
<pre>    sox -S -V -c 1 left.wav -c 1 left-sr.wav sinc 100-6000 reverb
    sox -S -V -c 1 right.wav -c 1 right-sr.wav sinc 100-6000 reverb
    sox -S -V -c 1 combined.wav -c 1 center.wav sinc 80-12000
    sox -S -V -c 1 combined.wav -c 1 lfe.wav sinc 20-200
    sox -S -V -c 1 left.wav -c 1 left-fr.wav sinc 80-20000
    sox -S -V -c 1 right.wav -c 1 right-fr.wav sinc 80-20000</pre>
<p>Now we have all channels. Now we&#8217;ll just add a delay of 15ms to the rear speakers and we&#8217;ll put the whole stuff together. That&#8217;s all <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre>    multimux -d 0,0,15,15,0,0 \
     left-fr.wav right-fr.wav \
     left-sr.wav right-sr.wav \
     center.wav lfe.wav > final.wav</pre>
<p>As the Comment of Jay (thanks) states &#8211; The LFE Channel is not simply a subwoofer channel &#8211; Its for effects. So you might want to just remove the vocals instead of doing lowpass filtering and limiting the frequencies</p>
<p>Remember, our source has only 2 channels (left and right) &#8211; For 4 channel input or 6 channels input this whole document is not very helpful. I&#8217;m trying to make &#8220;surround&#8221; out of &#8220;stereo&#8221; &#8211; So i have to &#8220;guess&#8221; to &#8220;try&#8221; and to &#8220;hope&#8221; <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>the whole script to do the conversation</strong></p>
<pre>#!/bin/bash

###
# stereo 2 surround
###

inFile="$1";
outFile="$2";
debug="$3";

# todo ...
#if [ ! -z sox ]; then
#echo "sox"
#  run=0;
#fi

#if [ ! -x multimux ]; then
#echo "multimux"
#  run=0;
#fi

#if [ ! -x soxi ]; then
#echo "soxi"
#  run=0;
#fi

#if [ ! -x normalize ]; then
#echo "normalize"
#  run=0;
#fi

# default parameter
soxParm="";
normParm="-q";

# debug parameter
if [ $debug -eq 1 ]; then
  soxParm="-V -S";
  normParm="-v";
fi

if [ $run -eq 0 ]; then
  echo "Error: Requirenment missing: normalize multimux, sox or soxi";
else
  echo " Preparing Source";
  normalize $normParm $inFile;
  rate=$(soxi $inFile | grep "Sample Rate" | awk '{ print $4; }');
  # if rate is 44100, we'll most likely have stuff from an audio-cd,
  # which we want to deemph at least i assume so
  if [ $rate -eq 44100 ]; then
    echo " + Source is 44.1kHz, De-Emphasing &#038; Resampling...";
    sox $soxParm -c 2 $inFile source.wav deemph rate -v -a 48000
  else
    sox $soxParm -c 2 $inFile source.wav rate -v -a 48000
  fi
  # create combined channel
  sox $soxParm -c 2 source.wav -c 1 combined.wav mixer 0.5,0.5
  normalize $normParm combined.wav
  # create pre- left and right channels
  sox $soxParm -c 2 source.wav -c 1 sleft.wav mixer -l
  sox $soxParm -c 2 source.wav -c 1 sright.wav mixer -r
  sox $soxParm -M -c 1 -v -1 sright.wav -c 1 combined.wav -c 1 right.wav
  normalize $normParm right.wav
  sox $soxParm -M -c 1 -v -1 sleft.wav -c 1 combined.wav -c 1 left.wav
  normalize $normParm left.wav
  # frequency games
  sox $soxParm -c 1 left.wav -c 1 ls.wav sinc 100-6000 reverb
  sox $soxParm -c 1 right.wav -c 1 rs.wav sinc 100-6000 reverb
  sox $soxParm -c 1 combined.wav -c 1 c.wav sinc 80-12000
  sox $soxParm -c 1 combined.wav -c 1 lfe.wav sinc 20-200
  sox $soxParm -c 1 left.wav -c 1 lf.wav sinc 80-20000
  sox $soxParm -c 1 right.wav -c 1 rf.wav sinc 80-20000
  # normalize it in batch-mode
  normalize $normParm -b ls.wav rs.wav c.wav lfe.wav lf.wav rf.wav
  # let's mux it
  multimux -d 0,0,15,15,0,0 lf.wav rf.wav ls.wav rs.wav c.wav lfe.wav > $outFile
  # cleanup
  rm left.wav right.wav combined.wav source.wav sleft.wav sright.wav
fi</pre>
<p><strong>Hopefully useful links</strong><br />
You&#8217;re visiting those pages on your own risk. I took a look over them, but i can&#8217;t assure that those pages are &#8220;good&#8221;, &#8220;correct&#8221; or anything else.</p>
<ul style="list-style-type: none;">
<li style="list-style-type: none;"><img src="http://jeanbruenn.info/images/lang/lang_en.png" /> <a href="http://www.5dot1.com/articles/stereo_to_surround_sound.html">stereo to surround sound</a></li>
<li style="list-style-type: none;"><img src="http://jeanbruenn.info/images/lang/lang_en.png" /> <a href="http://forum.doom9.org/showthread.php?t=83752">Doom9: GUIDE LIST: Stereo-to-Surround Conversion Guides</a></li>
<li style="list-style-type: none;"><img src="http://jeanbruenn.info/images/lang/lang_en.png" /> <a href="http://en.wikipedia.org/wiki/Stereophonic_sound">Wikipedia: Stereophonic Sound</a></li>
<li style="list-style-type: none;"><img src="http://jeanbruenn.info/images/lang/lang_en.png" /> <a href="http://musichack.wordpress.com/gw-tutorials/center-channel-extractionisolation/">Musichack Tutorials: center channel extraction/isolation</a></li>
<li style="list-style-type: none;"><img src="http://jeanbruenn.info/images/lang/lang_en.png" /> <a href="http://www.sintel.org/">OpenMovie: Sintel</a> (I used their sound for testing)</li>
<li style="list-style-type: none;"><img src="http://jeanbruenn.info/images/lang/lang_de.png" /> <a href="http://de.wikipedia.org/wiki/Quadrophonie">Wikipedia: Quadrophonie</a></li>
<li style="list-style-type: none;"><img src="http://jeanbruenn.info/images/lang/lang_de.png" /> <a href="http://de.wikipedia.org/wiki/Mehrkanal-Tonsystem">Wikipedia: Mehrkanal-Tonsystem</a></li>
<li style="list-style-type: none;"><img src="http://jeanbruenn.info/images/lang/lang_en.png" /> <a href="http://www.howtogeek.com/61250/how-to-isolate-and-save-vocals-from-music-tracks-using-audacity/">How to isolate and save vocals from music tracks using audacity</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jeanbruenn.info/2011/10/22/stereo-to-fake-surround/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>mod_fcgid</title>
		<link>http://jeanbruenn.info/2011/10/19/mod_fcgid/</link>
		<comments>http://jeanbruenn.info/2011/10/19/mod_fcgid/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 12:51:27 +0000</pubDate>
		<dc:creator>Jean</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[the daily insanity]]></category>

		<guid isPermaLink="false">http://jeanbruenn.info/?p=1060</guid>
		<description><![CDATA[While fiddeling around with mod_fcgid it turned out I have no clue what the settings mean. And they aren&#8217;t very good described. Well maybe they are and I&#8217;m just not fit enough to get the correct definitions. So I asked Sven&#8230; The definition for fastcgi-server is unclear to me. Basically I understood it as &#8220;server-process&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>While fiddeling around with mod_fcgid it turned out I have no clue what the settings mean. And they aren&#8217;t very good described. Well maybe they are and I&#8217;m just not fit enough to get the correct definitions. So I asked Sven&#8230;</p>
<p><span id="more-1060"></span></p>
<p>The definition for fastcgi-server is unclear to me. Basically I understood it as &#8220;server-process&#8221; which is in my case a wrapper-script/php. Such a fastcgi server, can serve many requests and thus has child-processes.</p>
<p>Keeping this in mind and taking a look at <b>IdleTimeout</b> we&#8217;re talking about the time a fast-cgi-application was idle and so didn&#8217;t receive any request. The important part about this setting is, that starting a new fast-cgi-application takes more time. If a user visits your website and there is no fast-cgi-application running, he/she will have a little delay. Opening another page on your website will go fast. So, you&#8217;re dealing here between performance and resources. The earlier the process is terminated, the more resources you have available for other things. The later the process is terminated, the higher the chance to serve a user with no delay.</p>
<p>I&#8217;m not sure how to determine a good value for this setting. Probably taking a look at all logs and determining the average time between initial requests could be used. For example: If you&#8217;re receiving new requests all 10 minutes, a setting of 11 minutes might make more sense than a setting of 5 minutes. If you&#8217;re receiving new requests every minute an even shorter value _might_ make sense. The default value for IdleTimeout is 300 seconds, which means 5 minutes. It just depends a lot on the scenario. For example: A page with high traffic and lots of visitors might want to higher idletimeout and other timeouts to make sure that the server doesn&#8217;t have to start thousands of new fast-cgi-applications/processes <- that might be end up in extreme slow downs. In another scenario, on a vserver with limited resources where you get visitors every 30 minutes you might want to limit the timeouts to save resources. So, it really depends on your use-case.</p>
<p>Also, another note about this: It might make sense to set max_execution time in php to 0 and just use the IdleTimeout Feature of the fast-cgi-server. One might think that the fast-cgi-stuff uses the cli, and due to that max_execution time would be 0 per default, my tests have shown that this is not true (at least not with mod_fcgid, php 5.2 and ispcp). So - The max_execution time needs to be highered to match the IdleTimeout.</p>
<p>Now there's also <b>BusyTimeout</b> which is there to define how long a single-request can keep a fast-cgi-application busy. That&#8217;s by the way where my confusion starts. The documentation says it terminates the process. Which one? The child process or the server one? Of course it wouldn&#8217;t make much sense to terminate the whole fast-cgi-application because of a single-request (if that application has child processes or is able to handle many requests simultanously) &#8211; But how could I know? It&#8217;s not documentated. Let&#8217;s assume, this defines the maximum time a single-request (child process) can run. In this case, if your fast-cgi-application is PHP the same or a similar value to your php.ini&#8217;s max_execution time would make sense. Example: The default max_execution_time of PHP is 30 seconds. The default BusyTimeout of fcgid is 300 seconds. Thus a single-request is <b>always</b> finished or &#8220;over&#8221; after 30 seconds. Doesn&#8217;t make much sense to allow 300 seconds then &#8211; In this case 31 or 32 would be a good value. <b>BusyScanInterval</b> is similar. That setting scans processes every 120 seconds, while our PHP script is already finished after 30 seconds &#8211; It will never each BusyTimeout or BusyScanInterval.</p>
<p>Personally I think max_execution time of 30 seconds is not enough for a php-script, Sven&#8217;s opinion is different here: Uploading large files through PHP is inefficient (which is true) and then 30 seconds is of course enough for a normal website. Uploads should be handled by the webserver directly. A good value for Busy* should match the runtime of your fast-cgi-server, in case of php&#8217;s default value, 30 seconds. With a check every 14 seconds.</p>
<p>You could tune max_execution time by the way, by taking a look at your max upload size. Let&#8217;s assume that the average user of your website (who is allowed to upload) got a 3mbit/s connection:</p>
<pre>100 mbit/s = 11 MB/s (yeah ppl argue, might be 10, might be 12)
1 mbit/s = 11 / 100 = 0.11 MB/s
3 mbit/s = 0.33 MB/s</pre>
<p><strong>In 30 seconds</strong> you can upload 0.33*30 MB <strong>with a 3mbit/s</strong> connection. That&#8217;d be <strong>9.9 MB.</strong> Keeping this in mind, it might make no sense to define a max upload size of 100 MB &#8211; As your users can&#8217;t reach that within 30 seconds (except they&#8217;ve got a quite good connection). However, look at this calculation sceptical &#8211; It should just give an idea on how to tune your parameters.</p>
<p>And finally there&#8217;s <b>ProcessLifeTime</b> which is meant to terminate the whole fast-cgi-application regardless of whether it is busy or idle. This is a good thing to avoid having processes eating up all memory and similar things, because the application will be &#8220;refreshed&#8221; each x minutes. That means, ProcessLifeTime should be a multiple of IdleTimeout.</p>
<p>Apart from <b>BusyScanInterval</b> there&#8217;s also <b>IdleScanInterval</b>. Basically you can choose how frequently to &#8220;check&#8221; the specific process for, whether it is idle or busy. The more frequently you check, the more accurate the decission might be. Per default it&#8217;s about two checks. The checks should be smaller than the amount of their parent setting. For example: BusyTimeout of 30 and BusyScanInterval 60 makes no sense. Minimum value would be 29. If you want to check twice in it&#8217;s run-time you&#8217;d set 29/2 = 14 (rounded down) &#8211; The first check happens after 14 seconds, the second check happens after 28 seconds. So basically: (*TimeoutValue &#8211; 1) / AmountOfChecks = Interval</p>
<p>Then there is <b>ErrorScanInterval</b> and <b>ZombieScanInterval</b>. You can choose between scanning very frequently (might eat resources/slow things down) and terminating processes faster (which might free resources earlier and give faster-responses on errors). I think a good value is between 3 and 9 seconds.</p>
<p>One of the most interesting settings is <b>DefaultMinClassProcessCount</b> with a default value of 3. Which avoids the termination of idle-processes in some circumstances. It will kill only idle-processes if there are more than 3. Which is again confusing, are processes of a fast-cgi-application or all fast-cgi-applications of the webserver meant? However, I assume, that a fast-cgi-application handles many requests which turn into child-processes and that such childs are meant with &#8220;processes&#8221;. Right after tuning IdleTimeout it makes sense to set this to 0 to always enforce the use of IdleTimeout.</p>
<p>And then there&#8217;s the trouble-causing (or more precisely the trouble-solving) setting <b>PHP_Fix_Pathinfo_Enable</b>. Usually you should set this to 1 only, if you got ;cgi.fix_pathinfo=1 in your php.ini. As you can see at the ; it&#8217;s commented in mine. Still it seems to be in-use. If I don&#8217;t use PHP_Fix_Pathinfo_Enable 1&#8243; for mod_fcgid &#8211; Some Uploads are broken. Uploading a picture with more than 100kb results in 500 HTTP Errors which aren&#8217;t tracked by PHP or Apache Error log. Might be some PHP, Debian or mod_fcgid bug. I cannot track this issue down (Maybe I don&#8217;t want to investigate more time :p)</p>
<p>Finally there&#8217;s <b>MaxRequestsPerProcess</b>. Okay.. Errm. Probably I should just forget about server, childs, parents, processes, requests, and all this crap (In this case, I guess they mean, how many &#8220;requests&#8221; a single-fast-cgi-server can handle).</p>
<p>Another problematic part is <b>MaxRequestLen</b> which was set to 1 GB with earlier versions and which is set to 128kB. According to the documentation, &#8220;only&#8221; the header is meant &#8211; Not the message/content itself. However, I noticed errors with that low amount and so I&#8217;ve set MaxRequestLen to exactly the same value, people are allowed to upload in PHP. So if your max upload size in PHP is 10 MB, set MaxRequestLen to 10*1024*1024 (10 * 1024 * 1024) which would be 10485760 bytes.</p>
<p>There are a few other parameters which might be worth to look at, however &#8211; The above stuff is enough for me to tune.</p>
<p>A few further links. I&#8217;ve checked them and couldn&#8217;t find anything bad on those pages, however, I cannot give any guarantee for that &#8211; So click the links below on your own risk (you&#8217;re leaving this page by clicking such a link)</p>
<ul>
<li><a href="http://www.adploits.com/2011/06/13/vbulletin-php-fastcgi-large-attachment-upload-500-server-error-fix/">large attachement error (500)</a></li>
<li><a href="http://wiki.hot-chilli.net/Apache2_und_libapache2-mod-fcgid">some page with the default settings explained</a></li>
<li><a href="http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html">Apache mod_fcgid</a></li>
</ul>
<p>And thanks to Sven for helping a bit <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://jeanbruenn.info/2011/10/19/mod_fcgid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>urt video</title>
		<link>http://jeanbruenn.info/2011/10/15/urt-video/</link>
		<comments>http://jeanbruenn.info/2011/10/15/urt-video/#comments</comments>
		<pubDate>Sat, 15 Oct 2011 13:55:43 +0000</pubDate>
		<dc:creator>Jean</dc:creator>
				<category><![CDATA[the daily insanity]]></category>

		<guid isPermaLink="false">http://jeanbruenn.info/?p=1048</guid>
		<description><![CDATA[Just added a new video at youtube. Well new.. Thats a 4on1 I won ago a half year or something. I don&#8217;t remember Watch it in 720p.]]></description>
			<content:encoded><![CDATA[<p>Just added a new video at youtube. Well new.. Thats a 4on1 I won ago a half year or something. I don&#8217;t remember <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Watch it in 720p.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/Bc0BWRxCgKE" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://jeanbruenn.info/2011/10/15/urt-video/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>renamed modules</title>
		<link>http://jeanbruenn.info/2011/10/15/renamed-modules/</link>
		<comments>http://jeanbruenn.info/2011/10/15/renamed-modules/#comments</comments>
		<pubDate>Sat, 15 Oct 2011 10:12:28 +0000</pubDate>
		<dc:creator>Jean</dc:creator>
				<category><![CDATA[lunar linux]]></category>

		<guid isPermaLink="false">http://jeanbruenn.info/?p=1021</guid>
		<description><![CDATA[this article has moved to my dev blog]]></description>
			<content:encoded><![CDATA[<p><a href="http://wdp.blogs.lunar-linux.org/2011/10/15/handling-renamed-modules-an-idea/">this article has moved to my dev blog</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jeanbruenn.info/2011/10/15/renamed-modules/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>new layout</title>
		<link>http://jeanbruenn.info/2011/10/14/new-layout/</link>
		<comments>http://jeanbruenn.info/2011/10/14/new-layout/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 19:40:17 +0000</pubDate>
		<dc:creator>Jean</dc:creator>
				<category><![CDATA[the daily insanity]]></category>

		<guid isPermaLink="false">http://jeanbruenn.info/new/?p=931</guid>
		<description><![CDATA[well, I love minimalistic layouts. This one is somewhat similar to the google-plus layout. I just need a nice header. Some posts aren&#8217;t there anymore, coming back soon, I have to rewrite them a lot.]]></description>
			<content:encoded><![CDATA[<p>well, I love minimalistic layouts. This one is somewhat similar to the google-plus layout. I just need a nice header. Some posts aren&#8217;t there anymore, coming back soon, I have to rewrite them a lot.</p>
]]></content:encoded>
			<wfw:commentRss>http://jeanbruenn.info/2011/10/14/new-layout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Titel werden überbewertet. Heute mal ganz auf Deutsch :)</title>
		<link>http://jeanbruenn.info/2011/10/07/titel-werden-uberbewertet-heute-mal-ganz-auf-deutsch/</link>
		<comments>http://jeanbruenn.info/2011/10/07/titel-werden-uberbewertet-heute-mal-ganz-auf-deutsch/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 14:21:31 +0000</pubDate>
		<dc:creator>Jean</dc:creator>
				<category><![CDATA[the daily insanity]]></category>

		<guid isPermaLink="false">http://jeanbruenn.info/new/?p=918</guid>
		<description><![CDATA[Habe gerade die Bewertung von einigen Büchern überarbeitet. Mir sind ein paar Rechtschreibfehler aufgefallen &#8230; Heute auch Französisch Vokabel Test geschrieben, war aber eher einfach, ich hab&#8217;s mir schlimmer vorgestellt, nach 3 minuten abgegeben und mich die restlichen 7 Minuten gelangweilt. ^^ Hab auch zwei neue Bücher eingetragen, Rothammel&#8217;s Antennenbuch (super erklärt, leicht verständlich, aber [...]]]></description>
			<content:encoded><![CDATA[<p>Habe gerade die Bewertung von einigen Büchern überarbeitet. Mir sind ein paar Rechtschreibfehler aufgefallen &#8230; <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Heute auch Französisch Vokabel Test geschrieben, war aber eher einfach, ich hab&#8217;s mir schlimmer vorgestellt, nach 3 minuten abgegeben und mich die restlichen 7 Minuten gelangweilt. ^^</p>
<p>Hab auch zwei neue Bücher eingetragen, Rothammel&#8217;s Antennenbuch (super erklärt, leicht verständlich, aber ein Klopper&#8230;) und &#8220;Lehrbuch der Hochfrequenztechnik&#8221; von Otto Zinke (leider ein wenig komplizierter, ich muss mir da noch ein wenig die Grundlagen beibringen)</p>
<p>Ich glaub ich sollte mir mal eine Liste zusammenstellen mit Büchern die ich mir noch holen will und Bücher die mir empfohlen wurden&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://jeanbruenn.info/2011/10/07/titel-werden-uberbewertet-heute-mal-ganz-auf-deutsch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quality of Regexp</title>
		<link>http://jeanbruenn.info/2011/09/11/quality-of-regexp/</link>
		<comments>http://jeanbruenn.info/2011/09/11/quality-of-regexp/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 20:51:45 +0000</pubDate>
		<dc:creator>Jean</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://jeanbruenn.info/new/?p=857</guid>
		<description><![CDATA[In my last blog-entry you&#8217;ve seen that I compared regexp vs nonregexp-techniques and the result was, that there are &#8220;bad&#8221; and &#8220;good&#8221; regexp; while the good regexp are as fast as non-regexp-techniques. Let&#8217;s take a closer look at what &#8220;good&#8221; regexp are. Please notice that I&#8217;m not a regexp-magician so if you know about a [...]]]></description>
			<content:encoded><![CDATA[<p>In my last blog-entry you&#8217;ve seen that I compared regexp vs nonregexp-techniques and the result was, that there are &#8220;bad&#8221; and &#8220;good&#8221; regexp; while the good regexp are as fast as non-regexp-techniques. Let&#8217;s take a closer look at what &#8220;good&#8221; regexp are. Please notice that I&#8217;m not a regexp-magician so if you know about a regexp which would do better than the regexp I&#8217;ll show, please let me know.</p>
<p><a href="#result">Want to jump directly to the result and skip the boring php examples? <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </a><br />
<span id="more-857"></span></p>
<h2>detecting mime-encoded-words</h2>
<p>According to RFC (2047) a mime-encoded-word needs to fulfill these rules (I hope I haven&#8217;t forgotten or misinterpreted one):</p>
<p>A mime-encoded-word</p>
<ul>
<li>starts with =? and ends with ?=</li>
<li>consists of a maximum (=?&#8230;?=) of 75 characters</li>
<li>has four (4) question marks (=?..?..?..?=)</li>
<li>consists of charset, encoding and the encoded word (=?charset?encoding?encodedword?=)</li>
</ul>
<p>also:</p>
<ul>
<li>the charset can contain everything EXCEPT controls &#8221; ()<>@,;:/[]?.=&#8221;</li>
<li>the encoding can contain everything EXCEPT controls &#8221; ()<>@,;:/[]?.=&#8221;</li>
<li>the encoded-word can contain any printable ASCII character EXCEPT &#8221; ?&#8221;</li>
</ul>
<p>So&#8230; If we put that into an &#8220;exact&#8221; (php-)regexp, step by step, we&#8217;d start with:</p>
<pre>    $token = '[^ \(\)<>@,;:\/\[\]\?\.=]+';</pre>
<p>That would cover whitespaces and the special characters above. ascii-controls goes from 0 to 31 and 127 is also a control character. Printable characters are 32 to (including) 126. Doing this in regexp is (might) be somewhat more difficult, there are several ways to achieve what we want. For example p{Cc} might do what we want. [:cntrl:] also. [\x00-\x1F\x7F] this one of course also. I&#8217;m prefering the last one for this:</p>
<pre>    \x00-\x1F\x7F</pre>
<p>Putting that into our $token regexp would look like that:</p>
<pre>    $token = '[^ \(\)<>@,;:\/\[\]\?\.=\x00-\x1F\x7F]+';</pre>
<p>We&#8217;ll use $token for charset and encoding. Thus let&#8217;s take a look at &#8220;encoded-word&#8221;:</p>
<pre>    $encword = '[\x21-\x3E\x40-\x7E]+';</pre>
<p>You might wonder where i got x21 and x3E etc from and what they mean. <a href="http://en.wikipedia.org/wiki/ASCII#cite_note-35">I&#8217;d suggest you to read this link at wikipedia <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </a> Take a look at &#8220;Hex&#8221; in the tables. The &#8220;-&#8221; between \x21 and \x3E is used as &#8220;range&#8221; (from to).</p>
<p>Alright. Now let&#8217;s form our basic regexp. I&#8217;m using _ as delimiter:</p>
<pre>    $regexp = "_=\?$token\?$token\?$encword\?=_";</pre>
<p>without variables:</p>
<pre>    $regexp = '_=\?[^ \(\)<>@,;:\/\[\]\?\.=\x00-\x1F\x7F]+\?[^ \(\)<>@,;:\/\[\]\?\.=\x00-\x1F\x7F]+\?[\x21-\x3E\x40-\x7E]+\?=_';</pre>
<p>understood why I use variables to build the regexp? <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  However. The regexp isn&#8217;t finished yet. We need to make sure that it&#8217;s at maximum 75 chars long:</p>
<pre>    $regexp = "_(=\?$token\?$token\?$encword\?=){1,75}_";</pre>
<p>The above regexp is made to be used with preg_match_all. With preg_match in a foreach (prior splitting of the content by spaces) you&#8217;d add ^ at the beginning and $ at the end of the regexp.</p>
<p>However, let&#8217;s go back to my test. For my test I use the following regexp:</p>
<pre>
     // notice, this one is wrong!
     $regexA = '=\?[^ \(\)\<\>\@\,\;\:\/\[\]\?\.\=\x00-\x1F\x7F]+\?[^ \(\)\<\>\@\,\;\:\/\[\]\?\.\=\x00-\x1F\x7F]+\?[\x20-\x7E^ \?]+\?=';
     // notice, this one is not very accurate and uses subpattern ()
     $regexB = '=\?(.*)\?(.*)\?(.*)\?=';
     // notice, this one is not very accurate, _not_ using subpattern
     $regexC = '=\?.*\?.*\?.*\?=';
     // notice, needs modifier U and might not be very accurate
     $regexD = '=\?[[:ascii:]]+\?[[:ascii:]]+\?[[:ascii:]]+\?=';
     // this should be the correct and most accurate regexp
     $regexE = '=\?[^ \(\)<>@,;:\/\[\]\?\.=\x00-\x1F\x7F]+\?[^ \(\)<>@,;:\/\[\]\?\.=\x00-\x1F\x7F]+\?[\x21-\x3E\x40-\x7E]+\?=';
</pre>
<p>The string used for testing is:</p>
<pre>
     $test = 'From: =?US-ASCII?Q?Keith_Moore?= <moore@cs.utk.edu>
   To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld@dkuug.dk>
   CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>
   Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=
    =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=';
</pre>
<p>As you can see, we should get 5 results per regexp. My testscript:</p>
<pre>

	ob_implicit_flush();

	$input = 'From: =?US-ASCII?Q?Keith_Moore?= <moore@cs.utk.edu>
   To: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld@dkuug.dk>
   CC: =?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>
   Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=
    =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=';

     // notice, this one is wrong!
     $regexps[0] = '_=\?[^ \(\)\<\>\@\,\;\:\/\[\]\?\.\=\x00-\x1F\x7F]+\?[^ \(\)\<\>\@\,\;\:\/\[\]\?\.\=\x00-\x1F\x7F]+\?[\x20-\x7E^ \?]+\?=_';
     // notice, this one is not very accurate and uses subpattern ()
     $regexps[1] = '_=\?(.*)\?(.*)\?(.*)\?=_';
     // notice, this one is not very accurate, _not_ using subpattern
     $regexps[2] = '_=\?.*\?.*\?.*\?=_';
     // notice, needs modifier U and might not be very accurate
     $regexps[3] = '_=\?[[:ascii:]]+\?[[:ascii:]]+\?[[:ascii:]]+\?=_U';
     // this should be the correct and most accurate regexp
     $regexps[4] = '_=\?[^ \(\)<>@,;:\/\[\]\?\.=\x00-\x1F\x7F]+\?[^ \(\)<>@,;:\/\[\]\?\.=\x00-\x1F\x7F]+\?[\x21-\x3E\x40-\x7E]+\?=_';

	$i = 0;
	foreach($regexps as $regexp)
	{

		echo "Test: #$i\n";
		echo "Run:\n";
		$teststart[$i] = microtime(true);
		for($run = 0; $run < 100000; $run++)
		{
			echo $run;
			$runstart[$i] = microtime(true);
			preg_match_all($regexp, $input, $matches);
			$runcount[$i] = $runcount[$i] + sizeof($matches[0]);
			$runstop[$i] = microtime(true);
			$rundiff[$i] = $rundiff[$i] + ($runstop[$i] - $runstart[$i]);
		}
		$teststop[$i] = microtime(true);
		$testdiff[$i] = $teststop[$i] - $teststart[$i];
		$i++;

	}

	echo "testno, testduration, testcount, testmicrotime, testseconds\n";
	for($i = 0; $i < count($regexps); $i++)
	{
		$runmilliseconds = $rundiff[$i] / 1000;
		echo $i.' '.$testdiff[$i].' '.$runcount[$i].' '.$rundiff[$i].' '.$runmilliseconds."\n";
	}
</pre>
<p><a name="result"></a></p>
<h2>The Result?</h2>
<p>As to be expected 100 000 runs:</p>
<table cellspacing="5" cellpadding="2" border="0">
<tr>
<td><b>testno</b></td>
<td><b>test duration (microseconds)</b></td>
<td><b>test count</b></td>
<td><b>avg runtime (microseconds)</b></td>
<td><b>avg runtime (milliseconds)</b></td>
</tr>
<tr>
<td colspan="5">_=\?[^ \(\)\<\>\@\,\;\:\/\[\]\?\.\=\x00-\x1F\x7F]+\?[^ \(\)\<\>\@\,\;\:\/\[\]\?\.\=\x00-\x1F\x7F]+\?[\x20-\x7E^ \?]+\?=_</td>
</tr>
<tr>
<td>0</td>
<td>2.73657202721 µs</td>
<td>500000</td>
<td>1.63955712318 µs</td>
<td>0.00163955712318 ms</td>
</tr>
<tr>
<td colspan="5">_=\?(.*)\?(.*)\?(.*)\?=_</td>
</tr>
<tr>
<td>1</td>
<td>6.10814499855 µs</td>
<td>500000</td>
<td>5.00233960152 µs</td>
<td>0.00500233960152 ms</td>
</tr>
<tr>
<td colspan="5">_=\?.*\?.*\?.*\?=_</td>
</tr>
<tr>
<td>2</td>
<td>4.76775789261 µs</td>
<td>500000</td>
<td>3.66750049591 µs</td>
<td>0.00366750049591 ms</td>
</tr>
<tr>
<td colspan="5">_=\?[[:ascii:]]+\?[[:ascii:]]+\?[[:ascii:]]+\?=_U</td>
</tr>
<tr>
<td>3</td>
<td>2.82996702194 µs </td>
<td>500000</td>
<td>1.73454999924 µs</td>
<td>0.00173454999924 ms</td>
</tr>
<tr>
<td colspan="5">_=\?[^ \(\)<>@,;:\/\[\]\?\.=\x00-\x1F\x7F]+\?[^ \(\)<>@,;:\/\[\]\?\.=\x00-\x1F\x7F]+\?[\x21-\x3E\x40-\x7E]+\?=_</td>
</tr>
<tr>
<td>4</td>
<td>2.57315015793 µs</td>
<td>500000</td>
<td>1.4738881588 µs</td>
<td>0.0014738881588 ms</td>
</tr>
</table>
<p><b>Conclusion?</b></p>
<p>You can see, that all regexp matches (count of 500 000 - we have 100 000 runs and 5 matches - do the maths, luke!). You can also see, that the slowest regex uses (.*). The regex using .* is a bit faster, which shows that the slowness is not caused by the subpattern (). The last regex, is the fastest (and also the most accurate one) - interesting, isn't it?</p>
]]></content:encoded>
			<wfw:commentRss>http://jeanbruenn.info/2011/09/11/quality-of-regexp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Regexp vs Non-Regexp performance</title>
		<link>http://jeanbruenn.info/2011/09/10/regexp-vs-non-regexp-performance/</link>
		<comments>http://jeanbruenn.info/2011/09/10/regexp-vs-non-regexp-performance/#comments</comments>
		<pubDate>Sat, 10 Sep 2011 16:51:26 +0000</pubDate>
		<dc:creator>Jean</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://jeanbruenn.info/new/?p=829</guid>
		<description><![CDATA[Yesterday I was talking with Sven about my Imap-Class and I told him that I switched regexp to non-regexp to gain performance. He was asking me whether the use of str* is really faster than the use of regexp in PHP and thus he said &#8220;you could write an entry about that in your blog, [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I was talking with Sven about my Imap-Class and I told him that I switched regexp to non-regexp to gain performance. He was asking me whether the use of str* is really faster than the use of regexp in PHP and thus he said &#8220;you could write an entry about that in your blog, I&#8217;d be interested&#8221; &#8211; Hey Sven, here you go.</p>
<p><span id="more-829"></span></p>
<p>For my tests I used debian lenny&#8217;s PHP 5.2.6 (in debian squeeze) using CLI. All tests have been averaged (the first test-case 1000 runs, the second test-case 10 000 runs). If you want to skip the &#8220;how I did it&#8221; and just want to read my conclusion, <a href="#conclusion">click this link</a> <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><b>Notice</b>: The regexp used here for detecting mime-encoded-words is not 100% correct; if you&#8217;re looking for a correct variant, <a href="http://jeanbruenn.info/2011/09/11/quality-of-regexp/">take a look at my next article here.</a></p>
<h2>1st test-case (mime-encoded-words)</h2>
<p>For my test case I&#8217;m using mime-encoded-words &#8211; a few thousand of them:</p>
<pre>

	$mew = "";
	$word = "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?= =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?= =?US-ASCII?Q?Keith_Moore?=";
	for($i = 0; $i < 80000; $i++)
		$mew .= $word." ";
	$tw = trim($mew);
</pre>
<p>Now after generating that list, we can start our time-measurements using microtime();</p>
<pre>	$start = microtime(true); </pre>
<p>I'm processing that list in a foreach, by exploding our wordlist using a whitespace as delimiter:</p>
<pre>
	foreach($elements as $element)
	{
		if(
			(substr($element, 0, 2) == '=?') &#038;&#038;
			(substr($element, -2) == '?=') &#038;&#038;
			(substr_count($element, '?') == 4)
		){
			$reAcount++;
		}
	}
	$stop = microtime(true);
	$testcaseA = ($stop - $start)
</pre>
<p>within that foreach we'll need the str* stuff</p>
<pre>
		if(
			(substr($element, 0, 2) == '=?') &#038;&#038;
			(substr($element, -2) == '?=') &#038;&#038;
			(substr_count($element, '?') == 4)
		){
			$reAcount++;
		}
</pre>
<p>Let's calculate the time:</p>
<pre>
	$stop = microtime(true);
	$testcaseA = ($stop - $start);
</pre>
<p>Let's do the same with preg now. The content of the foreach:</p>
<pre>
		if(preg_match('/^=\?(.*)\?(.*)\?(.*)\?=$/is', $element))
		{
			$reBcount++;
		}
</pre>
<p>Someone might say, my regexp isn't very good and the use of (.*) is causing all this stuff.. Here you go:</p>
<pre>
	$token = '[^ \?]';
	$especials = '[^ \(\)\<\>\@\,\;\:\/\[\]\.\?\=]';
</pre>
<p>content of foreach:</p>
<pre>
		if(preg_match('/^=\?'.$token.'*\?'.$token.'*\?'.$especials.'*\?=$/is', $element))
		{
			$reDcount++;
		}
</pre>
<p>last but not least there's also preg_match_all. With it we can avoid the foreach:</p>
<pre>
	$start = microtime(true);
	preg_match_all('/=\?(.*)\?(.*)\?(.*)\?=/U', $tw, $matches);
	$reCcount = sizeof($matches[0]);
	$stop = microtime(true);
	$testcaseC = ($stop - $start);
</pre>
<p>The averaged result of 1000 test runs is:</p>
<table cellspacing="5" cellpadding="2" border="0">
<tr>
<td><b>Type</b></td>
<td><b>microseconds</b></td>
<td><b>milliseconds</b></td>
<td><b>Count</b></td>
</tr>
<tr>
<td>str*</td>
<td>0.131636329651</td>
<td>0.000132</td>
<td>75000</td>
</tr>
<tr>
<td>preg_match #1</td>
<td>0.530133208275</td>
<td>0.00053</td>
<td>75000</td>
</tr>
<tr>
<td>preg_match #2</td>
<td>0.172833989382</td>
<td>0.000173</td>
<td>75000</td>
</tr>
<tr>
<td>preg_match_all #1</td>
<td>0.420841172218</td>
<td>0.000421</td>
<td>75000</td>
</tr>
<tr>
<td>preg_match_all #2</td>
<td>0.144988677502</td>
<td>0.000145</td>
<td>75000</td>
</tr>
</table>
<p>preg_match #1 means (.*) was used<br />
preg_match #2 means [^ ...]* was used<br />
preg_match_all #1 and #2 as above.</p>
<p><b>Conclusion?</b></p>
<p>First of all, this test-case is not ideal; I'm using the same mime-encoded-words (3 different ones) and there's apart from the mime-encoded words nothing else in the string. This test-case is still useful tho, because you can see the similarities between the results. Interesting is for example that using [^ ..]* in the regexp is faster than using (.*) and using preg_match_all is as fast as str*. However: As you can see in the results, we're talking about microseconds, it's not like you would notice a difference between 0,0004 and 0,0018, would you? If we put it together: str* is slightly faster than a proper preg_match_all which is slightly faster than a proper preg_match - a general preg_match using (.*) is the slowest approach. I guess preg_match is slower than preg_match_all in this case, due to overhead from using foreach.</p>
<h2>2nd test-case (mime-encoded-words out of rfc 2047)</h2>
<p>My 2nd test-case parses the whole text of rfc 2047 - I just downloaded the .txt and wrote the following in the top of my php script:</p>
<pre>
	$mew = trim(str_replace(array('(', ')', '"', '\r\n', '\n', '\0', '\t'), '', implode('', file('rfc2047.txt'))));
	$tw = preg_replace('_\s+_', ' ', $mew);
</pre>
<p>So basically, I'm just removing a few characters, newlines, tabs ( I know unlikely that \0 and \t will be there.. ) and I converted many spaces to one space. Processing that with my previous script shows the following result:</p>
<table cellspacing="5" cellpadding="2" border="0">
<tr>
<td><b>Type</b></td>
<td><b>microseconds</b></td>
<td><b>milliseconds</b></td>
<td><b>Count</b></td>
</tr>
<tr>
<td>str*</td>
<td>0.00320203952789</td>
<td>0</td>
<td>22</td>
</tr>
<tr>
<td>preg_match #1</td>
<td>0.00531774499416</td>
<td>0</td>
<td>22</td>
</tr>
<tr>
<td>preg_match #2</td>
<td>0.00729660811424</td>
<td>0</td>
<td>22</td>
</tr>
<tr>
<td>preg_match_all #1</td>
<td>0.000311268949509</td>
<td>0</td>
<td>25</td>
</tr>
<tr>
<td>preg_match_all #2</td>
<td>0.000101275420189</td>
<td>0</td>
<td>22</td>
</tr>
</table>
<p><b>Conclusion?</b></p>
<p>Well. I'm a bit confused and impressed myself. Because I expected str* to be faster here. The opposite is the case. While doing this test I noticed inacurate behaviour of preg*, thus preg_match got 25 as count where it should get 22. I wasn't able to find out what's causing that; however: regexp might be inaccurate and shouldn't be generalized using (.*) if it's possible, avoid (.*). A proper regex and preg_match_all is faster here than str* still str* is faster than a regexp using (.*).</p>
<h2>3rd test-case (parsing a log-file / getting the date)</h2>
<p>For one of my projects I wrote a log-parser, the first version of it was using a lot of regexp and it was damn slow. I'm not sure whether this was due to the use of regexp (I rewrote the whole thing recently and switched from using preg* to non-regexp - Let's take a look. I'm using a real mail log file:</p>
<pre>wdp@lunar ~ $ du -h mail.txt
2.2M    mail.txt</pre>
<p>And the following regexp to get the date (1000 runs):</p>
<pre>preg_match('/^([A-Za-z]{3}) ([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}) (.*)$/', $logentry, $matches);</pre>
<p>For the non-regexp variant I'm using substr, str*, explode.</p>
<p>The result is:</p>
<table cellspacing="5" cellpadding="2" border="0">
<tr>
<td><b>type</b></td>
<td><b>parsed lines</b></td>
<td><b>skipped lines</b></td>
<td><b>microseconds</b></td>
<td><b>milliseconds</b></td>
</tr>
<tr>
<td>regexp</td>
<td>16180000</td>
<td>0.254695117474</td>
<td>0.000254695117474</td>
</tr>
<tr>
<td>non-regexp</td>
<td>16180000</td>
<td>0.267557286263</td>
<td>0.000267557286263</td>
</tr>
</table>
<p><b>Conclusion</b></p>
<p>again, not much difference between both variants, however in this case, regexp are faster.<br />
<a name="conclusion"></a></p>
<h1>Overall conclusion</h1>
<p>The performance of regexp depends on the regexp itself. I noticed that (.*) is slower than for example [^ \?]* or [A-Za-z0-9]. So the general rule should be: try to write your regexp as exact as possible. Generally regexp seems to be slightly slower than str* and similar things. In some scenarios regexp MIGHT be faster. The general rule "try to avoid regexp whenever possible" is wrong, tho. However: Using regexp you might make things worse (in some cases, they might be slower and they might be inaccurate) keeping that in mind, there's some sense in "try to avoid them" <img src='http://jeanbruenn.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://jeanbruenn.info/2011/09/10/regexp-vs-non-regexp-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

