May 30, 2013

The setup

Over the past couple of years I have had the fortune to pick up some great habits from great people. It is time to share an updated setup. These are the things my work-life currently depends on.

  • Python

  • Life environment: OSX, iMac, MacBook Pro, and recently back to iPhone.

  • Dev environment: VirtualBox. I still like free, and VBox works just fine.

  • Dev OS: Ubuntu Server. No more esoteric nonsense like Arch. The skinnier Server Edition is preferred as I need very little graphics capability from my Linux. Cannot stand Linux GUIs.

    Now, how it all works together:

    • Linux runs the code and manages packages. All the dev stuff stays there. Linux runs in headless mode.
    • OSX runs the editor (Sublime Text), terminal (iTerm), browsers, etc. and keeps my senses happy with beautiful fonts.
  • sshfs: the sanest way I know to share files between host and guest OSes. I keep a virtual directory mounted locally on OSX and point the editor there.

  • X11: always ready when I do need to bring up a GUI tool over a tunnel (I always ssh -X into my virtual machine), which are:

  • git gui, gitk: if they are not part of your git-fu already, you are missing out
  • tig: very useful for a quick history browse
  • IPython+Notebook: I often run my code as I'm testing it, and IPython is the way to interact with the interpreter. As the experiment grows or whenever working with data plots, firing up Notebook is worth the hassle.
  • nose+mock: I finally learned to stop worrying and love the tests. Yes, tests are always worth having.
  • Sublime Text: this probably deserves a separate post. In short, breaking away from the IDE land has been a happy change.
  • pianobar

May 21, 2013

Support your local caching

Suppose you had an expensive function xyz() whose output does not change often. Caching sounds appropriate. You may be inclined to memoize the function at the source, maybe by adding a decorator.

def xyz(a, b):

result = xyz('foo', 'bar')

You have just added behavior on which downstream users are likely to end up depending; and imposed a design decision on them. This is fine in most cases.

But perhaps not all users need xyz() cached. Perhaps the results are only good for some time but only the user knows exactly how long. Perhaps the caching behavior will depend on factors you do not even know ahead of time. Now you have a problem: making a simple decision that works for everyone is not trivial any more.

To avoid a contrived dependency configuration, consider caching at the usage point — the function call itself — and use it where you need it.

Stamped = namedtuple('Stamped', 'stamp obj')
cache = {}

def cached(ttl, func, *args, **kw):
    'Simple inline cache for function calls'

    key = (func.__name__,) + args
    entry = cache.get(key, None)
    now = time.time()

    if not entry or (now - entry.stamp) > ttl:
        result = func(*args, **kw)
        entry = cache.setdefault(key, Stamped(now, result))
    return entry.obj

Then the calling code might become:

# ttl is the number of seconds until a cached value expires
ttl = 60 * some_number_of_minutes_only_i_know

result = cached(ttl, xyz, 'foo', 'bar')

Now your caching can be as dynamic as needed, the other users need not know the details and the library function can stay simple. The caching behavior stays with the rest of the user logic.

We use a function name and argument tuple as a key for illustration purposes. You may need to index your functions differently — and again, with minimal local inline caching you can be maximally lazy about it.

Nov 03, 2010

OS X system-wide EQ with Soundflower and AU Lab

