So I'm like working on my dronesizer, and I'm like not getting so far ahead as I like to, but like, I wanna show it anyways. So I've made a little movie:
Basically it is a resistor ladder digital to analog converter, check out the R2R DAC if you want to build one. I added LED's as well. I've also added 6 potentiometers. Just do this 6 times
It's as easy as that. Now I need to add more sound options and tighten the void loop() function because it's dead slow right now.
//audio out variables
float TEMP= 0.0;
#define SINC_LENGTH 32
float sinC[3][SINC_LENGTH] = {
{//sinus
0.59754515,0.69134176,0.7777851,0.8535534,0.9157348,0.96193975,0.9903926,1.0,0.9903927,0.9619398,0.9157348,0.8535534,0.77778506,0.69134164,0.597545,0.49999985,0.40245464,0.30865806,0.22221464,0.14644638,0.08426499,0.03806007,0.009607285,0.0,0.009607464,0.038060457,0.08426553,0.14644706,0.22221544,0.30865896,0.4024556,0.5000008, }
,
{//saw
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }
,
{//tri
0.03125,0.0625,0.09375,0.125,0.15625,0.1875,0.21875,0.25,0.28125,0.3125,0.34375,0.375,0.40625,0.4375,0.46875,0.5,0.53125,0.5625,0.59375,0.625,0.65625,0.6875,0.71875,0.75,0.78125,0.8125,0.84375,0.875,0.90625,0.9375,0.96875,1.0, }
};
int incomingByte = 0; // for incoming serial datar
int pin0val =0;
enum waveFormType {
SIN, SQUARE,TRI, };
/*
float vol1=1.0;
float vol2=1.0;
float vol3=1.0;
float vol4=1.0;*/
float globalHz1 =0.001;
float oscCount1=0;
float globalHz2 =0.001;
float oscCount2=0;
float globalHz3 =0.001;
float oscCount3=0;
float LFOHz =0.001;
float lfoCount=0;
int type=0;
void setup()
{
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
Serial.begin(9600);
randomSeed(analogRead(0));
//Timer2 setup This is the audio rate timer, fires an interrupt at 15625 Hz sampling rate
TIMSK2 = 1<<<SINC_LENGTH)
oscCount1=0;
oscCount2+=globalHz2;
if(oscCount2>SINC_LENGTH)
oscCount2=0;
oscCount3+=globalHz3;
if(oscCount3>SINC_LENGTH)
oscCount3=0;
lfoCount+=LFOHz;
if(LFOHz>SINC_LENGTH)
LFOHz=0;
}
void calculateHz(float in,float detune1, float detune2)
{
globalHz1 = ((440 * pow(2.0,(in-69.0)/12.0))/1562.50);
globalHz2 = (440 * pow(2.0,(detune1-69.0)/12.0))/1562.50;
globalHz3 = (440 * pow(2.0,(detune2-69.0)/12.0))/1562.50;
/*
Serial.print(" ");
Serial.print(globalHz1*100000, DEC);
Serial.print(" ");
Serial.print(globalHz2*100000, DEC);
Serial.print(" ");
Serial.print(globalHz3*100000, DEC);
*/
}
void loop()
{
LFOHz = (analogRead(3)/(SINC_LENGTH*10.0));
type=analogRead(5)/51;// 20 modes
float note = ((analogRead(0)/1024.0)*100.0);
calculateHz(note,note-(((analogRead(1)/1024.0)*2.0)-1.0),note-(((analogRead(2)/1024.0)*2.0)-1.0));
/*
Serial.println("vol ");
Serial.print(vol,DEC);
Serial.println(" LFOHz");
Serial.print(LFOHz,DEC);
Serial.print("analog 1: ");
Serial.print( analogRead(1),DEC);
Serial.print("___ analog 2: ");
Serial.print( analogRead(2),DEC);
Serial.print(" type ");
Serial.print(type);
Serial.print(" Note ");
Serial.print((int)(note) );
Serial.println(" ");
*/
}
5 Comments
made some serious code updates, adding them to a comment here until I write a new post!
//audio out variables
#define SINC_LENGTH 32
float sinC[4][SINC_LENGTH] = {
{//sinus
0.59754515,0.69134176,0.7777851,0.8535534,0.9157348,0.96193975,0.9903926,1.0,0.9903927,0.9619398,0.9157348,0.8535534,0.77778506,0.69134164,0.597545,0.49999985,0.40245464,0.30865806,0.22221464,0.14644638,0.08426499,0.03806007,0.009607285,0.0,0.009607464,0.038060457,0.08426553,0.14644706,0.22221544,0.30865896,0.4024556,0.5000008 }
,
{//square
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
,
{//saw
0.03125,0.0625,0.09375,0.125,0.15625,0.1875,0.21875,0.25,0.28125,0.3125,0.34375,0.375,0.40625,0.4375,0.46875,0.5,0.53125,0.5625,0.59375,0.625,0.65625,0.6875,0.71875,0.75,0.78125,0.8125,0.84375,0.875,0.90625,0.9375,0.96875,1.0 }
,
{//tri
0.0625,0.125,0.1875,0.25,0.3125,0.375,0.4375,0.5,0.5625,0.625,0.6875,0.75,0.8125,0.875,0.9375,1.0,0.9375,0.875,0.8125,0.75,0.6875,0.625,0.5625,0.5,0.4375,0.375,0.3125,0.25,0.1875,0.125,0.0625,0.0 }
};
float note =50;
float TEMP= 0.0;
int oldKnobs[6] ={
0,0,0,0,0,0};
int tempKnobs[6] ={
0,0,0,0,0,0};
enum waveFormType {
SIN, SQUARE,SAW,TRI, };
float globalHz1 =0.001;
float oscCount1=0;
float globalHz2 =0.001;
float oscCount2=0;
float globalHz3 =0.001;
float oscCount3=0;
float LFOHz =0.001;
float lfoCount=0;
int type=0;
void setup()
{
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
Serial.begin(9600);
OCR2A = 127;
sei(); // global interrupt enable
//Timer2 setup This is the audio rate timer, fires an interrupt at 15625 Hz sampling rate
TIMSK2 = 1<
TCCR2A = 2; // CTC mode, counts up to 127 then resets
TCCR2B = 0<
}
// timer 2 is audio interrupt timer
ISR(TIMER2_COMPA_vect)
{
OCR2A = 127;
oscillator();
}
//output to audio
void aWrite(byte i)
{
PORTB = PORTB & B000000;
PORTB = PORTB | i;
}
void oscillator()
{
switch(type)
{
case 0:
{
TEMP = (sinC[SIN][(int)oscCount1] );
TEMP += (sinC[SIN][(int)oscCount2] );
TEMP += (sinC[SIN][(int)oscCount3]);
if(LFOHz!=0.0)
TEMP *= (sinC[SIN][(int)lfoCount]);
break;
}
case 1:
{
TEMP = (sinC[SIN][(int)oscCount1] );
TEMP += (sinC[SIN][(int)oscCount2]);
break;
}
case 2:
{
TEMP = (sinC[SIN][(int)oscCount1] );
TEMP += (sinC[SIN][(int)oscCount2] );
TEMP += (sinC[SIN][(int)oscCount3] );
break;
}
case 3:
{
TEMP = (sinC[TRI][(int)oscCount1] );
TEMP += (sinC[TRI][(int)oscCount2] );
TEMP += (sinC[TRI][(int)oscCount3] );
if(LFOHz!=0.0)
TEMP *= (sinC[SIN][(int)lfoCount] );
break;
}
case 4:
{
TEMP = (sinC[TRI][(int)oscCount1] );
TEMP += (sinC[TRI][(int)oscCount2] );
break;
}
case 5:
{
TEMP = (sinC[SIN][(int)oscCount1] );
if(LFOHz!=0.0)
TEMP *= (sinC[SIN][(int)lfoCount] );
break;
}
case 6:
{
TEMP = (sinC[TRI][(int)oscCount1] );
if(LFOHz!=0.0)
TEMP *= (sinC[TRI][(int)lfoCount] );
break;
}
case 7:
{
TEMP = (sinC[SQUARE][(int)oscCount1] );
if(LFOHz!=0.0)
TEMP *= (sinC[SQUARE][(int)lfoCount] );
break;
}
case 8:
{
TEMP = (sinC[SQUARE][(int)oscCount1] );
TEMP -= (sinC[SQUARE][(int)oscCount2] );
TEMP += (sinC[SIN][(int)oscCount3] );
break;
}
case 9:
{
TEMP = (sinC[SIN][(int)oscCount1] );
TEMP -= (sinC[TRI][(int)oscCount2] );
TEMP += (sinC[SIN][(int)oscCount3] );
break;
}
case 10:
{
TEMP = (sinC[SAW][(int)oscCount1] );
TEMP += (sinC[SAW][(int)oscCount2] );
TEMP += (sinC[SAW][(int)oscCount3] );
break;
}
case 11:
{
TEMP = (sinC[SAW][(int)oscCount1] );
TEMP += (sinC[SAW][(int)oscCount2] );
TEMP -= (sinC[SAW][(int)oscCount3] );
break;
}
case 12:
{
TEMP = (sinC[SAW][(int)oscCount1] );
TEMP += (sinC[SAW][(int)oscCount2] );
TEMP -= (sinC[SAW][(int)oscCount3] );
if(LFOHz!=0.0)
TEMP *= (sinC[SAW][(int)lfoCount] );
break;
}
case 13:
{
TEMP = (sinC[SAW][(int)oscCount1] );
TEMP += (sinC[SAW][(int)oscCount2] );
TEMP -= (sinC[SAW][(int)oscCount3] );
if(LFOHz!=0.0)
TEMP *= (sinC[SAW][(int)lfoCount] );
break;
}
case 14:
{
TEMP = (sinC[TRI][(int)oscCount1] );
TEMP += (sinC[TRI][(int)oscCount2] );
TEMP -= (sinC[TRI][(int)oscCount3] );
if(LFOHz!=0.0)
TEMP *= (sinC[TRI][(int)lfoCount] );
break;
}
default:
{
TEMP = (sinC[SQUARE][(int)oscCount1] );
TEMP += (sinC[SQUARE][(int)oscCount2] );
TEMP += (sinC[SQUARE][(int)oscCount3] );
if(LFOHz!=0.0)
TEMP *= (sinC[SIN][(int)lfoCount] );
break;
}
}
aWrite((byte)((TEMP)*24)); //write to output
oscCount1+=globalHz1;
if(oscCount1>SINC_LENGTH)
oscCount1=0;
oscCount2+=globalHz2;
if(oscCount2>SINC_LENGTH)
oscCount2=0;
oscCount3+=globalHz3;
if(oscCount3>SINC_LENGTH)
oscCount3=0;
/*lfoCount+=LFOHz; //WTF WHERE I THINKING HERE ????
if(LFOHz>SINC_LENGTH)
LFOHz=0;
*/
lfoCount+=LFOHz;
if(lfoCount>SINC_LENGTH)
lfoCount=0;
}
void loop()
{
tempKnobs[0] =analogRead(0);
tempKnobs[1] =analogRead(1);
tempKnobs[2] =analogRead(2);
tempKnobs[3] =analogRead(3);
tempKnobs[4] =analogRead(4);
tempKnobs[5] =analogRead(5);
if(tempKnobs[0]!=oldKnobs[0])
{
//note = ((tempKnobs[0]/1024.0)*100.0);
//globalHz1 = ((440 * pow(2.0,(note-69.0)/12.0))/1562.50);
globalHz1 = ((tempKnobs[0]/1024.0)*1.70);
oldKnobs[0]=tempKnobs[0];
globalHz2 =globalHz1+ (((tempKnobs[1]/1024.0)*.25)-0.125);
globalHz3 =globalHz1+ (((tempKnobs[2]/1024.0)*.25)-0.125);
}
if(tempKnobs[1]!=oldKnobs[1])
{
globalHz2 =globalHz1+ (((tempKnobs[1]/1024.0)*.25)-0.125);
oldKnobs[1]=tempKnobs[1];
}
if(tempKnobs[2]!=oldKnobs[2])
{
globalHz3 =globalHz1+ (((tempKnobs[2]/1024.0)*.25)-0.125);
oldKnobs[2]=tempKnobs[5];
}
if(tempKnobs[3]!=oldKnobs[3])
{
LFOHz=((tempKnobs[3]/1024.0)*0.4);
oldKnobs[3]=tempKnobs[3];
}
if(tempKnobs[4]!=oldKnobs[4])
{
oldKnobs[4]=tempKnobs[4];
}
if(tempKnobs[5]!=oldKnobs[5])
{
type=tempKnobs[5]/51;// 20 modes
oldKnobs[5]=tempKnobs[5];
}
}
Cool.
This actually inspired me to get my own arduino and coding some simple audio processing.
So I just wanted to say thanks!
//PT
Awesome, great to inspire!
Hi!
Today I’ve tried to make my own dronesizer with your code and instructions but something is wrong and… I don’t know what!!
I want to use your second code (your comment), but there is some strange chars on it….
I would be grateful if you could send me your arduino project by mail and a brief drawing of the connections (perhaps I’m doing something wrong …)
Thanks in advance!
Oh! I have also a blog about noise music but… in spanish… !!
sadly, your code wont run as is….I think when you pasted it into your blog it lost characters or had some scrambled.
its a shame as It looks great!
Post a Comment