k20
I finished the promised K-20 meter. I imaginatively called it k20, and you can find it at http://hans.fugal.net/src/k20. Here's a screenshot:

From left to right, read average (VU), peak (instantaneous with 26 dB / 3 sec falloff), maximum peak, and overs.
This is pure unadulterated printf() abuse. No ncurses. Not that I have
anything against ncurses, just that I'm lazy. Of course you need an ANSI
capable terminal, but I'm sure you can find one lying around.
opg ftw
Few things about programming (in most languages) are less enjoyable than
writing option parsing code. On the other hand, few things are more irritating
to users than no -h and no options where options are needed (or
underdeveloped option parsers). In few languages is it more painful to do
option parsing than it is in C.
So I did what any sane lunatic would do. I wrote an option parser generator. I think it's quite nice. This input:
usage: foo [options] other stuff
-f --foo bool Short name, long name, type, help text.
-b --bar=name char* This has a required string argument.
-z --baz=decibels int? Optional integer argument
-q --quux=MACH float char*, int, and float are the recognized types
Any line not starting with a dash is copied into the help message verbatim.
becomes this output (a header and source file):
/* This file is automatically generated by opg */
#ifndef _OPG_H
#define _OPG_H
struct options {
int f; /* foo */
char* b; /* bar */
int z; /* baz */
float q; /* quux */
};
/* Print usage and exit(1) */
void usage(void);
/* Parse options, populate opts, adjust argc/argv */
void parse_options(int *argc, char * const *argv, struct options *opts);
#endif
/* This file is automatically generated by opg */
#include "opts.h"
...
void usage(void)
{
puts("usage: foo [options] other stuff");
puts(" -f --foo Short name, long name, type, help text.");
puts(" -b --bar=name This has a required string argument.");
puts(" -z --baz[=decibels] Optional integer argument");
puts(" -q --quux=MACH char*, int, and float are the recognized types");
puts("");
puts("Any line not starting with a dash is copied to the help message verbatim.");
exit(1);
}
void parse_options(int *argc, char * const *argv, struct options *opts)
{
...
}
http://hans.fugal.net/src/opg. Enjoy.
Simple RSS
Have you ever thrown together a simple static webpage, only to find down the road that you want to add an RSS feed? What are your options? Maintain an ugly XML file by hand, or migrate to a big slow messy CMS. Yeah, no fun.
Sars is a simple RSS domain specific language. This:
# This is a YAML stream (http://yaml.org) but you don't need to know much YAML
# to get the hang of it.
# There are multiple "documents". The first document is the channel information:
---
title: Foo News Feed
link: http://example.com/foo/
description: News for the Foo Project
webmaster: you@example.com
# The second and subsequent documents are items. The first line is the title,
# the second line is the date, and the rest is the item description (Markdown).
# Because line endings are important, don't forget the pipe character.
--- |
Really Exciting Title
2/28/08 12:00
This is where I pontificate
about the really exciting fish
that is sitting on my plate.
Here's a [download link](http://example.com/foo/foo-1.0.tar.gz).
--- |
Another Item
2/28/08 12:04
You know, it doesn't really matter what order you put them in, since they each
have dates.
becomes this:
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>Foo News Feed</title>
<link>http://example.com/foo/</link>
<description>News for the Foo Project</description>
<lastBuildDate>Thu, 28 Feb 2008 12:07:32 -0700</lastBuildDate>
<generator>yaml2rss</generator>
<webMaster></webMaster>
<item>
<title>Really Exciting Title</title>
<description><p>This is where I pontificate
about the really exciting fish
that is sitting on my plate.</p>
<p>Here's a <a href="http://example.com/foo/foo-1.0.tar.gz">download link</a>.</p></description>
<pubDate>Thu, 28 Feb 2008 12:00:00 -0700</pubDate>
<guid>http://example.com/foo//2008-02-28T12:00:00-07:00</guid>
</item>
<item>
<title>Another Item</title>
<description><p>You know, it doesn't really matter what order you put them in, since they each
have dates.</p></description>
<pubDate>Thu, 28 Feb 2008 12:04:00 -0700</pubDate>
<guid>http://example.com/foo//2008-02-28T12:04:00-07:00</guid>
</item>
</channel>
</rss>
Any questions?
Crème Rappel v2.2
I've released yet again. Go to the web page for the details. Now Crème Rappel has its own RSS feed so I'll shut up about here now.
sourdough calculator 0.2
My sourdough calculator had a major bug in the calculations. If you followed its instructions you got much higher hydration than you asked for. e.g. if you asked for 68% hydration at 20% starter inoculation, you got a dough that was 74% hydration. Oops. It's been fixed and can be downloaded at the same place. Other changes include different defaults (500g 68% hydration loaf with 20% start) and volume measurements for the scale-deprived.
mg
My body is going on a diet (not me, but that's another post), but we all know it's no fun to go on a diet unless you get a nifty digital scale and make cool graphs of your progress. Over on the left you'll see my cool graph which I generate with a small ruby script (less than 60 LOC) and even smaller shell script. The use case is simple. Every day after weighing myself I do simply this:
mg $my_weight_today
You too can make cool graphs if you mosey on over to my src page.
Constructors, coercion and casting, oh my!
This little bit of C++ trivia I may have known once but had forgotten. If you have the appropriate constructor, the compiler will happily coerce for you:
class Foo
{
public:
Foo(int);
int i;
};
int bar(Foo f)
{
return f.i;
}
int main(void)
{
return bar(42);
}
You can also explicitly cast, which is useful when you are feeling explicit, or want to cast to a subclass for polymorphic reasons.
Summer of Code 2006
It's official! I am one of the recipients of Google's Summer of Code grant. That means I get paid $4500 to improve Ardour according to my proposal over the summer. Combined with the GAANN fellowship I've received this means I can spend most of the time this summer writing code for Ardour and studying for quals.
My proposal was to modify Ardour so that plugins can be applied to regions instead of just tracks, both for realtime processing and bounced to disk. This is a feature I have sorely missed in Ardour, as it is an important tool for making electronic music and musique concrete efficiently. The other half is to add undo/redo serialization of the current undo system to allow unlimited undo across program instances.
I'm really excited for this opportunity. It will be my first serious involvement with a big and important open source project as a developer. I've often told myself I needed to get involved with one, and now I have an ideal opportunity to do just that.
There are two other SoC recipients for Ardour. One is adding basic MIDI recording and playback, and the other is doing a Windows port.
Posted in cs | 3 comments |
ruby/audio 0.1.1
Ladies and Gentlemen, I bring you ruby/audio 0.1.1. This is primarily a bugfix release, but you fill find a few documentation and feature enhancements as well. Enjoy!
Posted in cs | no comments |