12.31.2009

Windows 7: The Journey Continues

Ugh!! I hate to admit this, but I have recently converted my media center PC back to Windows. I have been running Mythbuntu for my media center PC for good portion of a year. I had previously run Windows with MediaPortal and GBPVR, and I had honestly never thought of running Windows Media Center. I am openly opposed to Windows and other closed source software, as well as the proprietary formats that come along with the closed source software.

Well after purchasing an Xbox360 earlier this year, I inadvertently set myself up for an easy transition to Windows Media Center. After getting fed up with how dated and kludgy the MythTV interface was (no offense to the MythTV team as they make a really solid product), I was looking at transition to XBMC. Something a little more modern and hip. Then I remembered that the Xbox360 can be used as a Media Center Extender (MCE), and so I started to dig into the idea a bit. I started discovering what was possible, e.g. recording/playback/music/etc. It had all the basic PVR software that I needed (along with free EPG, as I had previously been paying for it through SchedulesDirect).

After a long debate with myself, and looking at videos of the interface, I was ready to take the plunge. I ordered my copy of Windows 7 Home Premium (from NewEgg for like $100), and I ordered the Xbox 360 MCE Remote from Amazon for $20. Now it was just a waiting game. We had a huge snow storm hit the day I was expecting the packages, but unfortunately they didn't arrive until the Monday afterwards :( With this timing, I only had one day to setup the computer before I headed out on vacation.

So I did as much as I could in one day, but the system was lacking, and I wasn't sure how I felt about Windows Media Center. I already found myself missing the control/customization options of MythTV along with Linux. These features were not things that were readily visible to me in Windows Media Center, and I was feeling like a fish out of water. And to add insult to injury, I was having an issue with the Windows software not liking a hard drive that had worked fine for me under MythTV. It turns out linux can handle variances better in hardware than Windows (duh), and so I had to buy a new hard drive, and I am RMAing the non working one. So as I was leaving for vacation, I didn't have the greatest perspective on the Windows software setup, but I was still hopeful.

So, here comes today. I woke up at 4am (10am in Italy, which I had just come from) and the new hard drive had been delivered the day before, so I was raring to give it a second shot. I installed the new hardware (hard drive plus an extra 1gb of ram, as Windows 7 is more memory hungry than MythTV). I then proceeded to aim for feature parity with my MythTV system. The things on my checklist for today were:
  • Commercial Skipping
  • DivX file play back
  • Streaming media to PCs
  • Trailers and Movie Times
From previous forum searches, DivX playback on the Xbox 360 MCE looked to not be something Microsoft was interested in, but to my surprise, an updated was added, under the guise of 'supporting aac files', that added tons of codec support for the Xbox 360 MCE. Amazingly enough it supported all of my DivX and RMVB files (but not mp4, weird). Commercial Skipping had been a 5 hour battle with the realization that Windows 7 uses .wtv files for tv recordings, which apparently no one knows how to read. ShowAnalyzer by Dragon Global has a private beta that can handle .wtv somewhat (its progress atleast), and was actually able to attempt to analyze the shows (though it seemed a bit dodgy and missed more things than comskip did. But that probably means I need to configure it better). ShowAnalyzer, unlike comskip is not free, and requires a $30 for a license (which includes 1 year of updates).

Streaming between Vista and Windows 7 doesn't work so well (darn you MS), but I was able to share drives on my wife's computer to read the media. But another downer is that Windows Vista cannot read wtv files. Apparently only Windows 7 and Windows Vista Media Center can, which means I cannot share the tv recordings with my wife nor with my linux laptop. MythTV definitely had a better solution to this, but that is what you get for using open standards! So for the time being I am taking a loss on this one, but I will continue to press on.

Trailers and movie times I'm still in the mix for. I had a plugin for Windows Media Center that I thought would handle the trailers, but it hasn't panned out. The plugin seems to be pretty dodgy, and I am about to uninstall it for another.

So, all in all it has been a struggle, but a learning one. I haven't dealt to much with Windows software packages, and so it is good to get used to that world again, even if for a little. I will say I am pleased with Windows Media Center, but I know it is going to take as much tweaking as MythTV did to get it where I want it. Let's just hope that Windows allows for it ;-)

