Showing posts with label Generator. Show all posts
Showing posts with label Generator. Show all posts

Tuesday, 29 July 2014

Dub && Wise Synth


*some decoupling capacitors 100nFclose to the analog pins should be added.




My initial intention was to create something focused for the soundsystem culture. This turned out to be much more difficult than i thought .
Dub siren/Elec tom synth/And oscilattor+ MAD Lfos (some trying to recreate some of the sounds in a synare that Jah Shaka got us all used to)...All this synthesized on the fly with the help of some wavetables (all created during the start up)
.
Pots for :
-Oscillator wave selector ( Sine,cosine  Saw, Inverted Saw, Square wave, triangle and 1 extra slots for now )
-LFO rate
-LFO modulator type select ( Any of the above tables, plus a few more specific and tailored options)
-Attack
-Release
* Both attack and release can interact with the LFO
- Mode selector ( Dub Siren, Sound effects " a la Synare", Elec-Tom synth)

This video is just as an update on the proceedings.
Here i am using the Arduino Due.
Due to its complexity, i ended up re-writing the whole code from scratch and fresh to suit this specific idea.
Already started porting a similar idea to the chipKit DP32, and Pinguino and an Xmos version also soon to come, subject to availability of spare time.



Wednesday, 6 November 2013

Quick pictures update on ADSR

 Exp.attack at 0.4 and sustain level at 7/8 ( 20 Ms div)




A quick update to show that first try, worked as expected. Spent a few good hours in the process of starting to optimize the different building blocks id gathered, and make them interact. Tried to keep it as readable as possible and document the little quirks, and possible variations, references, etc in the implementation methods.
We have officially an ADSR with variable exponential attack, variable "decay-sustain ratio" ( allows both bypassing the sustain stage, and also looping/extending the sustain stage ), and variable duration/period... For now !


Next comes LFO's from all the wavetables available, simple filters, and start implementing simple convolution reverb. Lets see how far can i  "push the envelope" ( No pun intended).





Square wave and exp.attack at 0.5 ( .2 s Div )


Friday, 18 October 2013

Prime number generator with arduino

Prime number 1,370,795 from Wolfram Alpha's list

I had to share this Project !
Nick Gammon is a very helpful member on the Arduino forum , and always ready to share his knowledge and help/time .

http://www.gammon.com.au/forum/?id=12168&page=999
http://forum.arduino.cc//index.php?topic=192209.0



Monday, 30 September 2013

Symmetry of waves in wavetable generators and the differences and implications..


