Monday, January 14, 2008

Arduino noise maker info

Demo Video:
http://www.youtube.com/watch?v=UKxdTvKqIRc


How it works:
In essence, the waveform is constructed continuously using both the data from the arrays as well as external electrical states (pots, signals etc).

Two arrays store the data for pitch (128 ints) and waveform (544 bytes). The pitch array has been generated from converting MIDI notes to frequency, then from frequency to period time. This value is then divided by 32 to provide 32 samples per cycle. The pitch byte is read from an analog potentiometer on a cycle by cycle basis.

The waveform array was calculated by taking a sinewave of length 32 samples and then squaring it out over the 16 repetitions over the 512 bytes left in the array. The data bytes in the array are 6 bits in length and then they have been shifted left by 2 bits, so that port d (pins 0 to 7) of the Arduino can be set quickly without any bit shifting.

Arduino pins 2 to 7 are used in a resistor network to create a 6 bit digital to analog converter. One of the binary counters (4040 IC) is connected directly into pins 8, 9 and 10 and are read into the Arduino to scale the waveform on a sample by sample basis, effectively creating the possibility of an envelope generator.

The other 4040 IC is used to create a 3 bit digital to analog converter that is scaled by a potentiometer and then fed into an Arduino analog input. This data adds a delay in microseconds to the waveform on a sample by sample basis, effectively creating a pitch shifter / vibrato etc. This value is read on a cycle by cycle basis.


Schematic:


Breadboard:
Arduino Code:

/* Arduino Synthesis in 6 bits */

int pitchArray[] =

{3822, 3608, 3405, 3214, 3034, 2863, 2703, 2551, 2408, 2273, 2145, 2025, 1911, 1804, 1703, 1607, 1517, 1432, 1351, 1276, 1204, 1136, 1073, 1012, 956, 902, 851, 804, 758, 716, 676, 638, 602, 568, 536, 506, 478, 451, 426, 402, 379, 358, 338, 319, 301, 284, 268, 253, 239, 225, 213, 201, 190, 179, 169, 159, 150, 142, 134, 127, 119, 113, 106, 100, 95, 89, 84, 80, 75, 71, 67, 63, 60, 56, 53, 50, 47, 45, 42, 40, 38, 36, 34, 32, 30, 28, 27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 3, 2, 2, 2, 1, 1};


int waveArray[] =

{128, 152, 176, 196, 216, 232, 244, 248, 252, 248, 244, 232, 216, 196, 176, 152, 124, 100, 76, 56, 36, 20, 8, 4, 0, 4, 8, 20, 36, 56, 76, 100, 128, 152, 176, 200, 220, 240, 252, 252, 252, 252, 252, 240, 220, 200, 176, 152, 124, 100, 76, 52, 32, 12, 0, 0, 0, 0, 0, 12, 32, 52, 76, 100, 128, 156, 180, 208, 228, 248, 252, 252, 252, 252, 252, 248, 228, 208, 180, 156, 124, 96, 72, 44, 24, 4, 0, 0, 0, 0, 0, 4, 24, 44, 72, 96, 128, 156, 184, 212, 236, 252, 252, 252, 252, 252, 252, 252, 236, 212, 184, 156, 124, 96, 68, 40, 16, 0, 0, 0, 0, 0, 0, 0, 16, 40, 68, 96, 128, 156, 188, 216, 240, 252, 252, 252, 252, 252, 252, 252, 240, 216, 188, 156, 124, 96, 64, 36, 12, 0, 0, 0, 0, 0, 0, 0, 12, 36, 64, 96, 128, 160, 192, 224, 248, 252, 252, 252, 252, 252, 252, 252, 248, 224, 192, 160, 124, 92, 60, 28, 4, 0, 0, 0, 0, 0, 0, 0, 4, 28, 60, 92, 128, 160, 196, 228, 252, 252, 252, 252, 252, 252, 252, 252, 252, 228, 196, 160, 124, 92, 56, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 56, 92, 128, 164, 200, 232, 252, 252, 252, 252, 252, 252, 252, 252, 252, 232, 200, 164, 124, 88, 52, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 52, 88, 128, 164, 204, 240, 252, 252, 252, 252, 252, 252, 252, 252, 252, 240, 204, 164, 124, 88, 48, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 48, 88, 128, 168, 208, 244, 252, 252, 252, 252, 252, 252, 252, 252, 252, 244, 208, 168, 124, 84, 44, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 44, 84, 128, 168, 212, 248, 252, 252, 252, 252, 252, 252, 252, 252, 252, 248, 212, 168, 124, 84, 40, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 40, 84, 128, 172, 212, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 212, 172, 124, 80, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 80, 128, 172, 216, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 216, 172, 124, 80, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 80, 128, 176, 220, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 220, 176, 124, 76, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 76, 128, 176, 224, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 224, 176, 124, 76, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 76, 128, 180, 228, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 228, 180, 124, 72, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 72, 128, 180, 232, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 232, 180, 124, 72, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 72};


byte pitch;

int wave;

int vibrato;