12.19.2009

Blogger Gadget: Syntax Highlighting

So I just spent the last hour battling Blogger. I recently updated my blog theme, and I quickly forgot that I had altered it to support syntax highlighting. And so I though to myself, why would I need to add the js/css files directly to the theme. Couldn't I just add it as a gadget (html/js) at the bottom of my page and not worry about it? Well the long answer is yes, but it was an arduous process. Blogger seems to do some Javascript parsing on it's side and caused me much heartache as I was trying to dynamically add the script/css tags (which is generally problematic on many large sites that take HTML input). So without further ado, if you just copy and paste the following code into a Blogger Html/JS gadget, (and have the syntax js/css files hosted on a server), you should be up and running in no time:

<script type="text/javascript">
(function() {
var open = '<', right = '>', sclose = '/'+'>', close='<'+'/';
var root = '~~~Your Web Location for your Syntax Highlighting js/css files ~~~';
var towrite = [];
var toAdd= [
'Core',
'BrushCpp', 'BrushCss', 'BrushDelphi',
'BrushJava', 'BrushJScript', 'BrushPhp',
'BrushPython', 'BrushRuby', 'BrushSql',
'BrushXml'];

function writeTag(t, attr, b) {
var out = ['<'+t], line, k;
for (k in attr) out.push(k+'="'+attr[k]+'"');
if (b == undefined) out.push(sclose);
else {
out.push(right,b,close+t+right);
}
towrite.push(out.join(' '));
}

function addScript(p) {
writeTag('script', {type : 'text/javascript', src : root+p+'.js'}, '');
}

function addCss(p) {
writeTag('link', {type : 'text/css', href : root+p+'.css', rel : 'stylesheet'});
}

for (var i=0; i < toAdd.length;i++) addScript('sh'+toAdd[i]);
addCss('SyntaxHighlighter');

window.onload = function() {
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
}

document.write(towrite.join('\n'));
})();
</script>


And now you can change themes without having to worry about losing your syntax highlighting changes. Enjoy!

12.06.2009

Dmenu and SDL

