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

Thursday 19 September 2013

Tuesday 10 September 2013

Cryptography and primes


Cryptography and primes come across, as two of my interests...
Im thinking about putting some basic codes as templates together as exercises... Maybe even do some basic RSA, eventually ?!
For now, some links

http://books.google.co.uk/books/about/In_Code.html?id=kyO7QgAACAAJ

Friday 6 September 2013

PRIME Prime





I am amazed i didnt noticed this before.
Regards the bounded gap of prime numbers and  twin prime conjecture, a subject much loved by the great Erdős.
For hundreds of years, mathematicians have speculated that there are infinitely many twin prime pairs. In 1849, French mathematician Alphonse de Polignac extended this conjecture to the idea that there should be infinitely many prime pairs for any possible finite gap, not just 2.
In April this year, a lecturer at the University of New Hampshire named Yitang Zhang surprised everyone when his new paper arrived in the inbox of Annals of Mathematics, a prominent journal.
With it, Zhang has broken through this barrier. His paper shows that there is some number N smaller than 70 million such that there are infinitely many pairs of primes that differ by N. No matter how far you go into the deserts of the truly gargantuan prime numbers — no matter how sparse the primes become — you will keep finding prime pairs that differ by less than 70 million.
Terence Tao, Fields medal in 2006,  has proposed a joint collaboration in the polymath project to lower that number,

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