Real Sound Cookery – Make a contact mic with baking soda and cream of tartar. | leafcutterjohn.com

A couple of months ago, Collin’s Lab featured a story about making your own piezoelectric crystals from Rochelle salt. Collin stopped short of making an actual microphone though: he just demonstrated that the salt crystal would generate a series of voltage spikes when whacked with the handle of a screwdriver. Leafcutter John followed pretty much the same recipe to make crystals of his own, and then clamped the crystal between the jaws of a little panvise, and hooked it to an audio amplifier. When a small music box was held near the crystal, a surprisingly high fidelity recording resulted. Check it out!

Real Sound Cookery – Make a contact mic with baking soda and cream of tartar. | leafcutterjohn.com.

Building tanjent’s “bliplace” kit…

I was in the mood to melt some solder, but didn’t really have a lot of time and/or brainpower last night, so I turned to my box of little electronics kits that seems to have been growing over the last few years. I located a small plastic bag which contained tanjent’s “bliplace”, a tiny kit that he generously was handing out at a conference we both attended. It’s simple: an Atmel ATTINY 8 pin controller, three caps, five resistors, an electret microphone and a battery is all it takes to get it to run. I figured it would take me about 20 minutes to assemble. It took about 35, mostly because I wasn’t paying attention and soldered the first two resistors in the wrong place (the board has a very symmetric layout, and I got turned around). That got me some practice in using my solder sucker, and had to solder in two new 1K resistors from my junkbox. But in the end, it worked!

What is bliplace? In his words:

Bliplace is a wearable, hackable, sound-activated blinky light toy. It uses a small microcontroller and a mix of hardware and software feedback to automatically synchronize with and adapt to the sounds around it – it should pulse along with the ambient noises around you no matter if you’re in a quiet park or a thunderously loud concert.

Here’s the video of the thing working. Pardon the sound levels when I turn the radio up, I shot and edited this on my iPhone.



It’s a clever little gadget by itself. But what’s especially cool is that it is open source. You can get the board and schematic files, Gerber files, and the source code for the firmware. I think it would be interesting to make an “amped up” version of this thing, which would drive some big power transistors to switch some truly high power CREE LEDs. The code is released under the MIT license, so modifications should be easy and redistributable. It should be trivial to get this to run on the Arduino platform as well, which will make experiments easier for the wider audience.

I’ll be staring at the code a bit harder over the next few days. Stay tuned.

You can tune a banjo, but you can’t tuna fish…

Or can you? Courtesy of the Make Blog, here’s an interesting little musical instrument called a “canjo”, a two string banjo that uses an old 4″ tuna fish can as the resonating cavity. Perhaps I should take a break from my plinky string sounds generated with software, and instead do it the old fashioned way.

Tuna can guitar @Makezine.com blog.


httpv://www.youtube.com/watch?v=W4sq17JFC8w

Plink2!

Okay, I finally found my copy of Ken Steiglitz’s A DSP Primer (a great book, but sadly more expensive now than when I got my copy) and read through the implementation of the tunable plucked string instrument. A couple of things really need to be added: first of all, I was off considerably in my tuning because the averaging operation inserts a delay of 1/2 a sample, and the tuning was necessarily coarse because the frequency was entirely determined by the length of the delay buffer, which was an integer. To make that work, you need to introduce an all-pass filter, which has a pretty simple form. Without any additional explanation, here’s the source code that I tinkered together over a half an hour of reading and typing.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sndfile.h>

/*
 * ks.c
 * an implementation of the Karplus-Strong algorithm, revised after
 * reading Ken Steiglitz's treatment in "A DSP Primer".
 */

#define SAMPLE_RATE     (22050)

double freq = 440. ;