So recently I have been doing a lot of work in C with SDL. I am working on a project called dmenu (http://code.google.com/p/dmenu/) which is a UI for the Dingoo A320 running Dingux. One of my recent goals is to provide some enhanced visuals for the UI. This entails the goal of adding animations as well as adding things like shadow, opacity, etc. The ultimate goal is to increase usability and also to make the UI seem more professional.

One of the major roadblocks is the processor speed on the Dingoo A320. It's easy to devise algorithms on a Pentium Core Duo2 that just aren't feasible on the Dingoo's limited MIPS processor. During one of my courses in college, I had the pleasure of implementing a simple encryption algorithm in C. I spent a lot of time optimizing the crap out of that (including bit twiddling, gnu C directives, and the likes), and so I feel I know a moderate amount of how to optimize C code (not to mention algorithm optimization in general). Even with this in hand somethings just happened to be too slow.

For example, I implemented an image viewer that is used for viewing wallpapers in the system as well as theme previews (for selecting different themes). Because SDL does not include scaled blitting, I had to implement a scaling solution myself. To optimize I had to make some gross assumptions (that just happen to be true for the Dingoo) and it made the algorithm much faster than if it had been general.

/**
* Optimized for 16bit images. Will not work any any others
*/
SDL_Surface* shrink_surface(SDL_Surface *src, int width, int height)
{
if (!src) return NULL;

int h = src-<h, w = src->w;

if(width>w || height>h || h <=0 || w <= 0) return NULL;

float fpx = (w*1.0f)/(width*1.0f), fpy =(h*1.0f)/(height*1.0f);
int y,x;

SDL_Surface *dst = SDL_CreateRGBSurface(
src->flags, width, height, 16,
src->format->Rmask, src->format->Gmask,
src->format->Bmask, src->format->Amask);

register int src_pitch = src->pitch, dst_pitch = dst->pitch;
register int src_y_off = 0, dst_y_off = 0, dst_x_off=0;
Uint16 *src_pixels = (Uint16*)src->pixels, *dst_pixels = (Uint16*)dst->pixels;
int max_w = 2*width;

y = height;
while (y--) {

dst_y_off = dst_pitch*y;
src_y_off = src_pitch*(int)(y*fpy);
dst_x_off = max_w;

x= width;
while (x--) {
dst_x_off -= 2;
*(Uint16*)((int)dst_pixels + dst_y_off+dst_x_off) =
*(Uint16*)((int)src_pixels + src_y_off+(int)(x*fpx)*2);
}
}

return dst;
}


Unfortunately this process was too slow for a real time experience. Also the cost of pre-scaling all the images would have been too expensive in time and memory. So I ultimately had to rely upon disk caching to provide the ultimate user experience. This included scaling and exporting as a PNG to disk and using threads to accomplish this. This allowed the UI to return the image after it had scaled (if it wasn't already on disk). So it optimized for the general user experience but ensure the first time (on a cache miss) was not unbearable.

Another problem that I just had to tackle was that of alpha blending. SDL and alpha blending are not good friends. I've seen posts by many other people about their struggles with trying to alpha blend a surface that has per pixel alpha values (e.g. a PNG image ). It seems like SDL was designed with the mindset that the images used in the programs would be simple alpha channels (e.g. GIFs or images that rely upon colorkey alpha channels). It has stellar operations/performance when handling surfaces of this type, but it just falls apart when trying to do alpha filtering on a surface that has per pixel alpha values. So I took it upon myself to write an efficient algorithm that would allow me to blend alpha:

/**
* Alpha blends a 32bit Surface using per pixel alpha blending. It will
* take any given surface and scale each pixel's alpha value down
* by alpha. If alpha is a power of 2 it should scale much faster than any
* other values as it can use bitwise shifting instead of multiplication. The
* following alpha values are the special values.
* 255 -> Does nothing (alpha blending by 100% is just ignored)
* 127, 63, 31, 15, 7, 3, 1 -> Quick divide using bitwise shifting
* 0 -> no math, just clears out alpha channel
* Everything else -> alpha/255 * pixel alpha
*/
void alphaBlendSurface( SDL_Surface* s, int alpha )
{
if (alpha == 255) return;

Uint32 *pixels = (Uint32*)s->pixels, *p;

float alpha_ratio;
const register int pitch = s->pitch;
register int off = 0;
register int x = 0;
int max_off = s->h*pitch,
max_x= pitch,
msk = s->format->Amask,
alpha_step = 8;

#define map_pixel(op)\
while (off<max_off) {\
while (x<max_x) {\
p = (Uint32*)((int)pixels + x);\
*p = op; x+=4; }\
off += pitch;max_x = off+pitch;}

switch (alpha) {
case 127: --alpha_step;
case 63: --alpha_step;
case 31: --alpha_step;
case 15: --alpha_step;
case 7: --alpha_step;
case 3: --alpha_step;
case 1: --alpha_step;
map_pixel((*p & ~msk) | (*p>>alpha_step & msk));
break;
case 0:
map_pixel((*p & ~msk));
break;
default:
alpha_ratio = alpha/255.0f;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
map_pixel((*p & ~msk) | (int)((*p>>24) * alpha_ratio) << 24);
#else
map_pixel((*p & ~msk) | ((int)(*p * alpha_ratio) & 0xFF));
#endif
break;
}
#undef map_pixel
}


Again, this isn't anything special, but the reduced complexity of the algorithm (plus the smaller size of the components being addressed [screen subsections]) allows for this algorithm to run efficiently in real time. I might ultimately end up caching the results just as a trade off for time/memory, but I'm not sure if it is ultimately worth it. Anyways, its been a blast today working on C optimizations.

9.12.2009

Microserfs - Too real to be fiction?

So, I just recently finished reading a book called Microserfs by Douglas Coupland. The book was based in the time period of 1993 to 1995 and was written during the same time period. When I first started reading the book, I didn't realize it was almost 15 years in the past. The archetypes and the themes of the book resonated with my view of the world. I remember growing up in the world that he paints, and how he uniquely pinpoints my view of technology, and the role that it plays in my life.

Anyone who grew up in the 90s and grew up in technology will more than likely love this book as I know that I did.

8.29.2009

Levels of Software Development

So, I was out for a walk this morning, and realized (while I already knew this, I saw it more clearly this morning) that there are different levels of people in Software Development, in the same way there are different levels of people in the Armed Forces. In the Armed Forces, it isn't time in that matters, as much as rank. This seems to be a common misconception in the Software Industry that years of service implies rank. While it is true that there tends to be a positive correlation, causation is not a valid assumption.

In Software Development, you really have three types of people:
  • Engineers (Generals) - These tend to be the people that get the big picture. They understand the overall issues, but should have a good enough grasp of the fundamentals to be able to write the software. The defining characteristic of an Engineer is the ability to see the problem as a whole, derive a solution, and set a direction to accomplish.
  • Developers (Lieutenants) - These are people who understand the fundamentals of overall design well enough to overcome obstacles in the development process. They do not necessarily live in the big picture world that the Engineer does, but it does not mean that they are unaware of the larger world. The defining characteristic of a Developer is the ability to fill in the gaps of the overall design that the Engineer sets forth.
  • Programmers (Grunts) - These are the people who understand how to turn specifications into code. The same way a solider knows how to turn training and orders into an accomplished mission. These people are not known for their quick thinking or problem solving, but their ability to actually produce results.
I realize this may not be 100% accurate, but from my experience tends to be fairly representative of the world at large. I have worked with people who make the decisions, those who understand how to take those decisions and make software happen, and those who need a spec sheet before they can even begin to code. I have no disdain for any of these three types of people, as they are all necessary in their own place and time.

What I do have a disdain for, is the fact that Recruiters and Managers tend to view the world as one type of person, and so can hire a Programmer and Engineer to play the same role on a project. It would be akin to a Company saying: "We need to hire soldiers for or upcoming project", and then proceeding to recruit a General and a Foot Soldier for the same task. Its ridiculous in the sense of the Armed Forces, but why not for Software Development.

Some companies try to get past this by requiring X number of years of experience, or a degree in this or that. And that helps to an extent but again, causality is non existent. There really needs to be some distinction of the different types of Software Development folk out in the world, instead of lumping everyone together under one title. Until that point occurs, the world of hiring of Software Development teams is still a scary and messy place.

4.25.2009

My First Video Game

Hey, so this is a widgetized-version of my "first" video game. I have made many before, but this is the first that has ever really been fun and easy to use. So I hope you enjoy it as much as I have playing it.

9.20.2008

99 Bottles of Python

So, I don't know if you have ever been to 99 Bottles website,but it is a cool website that uses a single problem space to show off the strengths and individuality of each language. I spent some time this morning making my own version. I thought I would share it as I found it quite a fun project and allowed me to do some cool things.

#! /usr/bin/python

''' Tail-Recursive, Booleans and Strings,

The goal of the this script is to have python behave like LISP with respect to
recursion, lambda usage, and ouptut building. The other optimization, which is
a favorite of mine, is using boolean operations in lieu of formal control flow
operations. I would have rather had a ternary operator, but I can live with the
pythonic 'test and true-value or false-value'

It is a bit terse, but that is beauty of the lisp aspects of the code,
intersecting with boolean operations for strings.

Email: timothy.soehnlin@gmail.com

to run: sing()
'''

def sing():
t,w,b,n = "Take one down and pass it around","of beer on the wall","bottles","no more"
c = lambda a,s='.':'%s %s %s'%(str(a or n),b[:a==1 and -1 or None],w.split(s)[0])
s = lambda b=99: b and '%s, %s.\n%s, %s.\n\n%s'%(c(b),c(b," on"),t,c(b-1),s(b-1)) or ''
print s()

Quick break down of how the code works:


Standard function and variable definitions. Here I have all the variables I need for the program:


Setup

def sing():

t,w,b,n = "Take one down and pass it around","of beer on the wall","bottles","no more"


Printing bottle count and location

c = lambda a,s='.':'%s %s %s'%(str(a or n),b[:a==1 and -1 or None],w.split(s)[0])


Description

Here I am defining an anonymous function that is used for printing all permutations of 'N bottles of beer on the wall'.


Arguments

  • a: is the current number of bottles we are on
  • s(default is '.'): is the string to split "of beer on the wall" on.

Break down

  • str(a or n) : What this does right here is it takes the number (a) given if it is greater than 0 (because python equates 0 with False), and if it is 0, then it takes the variable n (which is "no more").
  • b[:a==1 and -1 or None] : What this line does is that when the number (a) is 1, we will drop off the last character in "bottles". If you pass None as b[:None], the array slice doesn't do anything and you get the whole "bottles".
  • w.split(s)[0] : What happens here is that w ("of bottles of beer on the wall") will get split on s, and only the first element in the split array will be taken. If s is in the string (like ' on') then we get everything before on, otherwise we get the whole string.

After all these values are calculated, they are interpolated into the string '%s %s %s', basically equivalent to : size + ' ' + bottle(s) + ' ' + description.


Singing the song

s = lambda b=99: b and '%s, %s.\n%s, %s.\n\n%s'%(c(b),c(b," on"),t,c(b-1),s(b-1)) or ''


Description

s is another anonymous function that is a recursive function, that will build the output of the song.


Arguments

  • b (default is 99) : Number of bottles of beer on the wall

Break down:

  • b and Print song, removed for effect or '': This basically says if b is greator than 0 then print song, else return an empty string. This also sets 0 as the limit in the recursion depth.
  • c(b) : Prints "n bottles of beer on the wall"
  • c(b, " on") : Prints "n bottles of beer" This is split on the " on"
  • t : The string "Take one down and pass it around"
  • c(b-1): Prints "n-1 bottles of beer on the wall"
  • s(b-1): Prints the next chorus


After all these values are calculated, they are interpolated into the string '%s, %s.\n%s, %s.\n\n%s' to add the proper line breaks, and punctuation.


Making it run

And print s() just prints the song


Well there you have it. The code break down. It is simple and yet amusingly elegant (or so I think.)

9.14.2008

Roll your own RSL (simple)

Okay, so the post before this contained a lot of information, but let me condense it down to a very small set of steps, and hopefully all will be clear:

1) Either get or build the library you want to use. Yahoo Maps SWC for instance or you can use the Flex SDK and compc utility to build your own SWC. Building your own SWC (using the compc command line tools), can look like this:

compc -compiler.external-library-path+=(a comma seperated list of SWCs that shouldn't be included in SWC output) -output output.swc -include-sources src/(path to sources)

2) Extract the library.swf from the SWC you want to use and give it a useful name. You can extract files from the SWC using any standard ZIP tool (WinZip, Windows archive tools, unzip/zip, etc). SWCs are just ZIPs containing an XML description of your library, and the SWF with the definitions. You will need both the SWF and the SWC.

3) Build your project that relies upon the library you have from step 1. When building your project, you want to reference the SWC for compilation checks, but also exclude any and all code in the SWC from being included in your SWF output. This could look something like this:

