ByteBeat on Arduino

Preamble

Following on from Can an Arduino function as a DSP?, it is possible for the Arduino to make music – take Bytebeat, for example.

What is byte beat?

Bytebeat is a music synthesis technique that was discovered by Ville-Matias Heikkilä (viznut/pwp). Kragen Javier Sitaker has a good writeup on the subject. The way it works is that you generate a stream of 8-bit audio with the samples calculated by a function of sample index. This means that the song is defined by the function. In pure-form bytebeat, the function corresponds to a computer program that employs bit-wise and basic arithmetic operators, meaning that a small-sized formula would also have a small-sized implementation if realized in machine language or something like that. It may have been vital to Viznut’s discovery that he experimented with a low 8 kHz sampling frequency. With high sampling frequencies, the flat spectral envelope arising from bit-wise operations and numerical wrapping makes the sound thin and harsh. I regretfully admit that initially I had doubts that the methodology would be able to produce anything else than glitch-y noise, but it turns out that some formulas produce songs suitable for a wider audience.

Olli Niemitalo on 2012-02-25

See also

  • Chiptunes – unrelated but interesting nevertheless

Articles

Links

Video

Music from very short programs – the 3rd iteration

Code

The code function that creates the music looks typically like this:

u=t>>10,8*t*t*(t>>u%3+15)/(3+(u&(u>>5&3|4)))|t>>4

Arduino sketches

The following two examples are linked to from Kragen’s ByteBeat.

This code has accompanying video: byte beat en arduino, but it requires the TVout library, written by Myles Metzer:

This sketch is simply the audio without the video component, from AudioPWM.pde:

// Based on http://arduino.cc/en/Tutorial/Fading by David A. Mellis 
// and Tom Igoe, http://www.arduino.cc/playground/Code/PwmFrequency,
// and viznut's, skurk's, and raer's discoveries documented in 
// http://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.html
#include "wiring_private.h"
#undef round
#undef abs

// The speaker is on Arduino pin 11, which is port B pin 3, pin 17 on the PDIP.
// The signal on this pin is OC2A.

void setup()  { 
  // set bit 3 in data direction register B to 1 to configure Port B pin 3 for output:
  //pinMode(11, OUTPUT);
  DDRB |= 1 << 3;
  // I forget what this does!
  TCCR2A |= 1 << COM2A1;
  // use 0x01 for divisor of 1, i.e. 31.25kHz
  // or 0x02 for divisor of 8, or 0x03 for divisor of 64 (default)
  TCCR2B = TCCR2B & 0xf8 | 0x01;
} 

long t = 0;
int i = 0;

void loop() {
  if (++i != 64) return;
  i = 0;
  t++;
  OCR2A = ((t<<1)^((t<<1)+(t>>7)&t>>12))|t>>(4-(1^7&(t>>19)))|t>>7;
  return;
  
  switch ((t >> 22) & 3) {
    case 0:
      OCR2A = t*2*(char((t>>10)^(t>>10)-2)%11) | t >> 2 | (char(t>>15^t>>16^0x75)>>(7&t>>10)&1?0:-1);
      break;
    case 1:
      OCR2A = 255-((1L<<28)/(1+(t^0x5800)%0x8000) ^ t | t >> 4 | -t >> 10);
      break;
    case 2:
      OCR2A = ((t<<1)^((t<<1)+(t>>7)&t>>12))|t>>(4-(1^7&(t>>19)))|t>>7;
      break;
    case 3:
      OCR2A = ((((t>>6|t<<1)+(t>>5|t<<3|t>>3)|t>>2|t<<1) & t>>12) ^ t>>16);
      break;
  }    
}

 

Expansion via hardware

As can be seen the overall expression is made up from various sub-expressions.

It would be simple enough to add:

  • Potentiometers
  • BCD switch banks

to the Arduino input pins, in order to input and vary the multipliers, subtractors and the  number of shifts, etc. of a given expression.

However, to vary the form, and the order, of the expression would be a little more complex, and while the various parts of the expression could be chosen, using rotary switches/switches/push buttons, to select which various sub expressions are used, and in which left-to-right order, these would have to be chosen from a predefined pallet of sub expressions. I can’t see how custom sub-expressions could be made, without the use of a keyboard/keypad, or a relatively complex UI with menus, etc., using a touch screen.

Other examples

Taken from NEO_8Pixel-OneLiners.ino

case 1: // a classic
snd = (t|5) * ((t>>p1|t>>11)&p1&t>>3);
break;
case 3: // a classic
snd = (t*(t>>8|t>>4))>>(t>>p1);
break;
case 2: // a classic
snd = t*t/p1;
break;
case 4: // a classic
snd = (t|3) * ((t>>1|t>>6)&p1&t>>3);
break;
case 0: // a classic
snd = t*((t>>12|t>>8)&63&t>>(p1>>3));
break;
case 5: // a classic
snd = t * ((t>>p1|t>>3)&17&t>>9);
break;
case 6: // //dubStep
snd = t>>3&1?t>>4:-t>>(p1>>3) ; //dubStep
break;
case 7: // Tribute to Klaus
snd = ((((t/3)&(t>>11))|((t/5)&(t>>p1)))&7)*30;

blah

 

Leave a comment