main(int argc, char *argv[])
{
    SNDFILE *sf ;
    SF_INFO sfinfo ;
    double delay ;
    int L ;
    int i, j ;
    int sample ;
    double a  ;
    double w0 ;
    double x0, y0, x1, y1 ;

    freq = atof(argv[1]) ;

    sfinfo.samplerate = SAMPLE_RATE ;
    sfinfo.channels = 1 ;
    sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;

    sf = sf_open(argv[2], SFM_WRITE, &sfinfo) ;

    /* first of all, figure out the total delay... 
     * freq = SAMPLE_RATE / (L + 0.5) 
     * or L = SAMPLE_RATE / freq - 0.5 ;
     */

    delay = SAMPLE_RATE / freq - 0.5 ;
    fprintf(stderr, "... delay = %f\n", delay) ;
    L = floor(delay) ;
    delay -= L ;
    fprintf(stderr, "... buffer size is = %d\n", L) ;
    fprintf(stderr, "... fractional delay is = %f\n", delay) ;

    fprintf(stderr, "... approximate value for a = %f\n", (1-delay)/(1+delay)) ;
    w0 = 2.0 * M_PI * freq / SAMPLE_RATE ;
    a = sin((1. - delay) * w0/2.) / (sin((1. + delay) * w0/2.)) ;
    fprintf(stderr, "... exact value for a = %f\n", a) ;

    /* okay, now generate one second of the plucked string sound.
     */

    double *buf = calloc(L, sizeof(double)) ;

    /* initialize with random numbers. */
    for (i=0; i<L; i++) 
        buf[i] = 2.0 * drand48() - 1.0 ;

    x0 = y0 = 0. ;
    for (sample=i=0; sample < SAMPLE_RATE * 0.25 ; sample++) {
        j = i + 1 ;
        if (j >= L) j = 0 ;
        x1 = (buf[i] + buf[j]) / 2. ;
        /* implement the "allpass" filter. */
        y1 = a * x1 + x0 - a * y0 ;
        sf_write_double(sf, &y1, 1) ;
        y0 = y1 ;
        x0 = x1 ;
        buf[i] = y1 ;
        i = j ;
    }

    sf_close(sf) ;
}

This just writes out 1/4 of a second of a note tuned at the frequency that you specify. I wrote a little python program, and computed an mp3 of a simple two octave run of notes.

Addendum: I synthesized the small set of three note chords just to test how them merged. They do sound a bit plinky and a little thin, but not terrible.

Plink!

The other day, I was trying to remember how to generate some simple sounds with minimal amounts of code. I remembered vaguely something called the Karplus-Strong algorithm, and it has been floating around in my head that I should look it up again. I mentioned it to Tom, and he spent 15 seconds drawing something on his whiteboard to remind me how the rudiments of it worked. I spent two or three minutes in a break typing in this small chunk of C to try it out:

#include <stdio.h>
#include <stdlib.h>
#include <sndfile.h>

/*
 * ks.c
 * a small implementation of the karplus-strong synthesis algorithm
 * as described to me in 15 seconds or less by Tom Duff, and implemented
 * in the two or three minutes that it took to type in.
 */

#define SAMPLE_RATE     44100
#define TONE            440

/*
 *  BUFSIZE is essentially the period of the sound in samples.
 */

#define BUFSIZE         (SAMPLE_RATE/TONE)

double buf[BUFSIZE] ;

main()
{
    int sample ;
    int i, j ;
    double s ;
    SNDFILE * sf ;
    SF_INFO sfinfo ;

    sfinfo.channels = 1 ;
    sfinfo.samplerate = SAMPLE_RATE ;
    sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;

    sf = sf_open("test.wav", SFM_WRITE, &sfinfo) ;

    for (i=0; i<BUFSIZE; i++)
        buf[i] = 2.0 * drand48() - 1.0 ;

    for (sample=i=0; sample<5*SAMPLE_RATE; sample++) {
        j = i + 1 ;
        if (j >= BUFSIZE) j = 0 ;
        s = (buf[i] + buf[j]) / 2 ;             /* simplest filter imaginable */
        buf[i] = s ;
        sf_write_double(sf, &s, 1) ;
        i = j ;
    }

    sf_close(sf) ;

}

Here is link to the single note that the above code generated. Sure, it’s not all that impressive by itself, but consider how simple the code is. It takes a small buffer of random numbers and a simple averaging operation, and generates something which isn’t a completely unpleasant plucked-string sound. I find that rather remarkable. I’ll probably use this in a little programming project that I’ve been mulling over which involves Christmas music. Stay tuned.

Ambisonic Microphone Exp2 Construction

Here’s one for Tom, or anyone else interested in doing ambisonic sound recordings. It mounts four inexpensive Panasonic electret microphones into a tetrahedral array to record sound that can later be processed for surround or other spatialization effects. Seems pretty cool, and they even include the patterns for PCBs that can be cheaply manufactured by ExpressPCB. Nifty!

Ambisonic Microphone Exp2 Construction Documents page.

Zounds! Sounds!

Tom and I have been discussing some early hacking efforts, probably spawned in part by my re-reading of Levy’s Hackers. A couple of days ago, this resulted in me pondering the mysteries of Minsky’s circle algorithm (still ongoing), but today it drove me to an early interesting sound algorithm documented in the legendary HAKMEM, ITEM 168, which shows a simple six instruction program that generated sounds on the PDP-1. The basic idea was pretty simple: we have two variables, A and B. Read the front panel switches from the PDP-1, and add it to A. Then take the contents of A, apply a bit-wise AND from a mask, and then add that to B. Mask off the high bit of B, and output that as the “music”. (Note: I am a bit confused by ITEM 168. The PDP-1 code there doesn’t seem to be exactly what I described, but the mnemonics they list are somewhat unfamiliar to me. In any case, the rough English description above will suffice for now…)

