Sunday, October 02, 2011

Tweetable, One Loop, One Function, Simple Arduino Music

Inspired by the work in this thread on Pouet and also this Youtube video containing code by viznut, tejeez and visy, I decided to take the plunge and try out some simple maths music as well! Of course, my platform of choice for this is the Arduino (actually - I used the Teensy).

The hardware setup is very simple - simply an R2R DAC connected to output bits 0, 1, 2 and 3 of PORTB. For the Arduino board, this means digital pins 8, 9, 10 and 11. For the Teensy board, this means digital pins 0, 1, 2 and 3. In the schematic below, R1, R2, R3, R4 and R8 are double the value of R5, R6 and R7. For example - R1 might be 100kΩ and R5 might be 50kΩ.


I set myself some limitations with the coding side of things. The code should:
1) Be 140 characters or less with the whitespace removed i.e. Twitterable.
2) Contain a single 'for' loop within the main loop of the program
3) Contain a single function within the 'for' loop that sets the current value of PORTB
4) Additional libraries such as maths.h are to be avoided
5) The output should only be four bits

Let's hear some examples!


Example #1
void setup() {DDRB=B00001111;}
void loop() {for(long i=0;i<1000000;i++) {PORTB=i>>8;}}

Example #2
void setup() {DDRB=B00001111;}
void loop() {for(long i=0;i<1000000;i++) {PORTB=i/2>>2|i/3>>2;}}

Example #3
void setup() {DDRB=B00001111;}
void loop() {for(long i=0;i<1000000;i++) {PORTB=i/(i>>12&3)&i/(3+(i>>11&31))|(i/3)|((i/2)|(i>>9&15));}}

Example #4
void setup() {DDRB=B00001111;}
void loop() {for(long i=0;i<100000;i++) {PORTB=i/(1+(i>>12))>>5|i>>i/(6+(6-i>>12))|i/3>>4;}}

Example #5
void setup() {DDRB=B00001111;}
void loop() {for(long i=0;i<100000;i++) {PORTB=i/3>>(i%40+5)|i/(24+i&3)>>(i%(15-((i>>15)%8)*6)+5);}}

Example #6
void setup() {DDRB=B00001111;}
void loop() {for(long i=0;i<100000;i++) {PORTB=i/5>>(1+((i>>12)&3))|i/2>>2&(i/6)>>7|i&31*i*(i>>8);}}

Example #7

void setup() {DDRB=B00001111;}
void loop() {for(long i=0;i<100000;i++) {PORTB=i/13>>(1+((i>>12)&3))|i/2>>2&(i/6)>>7|i&31*i*(i>>8);}}


In general, I guess we can call this "index modulation", in the sense that we have a counter (i) that keeps track of a loop. The sound output is calculated on a sample by sample basis using a function that manipulates i in various ways (left and right shifting, multiplication, divide, modulo etc). The combined output for each sample is then output to the R2R DAC where the value is converted to a voltage, which can be sent to a piezo, an amp or an audio input.

I find these ideas very exciting - it's a very minimalist approach to creating sound and music on a basic level, yet the outcomes are at times complex, containing rhythm, pitch and structure.

7 comments:

Anonymous said...

Mr Scale, soundbites would be greatly appreciated!

Sebastian Tomczak said...

Hi! Each of the example titles is actually a link going to an MP3 recording of the resultant audio.

Anonymous said...

Seems like I was made of retard then :)

Thank you!

Sebastian Tomczak said...

No worries buddy!

aw3qc said...

Thank you very much for sharing this info. I made a little video:

http://vimeo.com/29928517

cheers

Unknown said...

Thank you very much for sharing this information. I made alittle video:

http://vimeo.com/29928517


cheers

Anonymous said...

Hi There is a better name for that method of synthesis than 'index modulation'. It is called WAVETABLE :)