Surprisingly, in the fifteen or so years I've been on the intertubes (remember FidoNet?!), I haven't ever been a subscriber of a DSL based ISP until recently. The progression of ISP tech has been roughly - Dial UP, LAN, Cable, LAN, Cable, MOTOwi4, Cable, DSL. Because of this I was fairly excited about getting the DSL connection. The first thing I did was to try out all the different DMT modulation settings and find the most reliable one and the one with the highest throughput. ITU G.992.5 satisfied both of those criteria.

As I was reading up on G.992.1 it seemed like it should win over G.992.5 on reliability as it can sustain a higher line rate over correspondingly high line attenuation. Ofcource, this kind of petty evidence isn't enough so I sampled the DSL noise margin for both modulations over the course of a day each amounting to roughly two thousand samples. Here is the graph for 992.1 followed by 992.5.

GMT NM Graph
Arithmetic Mean : ~12.823
Standard Deviation: ~0.068


ADSL2+ NM Graph
Arithmetic Mean : ~23.45
Standard Deviation: ~1.0733

We now have some empirical evidence to guide us. Looking at the graphs, 992.1 does seem much more stable as compared to 992.5. However, as a general rule, a higher noise margin is always preferable to a more stable one (Yeah, I just made that up right now). Now, on the actual values of the noise margin, this is what the wikipedia hive-mind has to say.

Noise Margin Range Effect
6dB or below is bad and will experience no sync or intermittent sync problems
7db - 10dB is fair but does not leave much room for variancies in conditions
11dB - 20dB is good with no synch problems
20dB - 28dB is excellent
29dB or above is outstanding

Now, ofcource there are tons of other factors that are possibly affecting my connection, namely line attenuation between my modem and the DSLAM, DSL Occupancy, and a bunch of other stuff I have no clue about. However, given that I have fewer connection issues with ADSL2+, I'm going to go with that for now. What a terribly unscientific way to make a decision ! :)
..............
A while back, I consciously decided to reduce or stop all forms of instant messaging on the interwebs. It wasn't that I was getting interrupted every other minute, but more that I hated having to perform expensive context switches from whatever I was doing to responding to messages. The way I look at it, if you're online you either respond to messages within some time-upper-limit or just stay offline. Ofcource there were other options like blocking a few people, or logging-on in 'invisible mode', etc, but they didn't feel right.

This itself wasn't much of an issue, but I was using my IM client to get mail notifications so I needed to find a reasonable alternative for that. Being a programming nerd, I wrote a minimal imap client in python that would connect with gmail and throw up a little popup informing me of unread messages. I set it to execute every 4 hours. This combined with wincal.exe that I was using for event notifications worked fine until recently when I moved up to Win7 and realized that the wincal client app was replaced with some stupid windows live calendar bullshit. (Yes, you can copy the old binaries from Vista and get wincal working, but there are some other problems)

So, I decided to give google calendar a try, and use their client to get notifications on events. As it happens google's client on startup registers Win + <KEY> hotkeys with User32!RegisterHotKey that I was using elsewhere. Also, in classic Google (and Apple?) fashion they remove all forms of control from the user and leave them no way to get rid of the annoyances. I know few people give a shit about it, but even Microsofts own "Guidelines for Keyboard User Interface Design" specify that Win + <KEY> shortcuts are reserved for operating system use. Heck, Raymond Chen even wrote up an entire article about not using the WIN key as the base key for your apps hotkeys. I'm sure some of Microsoft's own apps also fantastically violate those rules, so I suppose it just seems pointless to people observing externally, the value in that guideline.

One could argue that nothing is going to stop a determined nerd, but time afterall isn't free. I could have easily patched the executable and removed the offending call, but it just seemed annoying that I'd have to keep doing that for every update of the app. Alternatively, I could possibly also stick a patched copy of USER32.DLL in the local directory but both these solutions just seemed like A Bad Idea™. A while back Microsoft research had released a cool library called Detours that I knew could be put to good use here. All I would have to do is attach a Detour to RegisterHotKey and UnRegisterHotKey and route it to my own stub functions and I'd be all set. This was the extent of all the code I had to write:

#include <windows.h>
#include <detours.h>


static BOOL (WINAPI *ActualRegisterHotKey) (HWND,int,UINT,UINT) = RegisterHotKey;
static BOOL (WINAPI *ActualUnregisterHotKey) (HWND,int) = UnregisterHotKey;

BOOL WINAPI FakeRegisterHotKey(HWND a, int b, UINT c, UINT d)
{
    return TRUE;
}

BOOL WINAPI FakeUnregisterHotKey(HWND a, int b)
{
    return TRUE;
}

BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID reserved)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)ActualRegisterHotKey, FakeRegisterHotKey);
        DetourAttach(&(PVOID&)ActualUnregisterHotKey, FakeUnregisterHotKey);
        DetourTransactionCommit();
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID&)ActualRegisterHotKey, FakeRegisterHotKey);
        DetourDetach(&(PVOID&)ActualUnregisterHotKey, FakeUnregisterHotKey);
        DetourTransactionCommit();
    }
    return TRUE;
}

I'm not sure how Detours works but one other way that I know of to hook functions is to modify the executable's import table and rewrite the jump to the actual function to an address of your own. Ofcource there are other subtleties to it, and interested readers can google for "BugSlayer0298.exe" and look up the ancient column by John Robbins.

Anyway, Detours seems to have worked just fine here. I created a tiny dll with my stub function and used the 'withdll' sample from the detours library to help me get it up and running for the google talk executable. Unfortunately as I usually do, I can't really post my complete solution here as detours ships with a restrictive license. You could download the express version for personal use though. If you're a programmer this is fairly trivial to get working else shoot me an email if you can't for some reason.
..............
This is a little trick that I came across a few years ago. As the title suggests it provides for a quick-and-dirty way to fake fluid simulation or more specifically, faking the interface of a fluid as it reacts to various disturbances on its surface level. Its low computational overhead and trivial implementation, make for a very interesting algorithm.

The core algorithm, is just a few lines of code.

for_all i,j from 0,0 to MAX_I,MAX_J
	V(i,j) += (U(i-1,j) + U(i+1,j) + U(i,j-1) + U(i,j+1))/4 - U(i,j)
	V(i,j) *= dampingFactor
for_all i,j from 0,0 to MAX_I,MAX_J
	U(i,j) += V(i,j)

The fluid surface is approximated as a height map and is represented by the height-function U(x,y,t) which gives us the height of the wave at time t and position x,y. Also, V(x,y,t) represents the wave velocity at position x,y and time t. We don't really need to use a 3d array, as the updates can be done in situ without storing copies of the values at other time intervals.

One other important thing to mention is the boundary conditions. For the waves to be able to reflect off the boundary rectangle - (0,0,MAX_I,MAXJ), the following conditions are employed:

U(-1,j) = U(0,j)
U(i,-1) = U(i, 0)
U(MAX_I,j) = U(MAX_I-1,j)
U(i,MAX_J) = U(i, MAX_J-1)

I don't really have any information on who developed this algorithm or where it originated, but looking at the algorithm, it intuitively suggests that the water level (and velocity popogation) at any particular point on the surface varies with the variations of the water level at surrounding points. It seems to be a form of 2D discretization of the standard wave equation ∂2u/∂t2 = c22u

Download:


FFS-1.0.0.tar.bz2 - Source + Makefile
fakeFluid.exe - Pre-built binary (Hit space to add disturbance)
..............