The reason why im sharing these wave table generators is because of the fact that some of the ones i found didnt comply with the symmetry of waveforms ( Take the above graph as the correct reference of how they should relate !).
Why is this so important ?! Hmmm, try a guess ?! * Ill leave it to the reader to guess why, as an exercise, as its quite obvious !
Instead they have the period of  the Sawtooth wave starting as 0, when it should be starting at the DC-offset value ( 2047 for a 12-bits DAC, for example).
So, it was starting at PI, instead of zero. Triangle wave were starting at 1.5 PI( which both differences are easy and dirty ways of doing it, but this time didnt satisfy my needs, where i need something correct according to the symmetry for interaction and calculation purposes.
So this was my quick solution to it. I hope to maybe improve on this as soon as i can spare a moment.
Also intend to  do a see-sawtooth ( with more decrement intermediate stages) generator.


// create the individual samples for our Sawtooth-wave table
void createSawTable()
{
  Serial.println(" ");
  Serial.println("Saw table");
  for(uint32_t nIndex = 0;nIndex < WAVE_SAMPLES;nIndex++)
  {
    // normalised to 12 bit range 0-4095
    nSawTable[nIndex] = nIndex * 8;  // == nIndex + (4096/512 == 8);because it   //  never reaches 512
    Serial.println(nSawTable[nIndex]);
  }
}
// create the individual samples for our triangle-wave table
void createTriangleTable()
{
  //Serial.println(" ");
  //Serial.println("triangle table");
  for (uint32_t nIndex = 0;  nIndex < WAVE_SAMPLES; ++ nIndex) 
  { 
    if( nIndex <=128 ){
      nTriangleTable[nIndex] = nIndex * 16 + 2047 ; //+offset
      //Serial.println(nTriangleTable[nIndex]);
      //Serial.println(nIndex);
    }
    else if(nIndex >128 && nIndex < 384 )
    {
      nTriangleTable[nIndex] = 4095-((nIndex-128)*16);
      //Serial.println(nTriangleTable[nIndex]);
      //Serial.println(nIndex);
    }
    else if (nIndex == 384){
      nTriangleTable[nIndex] = 0;
      //Serial.println(nTriangleTable[nIndex]);
      //Serial.println(nIndex);
    }     else if (nIndex > 384){       nTriangleTable[nIndex] = (nIndex-384)*16;        //Serial.println(nTriangleTable[nIndex]);       //Serial.println(nIndex);     }        } }
void createSq_WaveTable() {   Serial.println(" ");   Serial.println("Square Wave table");   for(uint32_t nIndex = 0;nIndex < WAVE_SAMPLES;nIndex++)   {     // despite using numbers directly here, keep in mind its related to     // WAVE_SAMPLES as a variable     // if(nIndex < (WAVE_SAMPLES/2))     if( nIndex <256 ){       nSq_WaveTable[nIndex] = 4095 ; //       Serial.println(nSq_WaveTable[nIndex]);     }     else if(nIndex >=256 && nIndex <= WAVE_SAMPLES )     {       nSq_WaveTable[nIndex] =0;       Serial.println(nSq_WaveTable[nIndex]);     }        } }

Quick-Benchmark on LUT / sine wavetable generation with DUE



During my research for my "secret" project i decided to benchmark sine wave and sine wave LOOK UP TABLE's generation, the different methods and approximations, both mathematically and methods for discrete time systems like uC's.

For research purposes, and initial development i have been actually using the Arduino Due, due to its ease of testing and debugging initial stages of ideas , for which the DAC helps a lot.
I been guessing already some limitations speed performance (considering what i want to achieve) in later stages, but for now it has been a brilliant tool.

As the ARM in the DUE was a new thing to me, and to shorten the time, i had to look around for some initial guidance regarding the registers/tmers and interrupts in order to get started.
In that sense Duane B.'s work and Groovuino's with their QUICK 'N' DIRTY synth were invaluable.
At the moment, im quite advanced, and it came to mind to use some "live" sine calculations for some other purposes other than the Pure-tone sinewave itself ( complex sinusoids and subsequent modulation, etc).
So  decided to benchmark both thei sinewavetable generation and a somewhat adapted version i used previously.
And using the millis() in Arduino, there was almost a halving of time taken to generate 512 samples of wavetable.
Duane's version took 27/28 Ms contrasting with 16/17 Ms.
Now, while this is not relevant for their synths, it is to me. Specially when im trying to squeeze as many cycles as i can already with the arduino Due, due to all the layers that the "easy way" places in between, massively contributing to the decrease in performance of speed/time.  :)
Its easy to see where the optimization is, slightly reducing the cycles needed !
Some surprises soon, and some more on this as well...

 Table_1 test code

#define WAVE_SAMPLES 512
long previousMillis = 0; 
// default int is 32 bit, in most cases its best to use uint32_t but for large arrays its better to use smaller
// data types if possible, here we are storing 12 bit samples in 16 bit ints
#define offset 2047 // In this case is the same as the Amplitude
uint16_t sin_data[WAVE_SAMPLES];
float w ;    // ψ
float yi ;
float phase;
int sign_samp;
int i;

void create2nd_sine (){
  // Serial.println(" ");
  // Serial.println("Sine table2");
  w=(2.0 * PI)/WAVE_SAMPLES;
  for (i = 0; i <= 511; i++)
  {
    yi= offset*sin(phase); // Offset is the same as the Amplitude
    phase=phase+w;
    sign_samp=offset+yi;     // dc offset translated for a 12 bit DAC
    sin_data[i]=sign_samp; // write value into array
    // Serial.println(i);
    // Serial.println(sin_data[i]);
  }
}
//

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly: 
  unsigned int result;
  unsigned long currentMillis = millis();
  create2nd_sine ();
  result=currentMillis - previousMillis;
  previousMillis = currentMillis;
  Serial.println(result);
}


 Table_2 test code


// Duane's
#define WAVE_SAMPLES 512
// default int is 32 bit, in most cases its best to use uint32_t but for large arrays its better to use smaller
// data types if possible, here we are storing 12 bit samples in 16 bit ints
uint16_t nSineTable[WAVE_SAMPLES];
long previousMillis = 0;  

void createSineTable()
{
  //   Serial.println(" ");
  //   Serial.println("Sine table");
  for(uint32_t nIndex = 0;nIndex < WAVE_SAMPLES;nIndex++)
  {
    // normalised to 12 bit range 0-4095
    nSineTable[nIndex] = (uint16_t)  (((1+sin(((2.0*PI)/WAVE_SAMPLES)*nIndex))*4095.0)/2);
    //  Serial.println(nIndex);
    //  Serial.println(nSineTable[nIndex]);
  }
}
//

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly: 
  unsigned int result;
  unsigned long currentMillis = millis();
  createSineTable();
  result=currentMillis - previousMillis;
  previousMillis = currentMillis;
  Serial.println(result);
}





For a more detailed explanation of a sinewave generator, and a few diff methods, check below link
(1) http://dubworks.blogspot.co.uk/p/blog-page.html

Sunday, 1 September 2013

Simple sine wave generator template in C


As i only used a limited amplitude on the sine wave generator for Arduino Due's DAC, im posting a template here that should help you make the necessary changes( someone asked me this).
This specific template code was written for C code in Codeblocks for Gcc, so you will have to be able to know the differences.

# include < stdio.h >
# include < stdlib.h >
# include < math.h >
# define n_points 32 //256 is ideal for microcontrollers or highers if youre computing complex sinusoids
int main ()
{
    float pi = 3.141592;
    float w ;    // ψ
    float yi ;
    float phase;
    int sign_samp;
    int sin_data[n_points];  // sine LUT Array
    int i;
    w= 2*pi;
    w= w/n_points;
    for (i = 0; i <= n_points; i++)
    {
        yi= 2047*sin(phase);
        phase=phase+w;
        sign_samp=2047+yi;     // dc offset translated for a 12 bit DAC
        //sign_samp+= b;         // Add adc value; Keep it at zero for pure sine
        sin_data[i]=sign_samp; // write value into array
        /*
        */
    }
    for (i = 0; i <= n_points; i++)
    {
        int k=sin_data[i];
        printf ("sine is %d\n", k);
        printf ("i is ... %d\n", i);
    }
    float x;
    printf ("Enter a number ... \n");
    scanf ("%f", &x); // keeps the debugging console on codeblocks open ;)
    return 0;
}





Sine plot with result of a 32 n_points as above using GNUmeric



Pseudo-code


"Two random variables were talking in a bar. They thought they were being discrete but I heard their chatter continuously "

(1) Signal Processing for Communications by Paolo Prandoni and Martin Vetterli
(2) http://dubworks.blogspot.co.uk/p/blog-page.html