Demo: Sine Generator with CORDIC Algo in single cog

ReinhardReinhard Posts: 254
edited 2011-12-16 - 13:06:06 in Propeller 1
Hi,
I found this CORDIC Algo years ago in webspace,
saddly I do not remember the origin
// Cordic in 32 bit signed fixed point math
// generate approx. 200 Hz Sine and Cosine (in parallel !)
// Sine signal out on P0 via RC Lowpass 
// signal is a little bit strange in negative wave
// have now not found the reason

// main loop can be optimized

// propeller-elf-gcc -mcog -Os -o Cordic_sin.elf  main.c 
// need 808 Byte CogRam

#include <propeller.h>

#define cordic_1K 0x26DD3B6A
#define half_pi 0x6487ED51
#define CORDIC_NTAB 32

#define P0 1<<0
#define CRTMODE (1<<28) + (1<<27) + 0  // DUTY SINGLE ENDED


int cordic_ctab [] = {0x3243F6A8, 0x1DAC6705, 0x0FADBAFC, 0x07F56EA6, 
                      0x03FEAB76, 0x01FFD55B, 0x00FFFAAA, 0x007FFF55, 
                      0x003FFFEA, 0x001FFFFD, 0x000FFFFF, 0x0007FFFF, 
                      0x0003FFFF, 0x0001FFFF, 0x0000FFFF, 0x00007FFF, 
                      0x00003FFF, 0x00001FFF, 0x00000FFF, 0x000007FF, 
                      0x000003FF, 0x000001FF, 0x000000FF, 0x0000007F, 
                      0x0000003F, 0x0000001F, 0x0000000F, 0x00000008, 
                      0x00000004, 0x00000002, 0x00000001, 0x00000000, };
////////////////////////////////////////////////////////////////////////////////
// it is amazing, this shifts and adds produce a sine function 
////////////////////////////////////////////////////////////////////////////////
void cordic(int theta, int *s, int *c, int n)
{
  int k, d, tx, ty, tz;
  int x=cordic_1K,y=0,z=theta;
  for (k=0; k<n; ++k)
  {
    d = z>>31;
    tx = x - (((y>>k) ^ d) - d);
    ty = y + (((x>>k) ^ d) - d);
    tz = z - ((cordic_ctab[k] ^ d) - d);
    x = tx; y = ty; z = tz;
  }  
  *c = x; // cosine
  *s = y; // sine
}
////////////////////////////////////////////////////////////////////////////////
void main()
{
    int j ,k;
    int s,c;
    int i;  

    DIRA |= P0;                            
    CTRA = CRTMODE;    

LOOP:
    j=0;
    // 0 .. PI/2 in 50 steps  
    for(i=0;i<50;i++)
    {
        cordic(j, &s, &c, 32);
        FRQA = s+1;      // cordic result = 0xFFFFFFFF at angle = 0 ?? simple workaround 
        j += 0x0202b7f2; // PI/2 = 0x6487ED51 | : 50 = 0x0202B7F2
    } 
    k=j;
    j=0;
    // PI/2 ... PI in 50 steps
    for (i=0;i<50;i++)
    {
        cordic(k-j, &s, &c, 32);
        FRQA = s+1;
        j += 0x0202b7f2; 
    }
    j=0;
    // PI ... 3PI/2 in 50 steps
    for (i=0;i<50;i++)
    {
        cordic(j, &s, &c, 32);
        FRQA = s+1;
        j += 0x0202b7f2; 
    }
    k=j;
    j=0;
    // 3PI/2 ... 2PI in 50 steps
    for (i=0;i<50;i++)
    {
        cordic(k-j, &s, &c, 32);
        FRQA = s+1;
        j += 0x0202b7f2; 
    }
    
    goto LOOP; 
}

Comments

  • hello forists
    a long time has passed since my last post. I am retired now and have time to polish up my old things.
    The Cordic Algo now generates a clean sine / cosine.
    Digital signal processing with the P1 and C I still find very interesting.
    Enclosed also an application for the physical modeling of musical instruments. This is another approach to creating synthetic sounds in addition to the FM modulation, which have already been implemented in SPIN and the subtractive synthesis as used in the Moog. It simulates a vibrating (guitar) string. The application is for that
    Propeller demo board designed.
    Have fun, Reinhard.
  • Thanks for the update! Will try it out this weekend.
    Infernal Machine
  • ReinhardReinhard Posts: 254
    edited 2019-05-17 - 17:00:27
    I have made a few small changes in the file propPluckedString.c
    Commented in the source code.

    In the folder 'morecogs' is a first attempt with several parallel cogs, all at the same
    Work output. This should correspond to a summer in analog technology. However, this experiment is not yet fully operational.

    The goal is another kind of synthesizer.
  • If you want to hear how it sounds under LINUX soundcard:
    unzip the attachment in any folder
    from LINUX - terminal compile g++ -Wall -o zupf zupf.cpp
    run ./zupf_examples_2.sh
  • Plucked string now runs in a separate cog. There are also some synthesizer effects possible. It will not reach the quality that different synths have here in the forum. It's a completely different kind of sound synthesis, and that's what I'm concerned with in the first place. I thought, I really have to learn the assembler. But it goes in C.
    (asm I still want to learn)
Sign In or Register to comment.