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.
See also
- Chiptunes – unrelated but interesting nevertheless
Articles
- Bytebeat – Olli Niemitalo
- Algorithmic symphonies from one line of code — how and why? – Ville-Matias Heikkilä
- Some deep analysis of one-line music programs. – Ville-Matias Heikkilä
- Bytebeat – Kragen Javier Sitaker
- This Meet Bytebeat: A Brand New Electronic Music Genre
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:
- Arduino-TVout, possibly this library, which appears to be the latest maintained repository
- or this Playground – TVout , Google code repository
- See also Arduino TVout
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