In any case, I didn’t have a PDP-1 lying around, so I decided to implement the thing in C, using portaudio and the GNU readline library. Here’s the code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <readline/readline.h>
#include <sndfile.h>

/*                  __             
 *    ___  ___ ____/ /__  ___  ___ 
 *   / _ \/ _ `/ _  / _ \/ _ \/ _ \
 *  / .__/\_,_/\_,_/\___/\___/ .__/
 * /_/                      /_/    
 *
 * A simple musical toy inspired by some discussions on early computer 
 * music with Tom Duff, written by Mark VandeWettering.
 * 
 * THE BASIC IDEA
 * Tom informed me that someone generated odd musical tones with a 
 * very short program on the PDP 1 that basically looked like this:
 * 
 * for (;;) {
 *    a += sw ;         some front panel switches
 *    b += a & mask ;   mask just selects some part of a...
 *    output(a>>30) ;   output a single bit square wave... 
 * }
 * 
 * So that's what this toy emulates.   
 * 
 * I've also added a tiny bit of interface to allow you to change the 
 * switch settings and the mask on the fly, to "play" the instrument.
 * 
 * I've called this program "padoop" just because I needed some vowels
 * added to "PDP".
 * 
 * Tom points out that it wouldn't be hard to implement this in 
 * hardware, completely without a processor.
 */

#include <stdint.h>
#include <portaudio.h>

#define SAMPLE_RATE     44100

typedef struct {
        uint32_t        a, b ;
        SNDFILE         *sf ;
} paMusicData ;

uint32_t        SW ;
uint32_t        MASK ;

/* 
 * Here is a very simple output filter designed by Fisher's mkfilter code.
 */

#define NZEROS 2
#define NPOLES 2
#define GAIN   3.414213562e+00

static float xv[NZEROS+1], yv[NPOLES+1];

float
filter(float inp)
{
    xv[0] = xv[1]; xv[1] = xv[2]; 
    xv[2] = inp / GAIN;
    yv[0] = yv[1]; yv[1] = yv[2]; 
    yv[2] = (xv[0] + xv[2]) + 2 * xv[1]
        + ( -0.1715728753 * yv[0]) + ( -0.0000000000 * yv[1]);
    return yv[2];
}

static int
paMusicCallback(const void * inputBuffer,
                void * outputBuffer,
                unsigned long framesPerBuffer,
                const PaStreamCallbackTimeInfo * timeInfo,
                PaStreamCallbackFlags statusFlags,              
                void * userData)
{
    paMusicData * data = (paMusicData *) userData ;
    float *out = (float *) outputBuffer, *op ;
    float f ;
    int i ;

    op = out ;
    for (i=0; i<framesPerBuffer; i++) {
        data->a += SW ;
        data->b += data->a & MASK ;
        *op++ = filter((data->b&(1L<<31))?1.0:-1.0) ;
    }

    if (data->sf != NULL) sf_write_float(data->sf, out, framesPerBuffer) ;

    return 0 ;
}

void
process_command(char *cmd) 
{
    uint32_t tmp ;

    if (strlen(cmd) > 0)
        add_history(cmd) ;
    if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0) {
        fprintf(stderr, "sw 0x%08X\n", SW) ;
        fprintf(stderr, "mask 0x%08X\n", MASK) ;
    } else if (sscanf(cmd, "sw %i\n", &tmp) == 1) {
        SW = tmp ;
        fprintf(stderr, "sw 0x%08X\n", SW) ;
    } else if (sscanf(cmd, "mask %i\n", &tmp) == 1) {
        MASK = tmp ;
        fprintf(stderr, "mask 0x%08X\n", MASK) ;
    }
}

