klammer: videophone for android

A month ago, I spent a couple of weeks developing a Wi-Fi Direct videophone app for  Android. I had some ideas about creating an outdoorsy chatty thing that would have worked even when you were far away from a wireless access point.

Unfortunately, Wi-Fi Direct has a fairly limited range, to the point that if you’re close enough for the videophone to work, you’re close enough to just wave the other person over. So, maybe not the best use of time. On the other hand, I did get a little experience with the technology, plus audio and video codecs, so that’s a plus.

Anyway, the source itself is now on GitHub, and you’re free to do what you like with it.

freebeard: algorithmic music for android

My second Android app has hit the Play Store. It’s called Freebeard, and it makes music.

freebeard-1

That’s it, pretty much. The whole UI is just a notification. The application runs inside a service. Here’s a sample of the output:

It grew out of a simple experiement. I yanked the synthesizer module out of Quencher, and yoked it to a Markov chain initialized with random data. The result was interesting, though nothing I’d listen to for long. If the chain contained a few nodes, it would repeat the same note patterns endlessly. Adding more nodes created more variations, but also increased the randomness of the output. A melody that wanders everywhere and goes nowhere is just as boring as an endlessly repeated note. What I needed was some way of bringing long-term patterns into the music to be modulated and mutated over time.

Chains with few nodes create recognizable patterns. What if I built an array of them, and switched from one to the next as the music progressed? That works, but it’s still kind of boring, because once you play through the entire array, you have nowhere to go but back to the beginning. Moving through the chains in random order mixes things up, but it’s the wrong kind of mixing up. It’s patternless and unrepeatable.

Obvious solution? Drive the array with another little Markov chain. A chain of chains, if you like. That way, you have second-order effects, a larger pattern driving the smaller ones. I create all the improvisational lines, rhythm patterns, and chord changes this way. It’s simple, but there’s a whole lot of stuff that comes out of that simplicity.

let’s make lots of echoes: building a simple reverb

Having drifted into video for a bit, I’m back into audio, and putting together an exciting thing that I’ll be releasing soon. For this new project, I needed to sweeten the output of an audio synthesizer: add a little warmth, a little depth, that sort of thing. Give it atmosphere. How about some reverb? Sounds good!

So, what exactly is reverb? It’s the sum total of many, many echoes combining with the original signal. Imagine a musician playing in a large chamber. Sound waves from her instrument will bounce from the near wall, the far wall, the ceiling above her head, the floor twenty feet away, and so on, and each echo will bounce into other bits of the chamber, and so on, and so on. The echo intervals are very small–like fractions of a millisecond small. The totality of all these echoes, and echoes of echoes, produces a sort of low mutter that decays slowly. When applied to an audio signal it adds a sense of space, of location.

There are many algorithms that can provide reverb. Some involve convolution, others combine filters. I didn’t need anything too complex or configurable, and it’s been said that one can build nearly any effect out of delay lines. I decided to give it a try. Here’s what I came up with.

/**
 * implement circular delay buffer with multiple feedback paths
 */
public class Delay {

	static int Length = 8192;
	static int Modulus = Length - 1;

	static float Mixer = 0.95f;

	float[] buffer = new float[Length];
	int reader;
	int writer = Length >> 1;
	int[] path = new int[8];

	public Delay() {
		relocate();
	}

	/**
	 * recreate feedback paths to relocate echoes
	 */
	public void relocate() {
		Random rng = new Random();
		for (int i = 0; i < path.length; i++) {
			path[i] = rng.nextInt();
		}
	}

	/**
	 * process the next sample
	 */
	public float process(float s) {
		for (int i = 0; i < path.length; i++) {
			int w = (writer + path[i]) & Modulus;
			buffer[w] = s * (1f - Mixer) + buffer[w] * Mixer;
		}
		writer++;
		return buffer[(reader++) & Modulus] + s;
	}

}

Let’s see. The buffer size isn’t configurable but could be made so. Just make sure it’s a power of two, as I’m using one of my favorite buffer tricks: bitwise-AND modulus, which prevents indices from running over the length without hitting a conditional or an expensive divide-based modulus.

The path array represents a small number of feedback paths randomly distributed across the buffer that provide echo sources. Calling relocate() will shuffle them around. The user calls process() and supplies an audio sample, receiving in return the sample mixed with reverb. Inside the call, the sample is placed wherever the paths dictate, blending it with whatever’s already there.

The effect it produces is not nearly as impressive as you can get with more complex algorithms or DSP hardware, but for my application, it’s perfect. It gives the flat output of the synthesizer a subtle depth–a sense of having been recorded live rather than generated, and that’s all I needed.

ADDENDUM:

For best performance, you’ll want to submit a sample buffer to the delay object instead of trying to process one sample at a time. Here’s an implementation of the process() method that does this.

public void process(float[] sample) {
	for (int i = 0; i