Multiple sin wave synthesizer. Output on the DA port.

Dependencies:   mbed

sintone.cpp

Committer:
titanium
Date:
2019-07-18
Revision:
3:6c77b5c7510f
Parent:
2:82a0131e3c0e

File content as of revision 3:6c77b5c7510f:

/* sinetone --multiple sin wave generator */
/* copyright Toshihiro Matsui, IISEC, 2018 */
/* Any use/modification/copy of this program is granted to anyone
   as long as the above copyright is maintained*/

#include <mbed.h>
#define samplerate 16000
#define MAXFREQS 10

Serial pc(USBTX, USBRX);
Ticker tick1;
PwmOut pwm1(p21);
AnalogOut da1(p18);

// Frequencies of A, A#, B, C, C#, D, D#, E, F, F#, G, G#, totally 12
const int scalefreqs[12*4]={
        220, 233, 247, 262, 277, 293, 311, 330, 349, 370, 392, 415,
        440, 466,494,523,554,587,622,659,698,740,784,830,
        880,932,987,1046,1109,1175,1245,1319,1397,1480,1568,1661,
        1760, 1865, 1976, 2093, 2218, 2349, 2489, 2637, 2793, 2960
        };
const int chromatics[7]={0,2,3,5,7,8,10};
signed char bytesintab[samplerate];
int  freqlist[MAXFREQS];
int  seqlist[MAXFREQS]={0};
int  maxfreqs=0;

void make_sintab(int count) {
    int i;
    for (i=0; i<count; i++) {
        bytesintab[i]=sin( 2.0 * 3.141592 *((float) i)/((float)samplerate)) *120;
        }    }

void gentone() {
    float outval=0;
    int i;
    for (i=0; i<maxfreqs; i++) {
        outval += bytesintab[seqlist[i]];
        seqlist[i] += freqlist[i];
        seqlist[i] = seqlist[i] % samplerate; //wrap around at 160000
        }        
    da1.write((outval/(256.0*maxfreqs))+0.5); }

void setfreq(const int tone, const int scale) {
    freqlist[tone]=scalefreqs[scale];
    seqlist[tone]=0; }

main() {
    int ch, chord=0, base=0, sharp=0, tone=0, i;
    make_sintab(samplerate);    setfreq(0,0);    maxfreqs=1;
    tick1.attach(&gentone, 1.0/(float)samplerate);
    while (1) {
      ch=pc.getc();
      /* 1..7 changes chord (major, minor, 7th, maj7)*/
      /* a..l changes the base */
      /* # changes to sharp, % changes to flat (plain) ab*/
      if ('a'<=ch && ch<='u') {
        if (ch<='g') base=0;
        else if (ch<='n') { base=1; ch=ch-7;}
        else { base=2; ch=ch-14;}
        tone=chromatics[ch-'a']+base*12+sharp;
        setfreq(0, tone);
        if (chord<=1) maxfreqs=1;
        else if (chord==2) { setfreq(1, tone+7); maxfreqs=2;} /*add 5th*/
        if (chord==3) { setfreq(1, tone+4); setfreq(2, tone+7);  maxfreqs=3;} /*add major 3rd*/
        if (chord==5) { setfreq(1, tone+3); setfreq(2, tone+7); maxfreqs=3;} /*add minor 3rd*/
        if (chord==7) { setfreq(1, tone+4); setfreq(2, tone+7); setfreq(3, tone+10); maxfreqs=4; }/*7th*/
        if (chord==8) { setfreq(1, tone+4); setfreq(2, tone+7); setfreq(3, tone+11); maxfreqs=4; }/*maj7th*/
        }
      if ('1'<=ch && ch<='8') chord=ch-'0'; 
      if (ch=='#') sharp=1;
      if (ch=='%') sharp=0;
      pc.printf("octave=%d tone=%c%c chord=%d freqs=", base, ch, (sharp?'#':' '), chord);
      for (i=0; i<maxfreqs; i++) pc.printf("%d ", freqlist[i]);
      pc.printf("\r\n");}
    };