mxmlc -output main.swf -compiler.external-library-path+=(list of SWCs to exclude code from in your output SWF) src/Main.as

Note: What you have now is a SWF based on Main.as, that has all references to any code in your SWC (library) excluded from the SWF. This means that if you try to run your SWF now, you will get a VerifyError, stating that there is no definition for the classes your are trying to reference.


4) The final step in this process is loading of your library SWF (the one extracted from the SWC) at runtime. This step can be a little tricky. What needs to happen is that the library SWF needs to be loaded into your current ApplicationDomain (ApplicationDomain.currentDomain), before you make a single reference to any code in your SWC. This includes static references or using any of the classes as a super class for your code. The Flash VM will not try to import the code (it is very lazy) until it is referenced for the first time. We take advantage of this by loading all the class definitions to the current ApplicationDomain, and so when ever we go to reference a class for the first time, it exists, and we have just dynamically loaded code that we also statically compiled against. An example of loading your library could be as follows:

var req:URLRequest = new URLRequest('library.swf');
var loader:Loader = new Loader();
//Load url with current application domain and security domain
loader.load(req, new LoaderContext(true,
ApplicationDomain.currentDomain, SecurityDomain.currentDomain));

The above code will then inject the swf class definitions into your current class resolution scope (ApplicationDomain) and all your imports will be happy.

