How to Create 8-bit Music on Android

  Programming

8-bit music has been around for several decades now. Although not as popular as it was back in the 80s, it still is used in some games. There’s also a very active, though small, community of 8-bit music producers today. Creating such music takes just a few lines of code if you use the classes offered by the Android SDK. Because I am no music producer, in this tutorial, I’ll just be showing you how to generate musical frequencies programmatically. You can always string multiple frequencies together to generate some beautiful 8-bit tune.

Prerequisites

To be able to follow this tutorial, you’re going to need the latest version of Android Studio and an emulator running Android 4.0.4 or higher.

Generating a Frequency

Let us now create a method that accepts a frequency and a duration as its inputs and generates a sound of the given frequency that lasts for the given duration.

private void generateSound(int frequency, int duration) {

}

We’ll be using pulse-code modulation, or PCM for short, to create the sound. In simpler terms, we’ll be generating a sine wave and sampling it a fixed number of times per second.

Additionally, because we are interested only in 8-bit sounds, we’ll have to make sure that the value of each sample can be represented by a single byte.

Keeping the above details in mind, we’ll be generating sampleRate * duration samples. Here’s the code to do that:

int sampleRate = 44100; // Feel free to change this
byte soundData[] = new byte[sampleRate * duration];

for(int i = 0; i < soundData.length; i++) {
    byte sample = (byte)(
            Math.sin(2 * Math.PI * frequency * i / sampleRate) *
            255);
    soundData[i] = sample;
}

Note that we are using a simple sine wave. If you don’t understand the formula, I suggest you refer to this page.

Now that we have the sound data, we can pass it to an AudioTrack object to actually hear the sound. To initialize the AudioTrack instance, you can use its constructor, which accepts a few very obvious arguments.

AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,
        sampleRate,
        AudioFormat.CHANNEL_OUT_DEFAULT,
        AudioFormat.ENCODING_PCM_8BIT, soundData.length,
        AudioTrack.MODE_STATIC
);

To let the AudioTrack instance know that we want to play the sound that’s contained in the soundData array, use the write() method. Finally, call play() to start playing the sound.

track.write(soundData, 0, soundData.length);
track.play();

Go ahead and try to test the method now. Here’s a sample call to the generateSound() method that generates a tone of 440 Hz for 15 seconds.

generateSound(440, 15);

At this point, if you run your app, you should be able to hear the sound.

Warning: If you are wearing headphones and are using an emulator, lower the volume to protect your ears.

Adding Harmonics

The sound we just generated is way too simple. Usually, you can improve the quality of the sound, and make it feel a little more realistic by adding harmonics to the wave. A harmonic is nothing but the same sine wave having a frequency which is a multiple of the original frequency.

Let us now add two harmonics to our wave. The first harmonic will have frequency which is 2x the original frequency. Similarly, the second harmonic’s frequency will be 4x the original frequency. Furthermore, let the amplitudes of the harmonics be lower than 1, say 0.5 and 0.25.

Here’s the updated code to generate the samples:

for(int i = 0; i < soundData.length; i++) {
    double originalWave = Math.sin(2 * Math.PI * frequency * i / sampleRate);
    double harmonic1 = 0.5 * Math.sin(2 * Math.PI * 2 * frequency * i / sampleRate);
    double harmonic2 = 0.25 * Math.sin(2 * Math.PI * 4 * frequency * i / sampleRate);

    // Add all the waves
    byte sample = (byte)((originalWave + harmonic1 + harmonic2) * 255);
    soundData[i] = sample;
}

If you run the app now, you should hear a slightly different sound.

Conclusion

You now know how to create 8-bit sounds using the Android SDK. Go ahead and experiment with different frequencies and harmonics, and also try modifying the waveform.

If you found this article useful, please share it with your friends and colleagues!