main()
{
    PaStream *stream ;
    paMusicData data ;
    PaError err = Pa_Initialize() ;
    uint32_t m1, m2 ;
    if (err != paNoError) goto error ;
    SF_INFO sfinfo ;

    data.a = data.b = 0 ;
    /* log output data to a file... */

    sfinfo.samplerate = SAMPLE_RATE ;
    sfinfo.channels = 1 ;
    sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;
    data.sf = sf_open("padoop.wav", SFM_WRITE, &sfinfo) ;

    SW = 012345 ;
    MASK = 0x0f0f0f0f ;

    /* open the music output device... */
    err = Pa_OpenDefaultStream(&stream,
        0,              /* no input */
        1,              /* just one output */
        paFloat32,      /* output float data */
        SAMPLE_RATE,    /* at some sample rate */
        8192,           /* samples per frame */
        paMusicCallback,
        &data) ;

    if (err != paNoError) goto error ;

    /* start */
    err = Pa_StartStream(stream) ;
    if (err != paNoError) goto error ;

    for (;;) {
        char * line = readline("padoop> ") ;
        if (line == NULL) break ;
        process_command(line) ;
        free((void *) line) ;
    }
 
    err = Pa_StopStream(stream) ;
    if (err != paNoError) goto error ;

    sf_close(data.sf) ;

    err = Pa_Terminate() ;
    if (err != paNoError) goto error ;
    exit(0) ;

error:
    fprintf(stderr, "PortAudio error: %s\n", Pa_GetErrorText(err)) ;
    Pa_Terminate() ;
    exit(-1) ;
}

You’ll need to have the portaudio and readline libraries installed to me it work. When you run it, it should start making noises, and you’ll see a command line prompt. It accepts 3 commands: “print” which dumps the contents of the mask and switches, “sw” followed by a number, which sets the value of the switches, and “mask” followed by a number, which does the same for the mask. Give it a try.

Addendum: Try “sw 4096” and “mask 0xFF0F0000”. Let it run for a while. If you find some interesting settings, post them in comments.
Addendum2: I included a fairly soft output filter to round the square waves a tiny bit. I’m not sure it makes any difference at all.
Addendum3: I made a version of padoop that also logged the output audio to a WAV file, so even if you can’t compile it, you can hear some of the sounds it might make.
Output from Padoop, my PDP-1 inspired music program…
Another bit of output…
Addendum4: While editing, I got some of the escaped characters screwed up, so I reinserted with the latest version. It automatically outputs a padoop.wav file of all the output that the program creates.

The Virtual Choir – Eric Whitacre

In between celebrating the completion of a project at work (and coincidently Cinqo de Mayo) and pondering the mysteries of singular value decomposition, I found this rather interesting Internet collaboration, where the voices of 185 different singers which were recorded separately are combined into a virtual choir. The results are quite beautiful. Not my usual fare, but I found it interesting.

The Virtual Choir – Eric Whitacre.

Handmade Cigar Box Instruments – Ukuleles – Banjos – Guitars

It’s been a while since I posted a link to anything related to home made musical instruments, so when I ran across this page this morning, I thought of my friend Tom and his love of quirky instruments, and decided to pass it along. Papa’s Boxes sells both kits and completed ukuleles and banjos made from cigar boxes. Pretty neat folk instruments. Check it out.

Handmade Cigar Box Instruments – Ukuleles – Banjos – Guitars

Zinc based audio oscillators

Courtesy of the Make blog, check out Nyle Steiner’s Electronic Composition, using a variety of audio circuits which use bits of heated zinc instead of transistors. Nyle has done a bunch of experimentation with zinc negative resistance oscillators on his Spark, Bang, Buzz website, all of which are awesome.


httpv://www.youtube.com/watch?v=Z44jlvpRHXc

Intimate Control for Physical Modeling Synthesis

Okay, for every slobbery dog video I post, I promise to post something with a little more meat. My friend Tom is interested in all kinds of computer music and interface technologies, and no doubt, has already seen this controller. But just in case he hasn’t, here’s a really nifty controller, and even he has seen it before, the rest of you can be inspired by this home brew multitouch controller. Very nifty.

Intimate Control for Physical Modeling Synthesis.




Multitouch Prototype 2 from Randy Jones on Vimeo.

Dennis Havlena’s cool DIY instruments…

From the make blog, here is a pretty cool link to Dennis Havlena’s cool website about DIY musical instruments, including a youtube of him playing several of them. I’ve become fairly interested in folk music and folk instruments thanks to Tom, and Dennis’ web site has all sorts of ideas for instruments of every kind (string, wind, and percussion, and even odd combinations).

WEBPAGE of DENNIS HAVLENA – W8MI Mackinac Straits, MI



Weird Sound Generator

Here’s a link for Tom: a kit for the Weird Sound Generator. Unlike many of these things, I actually found the variety and quality of sounds produced by this thing to actually be pretty darned interesting. It might be fun to build one of these and work on your own soundtrack for Return to the Forbidden Planet. Check it out:

Weird Sound Generator

Here’s an MP3 of the example sounds you can make with this gadget.