Summary) The code in my previous post, facillitates all this work into a simple process that takes most of the work out, but for anyone who has already been building their own SWCs for a while and also using RSLs this isn't that big of a step. I hope this clarifies from below, and encourages smaller downloads in everyone's Flash applications.

8.31.2008

The Path Not Taken (Facebook remix)

Do you ever sit back and wonder: What if I had just chosen another path for my life? I don't tend to do this, though I view myself as someone who is very introspective (but not normally retrospective). I tend to, normally, get pretty focused on life, and not take time to review the past, or the course my life has taken over the years. Then comes Facebook.

Facebook is a pretty cool social networking site and its feature set fairly comparable with others out there, but in the US it has the privilege of being fairly popular especially with people of my age. This popularity lends itself to allowing me the pleasure to examine paths not taken at a moment's notice. I just spent the last couple of hours reliving experiences from my past and viewing the paths others lives have taken. These are people I used to consider very close friends and whose lives were very closely knit with my own.

This past connection is what makes me think, what if my life had grown in a different path, followed a different way? One of my biggest regrets in life, thus far, is that I tend to not place so much emphasis on people that are far enough away from me. My view and attention is so focused, that I sometimes forget to even handle things that are necessary in my immediate life. I have made many good friends over the years, and yet I have let even more of these friends pass out of my life. It pains me to realize the friendships lost, but I also realize that my life is progressing in spite of that as well.