void setup() {

pinMode(2, OUTPUT);

pinMode(3, OUTPUT);

pinMode(4, OUTPUT);

pinMode(5, OUTPUT);

pinMode(6, OUTPUT);

pinMode(7, OUTPUT);

pinMode(8, INPUT);

pinMode(9, INPUT);

pinMode(10, INPUT);

pinMode(13, INPUT);

}


void loop() {

for(int k = 0; k < 64; k ++) {

if(digitalRead(13) == 1) {

for(int j = 0; j < 8; j ++) {

pitch = analogRead(2) >> 3;

wave = analogRead(1) >> 2;

vibrato = analogRead(0);

for(int i = 0; i < 31; i ++) {

PORTD = waveArray[i + wave] >> (PINB & B00000111);

delayMicroseconds(pitchArray[pitch] + vibrato);

}

}

}

else

{

for(int j = 0; j < 8; j ++) {

pitch = analogRead(2) >> 3;

wave = analogRead(1) >> 2;

vibrato = analogRead(0);

for(int i = 0; i < 31; i ++) {

PORTD = waveArray[i + k + wave] >> (PINB & B00000111);

delayMicroseconds(pitchArray[pitch] + vibrato);

}

}

}

}

}

16 comments:

Anonymous said...

Hey thanks man :) Im gonna try it out!

Sebastian Tomczak said...

No probs. Let me know if the schematic is... problematic. I drew it when i was very tired.

Anonymous said...

hi sebastian. i've build up your schematic. The sound i get is really weird. but i try to debug what i did ;-)

Sebastian Tomczak said...

well, i guess it is supposed to make weird sounds! but hey, have you any pictures of your setup? or, you haven't changes the code, right?
hmmmm.

Anonymous said...

Hi. There is an image under http://www.ep7.ch/setup.jpg. I've ordered new potis... in the meantime i use these. I dont have the same sound as yout got with your setup. Thanks

Sebastian Tomczak said...

Oh, okay. I am not sure how much i can help you from here! But you have some sort of sound going, yes?

Unknown said...

Hi there! So I was wondering about the resistance of the pots labeled on your schematic as R32 and R33, are they 1M or 10K or what? The others are very clearly labeled. Sorry if the info is there, Im kind of a beginner and cant quite figure it out. Thanks a lot!

Sebastian Tomczak said...

Hi Ben,
The pots that you point out don't need to be a specific value. Anything between 10kΩ and 1MΩ should be just fine. The reason is that they are just diving VCC in order to provide an analog voltage value to the ADC on the Arduino. The actual current is irrelevant, only the voltage. Because the voltage dividers work as a ratio between two resistors, it doesn't matter in this situation what the resistance of these resistors = (pots) actually are.

Unknown said...

Woo! Thanks a lot Sebastian, especially for the lightning fast reply to my query. I had a lot of fun putting that circuit together, and I got some really nice sounds! the noises are a little faint, so I am either going to direct them into the computer or through an amp. My speaker may just be too small. I appreciate the documentation and clear schematic. Ill post a link when I get some documentation of my version with a few mods.

Sebastian Tomczak said...

Ben,
The output of the Arduino's sound would not be powerful enough to drive a speaker! Sorry, this is my fault for not mentioning it in the original post. Basically, either use a Piezo transducer if nothing else is available or use an amp and a speaker.

Cheers,
Seb

Anonymous said...

Hi sebastian
I've realize an arduino noise maker on a separate board and it's really nice :)
My idea was to build a small box for produce noise.
The 2 1m pot. are for the envelope, attak and decay ?
The pin 13 it's set as imput but no wire it's connect to it?
Will be nice have some led for visual feedback!
I'll like to send you some email for speak about some idea and try to develop someting toghether!?
Give me your email mine it's tonylight@email.it
Thankyou
best
ciao
tony

Anonymous said...

hi sebastian
I've some problem with the noise maker.
I've flash it on an atmega8 and seems to work, put the pitch pot seems to not have effect, the wave freq it's low, the pot works.
I've flash it on an atmega 168 and dosen't work only a blurp at start up! but the led on pin 13 blink, on the atmega8 no?
The connection seems ok, I've built it like an indipendet board from arduino, but connecting it to the arduino board I have the same result.
Thankyou for the help I really like your project we can speak by mail? so I can send you some photos of the prot.
thanks
ciao
tony
tonylight@email.it

tech.roberts said...

I have this working pretty well I believe. At least it makes great sounds and is driving the cat crazy. I still do not seem to get any discernible change to the sound by manipulating the pot that goes to the counter which outputs to pins 8, 9, and 10.
Also I was wondering about pin 13. In the code it has it as an input but I don't see any thing connected to it on the schematic. What am I missing?

K.Ellen. said...

Thank U for your info.
I'm a college student in Taiwan that is doing some experiments on ARDUINO now!!
Since I found the film on YOUTUBE I've been interest in NOISE MAKER like this!!
Oh~Your info really helps me a lot!
I'm gonna try it out,too!
Thank U ^_____^

Anonymous said...

@@
I couldn't see my comment?

Unknown said...

is it just me or is the photo different from the schematics?