Entirely free. Requires XCode.

  1. Download and install Soundflower.

  2. Open Audio MIDI Setup.

  3. Create Aggregate Device (Audio -> Open aggregate device editor), constisting of:

    1. Built-in output (or whatever output you need)
    2. Soundflower
  4. Set default output to Soundflower.

  5. Start audio. At this point you should hear nothing.

  6. Open AU Lab (/Developer/Applications/Audio/AU

  7. Add 1 stereo input track, set Audio Device to "Aggregate device". Click "Done".

  8. Now you should hear sound and see level meters move.

  9. In either Audio 1 or Output 1 strip, click Effects drop-down and select Apple Graphic EQ, or whatever else you want!


Aug 27, 2010

Setting up LDAP for the first time

The most humane walkthrough found so far:

Aug 12, 2010

Don't mix Eclipse and Linux package management

It is best to install Eclipse standalone and use its own software update/install mechanism, rather than rely on system package management (pacman, in this case). This avoids all sorts of permission and plugin conflicts.

Mar 05, 2010

Eclipse plugins fail after installation (on Archlinux)

After installing Atlassian Connector in Eclipse and everything just goes to shit: all installed plugins disappear from preferences. The problem, as it turns out, lies in installing Eclipse as root (sudo pacman -S) and later installing plugins while Eclipse is running as non-root.

So, the right thing to do is either:

  • run Eclipse as root when installing packages; or
  • chown /usr/share/eclipse to the appropriate user.

Feb 21, 2010

Mastering an off-the-air recording (in Logic)

Preface: A few months ago I found an amazing device I should have found years ago — the amazing Zoom H2. Appropriately dubbed "a studio on a stick", it can produce amazing sounding location recordings. In the right hands, of course.


By "mastering" such a recording I mean simply making it listenable and enjoyable. The process is different from a conventional mix. On one hand, the material is taken care of and, if you're lucky enough to be listening to great musicians, already sounds very good. On the other hand, the only things you can really control is the mic position and your input gain level. Your task in post production, therefore, becomes correcting the things you could not change earlier.


This is a big one. During a performance levels can fluctuate wildly between sets, individual songs, solo sections, etc.. This works great when you are part of the setting, but listening to such a recording would be rather difficult, especially in less than ideal environment such as a car. You would have to keep adjusting the volume to hear the quiet parts over the noise and to keep the loud parts from blasting your ears.

We can avoid that by preemptively doing it for the listener: with volume automation curves and compressors. But take care not to destroy the dynamics entirely — the level changes must be subtle enough to keep the quiet parts perceptibly quiet and loud parts loud. Just enough to make the whole thing intelligible at a moderate and constant level.

To throw in a video analogy, there are webcams that show a static frame with a person moving about and then there are some webcams that constantly follow your face and fill the screen with it. You have to play the camera operator, zooming in and out when appropriate to produce a smooth and transparent viewing experience that does not get in the way of the story.

My processing chain

1. Levels

There is a gain plugin set to +6.8dB to bring the recording into a more useable range. The rest is just volume automation, some of it done riding a fader, but mostly just mouse drawing. I briefly toyed with a compressor but could not get it to sound right to my ears.

2. LinPhaseEq

The order of EQ and compression still puzzles me, but this placement is logical: it is there to correct the room/mic response. Where I was sitting it picked up hardly any bass and there was a pronounced honk around 400Hz. Also, I was very close to the drummer and the cymbals are just way too overpowering most of the time, so everything above 2.7kHz comes down about 5dB to keep them under control.

3. MultiPressor

Tricky to operate and very easy to make a total mess of your sound. I started off with a "Slow Attack 4-Band" preset and played with it to add some punch below 40Hz and to control the cymbals a bit more.

4. AdLimiter

Two of them, sharing the gain increase. They seem to adapt better this way.

Docutils System Messages

System Message: ERROR/3 (/home/dev/work.shared/unthingable/content/mastering-an-off-the-air-recording-in-logic.rst, line 14); backlink

Unknown target name: "|image0|".

Feb 10, 2010

G&L wiring and SC mod question

G&L L-series basses are Leo Fender's last creation. They are great. They feature two humbucking pickups and three configuration selector switches:

  • Pickup selector: neck/both/bridge
  • Series/parallel switch
  • Preamp: passive/active/active with treble boost

Original wiring: Notice the 0.1 uF caps on the pickups in series — those are "bass boost" caps present in the early L-2*00 models. Later they were removed, which is a shame, they sounded great.

Not only they are beasts in their stock configuration, they are quite mod-friendly. A popular mod adds a single coil option. Here is a variation:

#7 is what I'll probably do, with added DPDT push-pull switches. But there is one thing I don't get. Notice that the caps are present and how the neck cap is grounded, but the bridge cap connects to the bridge output. Why is that?

Feb 09, 2010

Blank Java windows in Awesome

After updating to GWT 2.0.1 (official) and moving our project to a arch/vbox, I had a small adventure trying to get DevMode window to come up: it just wouldn't. The window just came up blank and nothing else happened.

It turns out you are running awesome, Java may not play nice. You need this:

And remember to export GDK_NATIVE_WINDOWS=true to make all your Eclipse buttons work correctly.

Thanks to selckin on ##gwt for wmname suggestion.

Feb 03, 2010

When I listen to Elsiane, this is what I see

← Previous Next → Page 2 of 3