It is this dichotomy, the way in which I let so many friendships fall away, and of the same people who manage to make friendships last decades, and who seem to enjoy life so much through these friendships. I see a difference in their lives and mine, and I wonder: How would my life be different, if I were to spend much more of my time building and maintaining friendships? But I fear I cannot answer that question. My time, at this point in my life, is focused on a few things, but these things consume so much of my time, that I cannot bring myself to divert my attention any more than it already is.

So I realize, that I have made the hard decision to forgo the luxury of normal social patterns, and a life full of paths not taken, and replaced it with a life of meaning. I was watching Heroes the other day, and a quote from the movie struck me: "There comes a time when a man has to ask himself whether he wants a life of happiness or a life of meaning. [They are] [t]wo very different paths. To be truly happy, a man must live absolutely in the present, no thought of what's gone before and no thought of what lies ahead. But a life with meaning, a man is condemned to wallow in the past and obsess about the future."

I do not fully agree with this quote, in the sense that I believe a life of happiness and meaning is possible simultaneously, but that in pursuing a life of meaning, many things that people consider fundamental to happiness get replaced with different goals, and purposes. In this way, I feel that I have lost the chance to follow many of the paths in my life that I once had access to, but in doing so have opened the way to a life of meaning. In the same manner that in marrying my wife, I have closed paths to many other women, in doing so I have gained so much meaning in my life that it is astounding.

Meaning comes at the cost of choosing a path and sticking with it. This is what meaning is. It is setting a direction for your life, and actively following it. In doing so you create for yourself paths not taken, and paths that will never be, and it is these "sacrifices" that give meaning to your path. Do I truly lament over the paths that I have not taken? No, for I know the meaning in my life is so much greater, but at times I do envy those who have not chosen a path yet, whose life is still so open and free (and incidentally not reached its full meaning yet) as the endless possibilities are amazing. But in this retrospective, I realize that the meaning my life has, and the value of my choices are so profound that if given the chance to make the decisions again, I would do the same.

At times I feel like Peter Parker, in while he chose a life of meaning, as well, made for himself many paths that will never be taken, but in the same sense will do so much for the world that the cost is almost laughable.

8.12.2008

Flash 9 VM

ActionScript 3 is a pretty cool development environment. Looking back on the plethora of languages and environments that people try to use for teaching new languages (python, java, etc), ActionScript 3, and the Flash VM have the potential for being the next basic. The Flash VM is a cross platform runtime that is free to compile for and run on. ActionScript 3 shares a lot in common with python and javscript which facilliates the sharing of code between languages. The built in functionality (specifically networking, graphics, and media) is quite useful for building simple powerful applications. This again is something that was most captivating and drawing of basic.

Also to note the documentation for the ActionScript 3 is amazingly helpful, and the support forums around the net are strong.