Space / Mbed 2 deprecated SITAEL_Sound-Generation

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SITAEL_Sound-Generation.cpp Source File

SITAEL_Sound-Generation.cpp

00001 // Tested : NUCLEO F207ZG
00002 // Tested : NUCLEO L476RG
00003 #include "mbed.h"
00004 
00005 // Definizione periferiche
00006 Serial pc(USBTX, USBRX);
00007 //AnalogOut OutWave(PA_5); //F207ZG
00008 AnalogOut OutWave(PA_4); //L476RG
00009 DigitalOut DigitalWave(PA_1);
00010 DigitalOut led1(LED1);
00011 DigitalOut led2(LED2);
00012 DigitalOut led3(LED3);
00013 
00014 // definizione della frequenza delle note ottava centrale del pianoforte
00015 #define Z 100.00     // diagnostica
00016 #define C 261.63
00017 #define Cd 277.18
00018 #define Db 277.18
00019 #define D 293.66
00020 #define Dd 311.13
00021 #define Eb 311.13
00022 #define E 329.63
00023 #define F 349.23
00024 #define Fd 369.99
00025 #define Gb 369.99
00026 #define G 392.9
00027 #define Gd 415.3
00028 #define Ab 415.3
00029 #define A 440.0
00030 #define Ad 466.16
00031 #define Bb 466.16
00032 #define B 493.18
00033 
00034 
00035 
00036 
00037 
00038 
00039 // numero di campioni che compongono un periodo della sinusoide in Output sull'ADC
00040 #define SAMPLESINENUM   45// consigliabile avere  multipli di 45
00041 
00042 // parametri dell'onda coseno da generare
00043 #define PI        (3.141592653589793238462)
00044 #define AMPLITUDE 32767 //(1.0)    // x * 3.3V
00045 #define PHASE     (PI/2) // 2*pi è un periodo
00046 #define OFFSET    32767 //(0x7FFF)
00047 
00048 // numero di note componenti la scala diatonica
00049 #define NUMTONE 120
00050 
00051 // Output LED di diagnostica
00052 DigitalOut led(LED1);
00053 
00054 // ticker per la generazione dell'onda con DAC
00055 Ticker SampleOutTicker;
00056 
00057 // Buffer contenente la sinusoide da porre in output.
00058 unsigned short usaSine[SAMPLESINENUM];
00059 
00060 // prototipo di funzione che genera i campioni della sinusoide da utilizzare per la generazione tramite DAC
00061 void CalculateSinewave(void);
00062 
00063 // carattere in arrivo dal PC
00064 volatile char cReadChar=0;
00065 volatile char cOldReadChar=0;
00066  
00067 // indice, nell'array, del campione da porre in output
00068 volatile int nSampleOutIndex;
00069 // contatore dei campioni in output sul DAC
00070 volatile int nSampleOutCount;
00071 // Periodo di generazione campioni in output DeltaT = T/NumSample
00072 double fDeltaT;
00073 // amplificazione per il dato da spedire sull'ADC
00074 volatile double fAmp;
00075 //volatile double fAmpNew;
00076 // flag per bloccare la generazione del segnale
00077 volatile bool bStop;
00078 // frequenza segnale da generare
00079 volatile double fFreq;
00080 // periodo della sinusoide da generare
00081 double fPeriod;
00082 double dDiatonic[NUMTONE];
00083 
00084 //****************************
00085 // Create the sinewave buffer
00086 //****************************
00087 void CalculateSinewave(int nOffset, int nAmplitude, double fPhase)
00088 {
00089     // variabile contenente l'angolo in radianti
00090     double fRads;
00091     // indici per i cicli
00092     int nIndex;
00093     // passo in frequenza fissato dal numero di campioni in cui voglio dividere un periodo di sinusoide: DeltaF = 360°/NUMSAMPLE
00094     double fDeltaF;
00095     // angolo per il quale bisogna calcolare il valore di sinusoide: fAngle = nIndex*DeltaF
00096     double fAngle;
00097     
00098     fDeltaF = 360.0/SAMPLESINENUM;
00099     for (nIndex = 0; nIndex < SAMPLESINENUM; nIndex++) 
00100     {
00101         fAngle = nIndex*fDeltaF; // angolo per il quale bisogna calcolare il campione di sinusoide
00102         fRads = (PI * fAngle)/180.0; // Convert degree in radian
00103         //usaSine[nIndex] = AMPLITUDE * cos(fRads + PHASE) + OFFSET;
00104         usaSine[nIndex] = nAmplitude * cos(fRads + fPhase) + nOffset;
00105     }
00106 }
00107 
00108 
00109 //**********************************************
00110 // Crea le frequenze delle note del pianoforte
00111 //**********************************************
00112 void CreateDiatonic()
00113 {
00114     int nTono;
00115     int nOttava;
00116     
00117     // ottava centrale = ottava 4
00118     dDiatonic[4*12+0]=261.63;   // C
00119     dDiatonic[4*12+1]=277.18;   // C#/Db
00120     dDiatonic[4*12+2]=293.66;   // D
00121     dDiatonic[4*12+3]=311.13;   // D#/Eb
00122     dDiatonic[4*12+4]=329.63;   // E
00123     dDiatonic[4*12+5]=349.23;   // F
00124     dDiatonic[4*12+6]=369.99;   // F#/Gb
00125     dDiatonic[4*12+7]=392.00;   // G
00126     dDiatonic[4*12+8]=415.30;   // G#/Ab
00127     dDiatonic[4*12+9]=440.00;   // A
00128     dDiatonic[4*12+10]=466.16;  // A#/Bb
00129     dDiatonic[4*12+11]=493.88;  // B
00130     
00131     // dalla ottava 5 alla 9
00132     for(nOttava=5; nOttava<9; nOttava++)
00133     {
00134         for(nTono=0; nTono<12; nTono++)
00135         {
00136             dDiatonic[(nOttava*12)+nTono]=dDiatonic[((nOttava-1)*12)+nTono]*2;
00137         }
00138     }
00139     
00140     // dalla ottava 0 alla 3
00141     for(nOttava=3; nOttava>=0; nOttava--)
00142     {
00143         for(nTono=0; nTono<12; nTono++)
00144         {
00145             dDiatonic[(nOttava*12)+nTono]=dDiatonic[((nOttava+1)*12)+nTono]/2;
00146         }
00147     }
00148 }
00149 
00150 //***************************
00151 // generazione sample da DAC
00152 //***************************
00153 void SampleOut() 
00154 {
00155     // se è stato inviato il comando Stop, non fare niente fino a nuovo comando
00156     if(bStop)
00157     {
00158     }
00159     else // se non è stato inviato il comando di bStop continua
00160     {
00161         // output del campione della forma d'onda
00162         OutWave.write_u16(usaSine[nSampleOutIndex]);
00163         
00164         // incrementa l'indice del campione in output, modulo NUMSAMPLE: se NUMSAMPLE è 360, nSampleOutIndex va da 0 a 359
00165         nSampleOutIndex++;
00166         if(nSampleOutIndex >= SAMPLESINENUM) 
00167         {
00168             nSampleOutIndex=0; 
00169         }
00170         
00171     }
00172 }
00173 
00174 
00175 
00176 
00177 //*******************
00178 // Loop Principale
00179 //*******************  
00180 int main()
00181 {
00182     // configura velocità della comunicazione seriale su USB-VirtualCom e invia messaggio di benvenuto
00183     pc.baud(921600); //921600 bps
00184     
00185     
00186     // messaggio di benvenuto
00187     pc.printf("\r\nHallo \r\n");
00188     pc.printf("\r\n*** SineWave Generation ***\r\n");
00189     
00190     //inizializza variabili
00191     cReadChar = 0;
00192     nSampleOutIndex=0;
00193     nSampleOutCount=0;
00194     bStop=true;
00195     
00196     // test dei LED
00197     led1=1; //Verde
00198     wait_ms(1000);
00199     led1=0;
00200     led2=1; // Blu
00201     wait_ms(1000);
00202     led2=0;
00203     led3=1; //Rosso
00204     wait_ms(1000);
00205     led3=0;
00206     //+++++++++++++++++++++++++++++++++++ START Test ONDA DIGITALE ++++++++++++++++++++++++++++++++++++++
00207     /*
00208     led1=1;
00209     led2=1;
00210     led3=1;
00211     while(true)
00212     {
00213         DigitalWave=0;
00214         //wait_us(2024); //SI
00215         //wait_us(2551); //SOL
00216         wait_ms(300); //MI
00217         DigitalWave=1;
00218         wait_ms(300);   
00219     }
00220     */
00221     //+++++++++++++++++++++++++++++++++++ END Test ONDA DIGITALE +++++++++++++++++++++++++++++++++++++++++++++
00222     
00223     
00224     //+++++++++++++++++++++++++++++++++++ START Test ONDA ANALOGICA ++++++++++++++++++++++++++++++++++++++++++
00225     fFreq=20.0; // frequenza della sinusoide di test
00226     pc.printf("\n\r--- Generazione LA = %.2f Hz ampiezza nominale ---\n\r", fFreq);
00227     bStop = false;
00228     // genera la frequenza relativa alla nota che è stata selezionata
00229     fAmp = 0.3; // coefficiente per il quale viene moltiplicato l'ampiezza massima
00230     fDeltaT = 1.0/(fFreq*SAMPLESINENUM);
00231     CalculateSinewave(32767, (32767*fAmp), (PI/2.0)); // generazione della sinusoide con valori nominali
00232     SampleOutTicker.attach(&SampleOut,fDeltaT); // avvia output della sinusoide per generazione
00233     while(true){};
00234     //+++++++++++++++++++++++++++++++++++ END Test ONDA ANALOGICA ++++++++++++++++++++++++++++++++++++++++++++
00235     
00236     //+++++++++++++++++++++++++++++++++++ START Test ONDA ANALOGICA ++++++++++++++++++++++++++++++++++++++++++++++
00237     
00238     // variabile contenente l'angolo in radianti
00239     double fRads;
00240     // passo in frequenza fissato dal numero di campioni in cui voglio dividere un periodo di sinusoide: DeltaF = 360°/NUMSAMPLE
00241     double fDeltaF;
00242     // angolo per il quale bisogna calcolare il valore di sinusoide: fAngle = nIndex*DeltaF
00243     double fAngle;
00244     
00245     fFreq=10.0;// frequenza della sinusoide DO da generare
00246     pc.printf("\n\r--- Generazione frequenza = %.2f Hz ---\n\r", fFreq);
00247     
00248      
00249     nSampleOutIndex=0;
00250     while(true)
00251     {
00252      
00253         // output del campione della forma d'onda
00254         //OutWave.write_u16( 32767*cos(nSampleOutIndex/3.14));
00255         OutWave.write_u16( nSampleOutIndex);
00256         
00257         // incrementa l'indice del campione in output, modulo NUMSAMPLE: se NUMSAMPLE è 360, nSampleOutIndex va da 0 a 359
00258         nSampleOutIndex++;
00259         if(nSampleOutIndex >= 32768)
00260         {
00261             nSampleOutIndex =0;
00262         }
00263         
00264         wait_ms(10);
00265      }
00266     
00267     //+++++++++++++++++++++++++++++++++++ END Test ONDA ANALOGICA ++++++++++++++++++++++++++++++++++++++++++
00268     
00269     //+++++++++++++++++++++++++++++++++++ START Loop principale ++++++++++++++++++++++++++++++++++++++++++
00270     while(true)
00271     {     
00272         // verifica se è arrivato un carattere dalla seriale del pc
00273         if(pc.readable())
00274         //if (true)
00275         {
00276             cReadChar = pc.getc(); // Read hyperterminal  
00277             //cReadChar = 'C';
00278             // genera la nota corrispondente al carattere ricevuto
00279             switch(cReadChar)
00280             {
00281                 //DO
00282                 case 'c':
00283                 case 'C':
00284                 {
00285                     fFreq=261.63;// frequenza della sinusoide DO da generare
00286                     pc.printf("\n\r--- Generazione DO = %.2f Hz ampiezza nominale ---\n\r", fFreq);
00287                     bStop = false;
00288                 } break;
00289                 // RE
00290                 case 'd':
00291                 case 'D':
00292                 {
00293                     fFreq=293.66;// frequenza della sinusoide RE da generare
00294                     pc.printf("\n\r--- Generazione RE = %.2f Hz ampiezza nominale ---\n\r", fFreq);
00295                     bStop = false;
00296                 } break;
00297                 // RE#/MIb
00298                 case 'm':
00299                 case 'M':
00300                 {
00301                     fFreq=311.13;
00302                     pc.printf("\n\r--- Generazione Mib = %.2f Hz ampiezza nominale ---\n\r", fFreq);
00303                     bStop = false;
00304                 } break;
00305                 case 'e':
00306                 case 'E':
00307                 {
00308                     fFreq=329.63; // frequenza della sinusoide MI da generare
00309                     pc.printf("\n\r--- Generazione MI = %.2f Hz ampiezza nominale ---\n\r", fFreq);
00310                     bStop = false;
00311                 } break;
00312                 case 'f':
00313                 case 'F':
00314                 {
00315                     fFreq=349.23;// frequenza della sinusoide FA da generare
00316                     pc.printf("\n\r--- Generazione FA = %.2f Hz ampiezza nominale ---\n\r", fFreq);
00317                     bStop = false;
00318                 } break;
00319                 
00320                 // SOL
00321                 case 'g':
00322                 case 'G':
00323                 {
00324                     fFreq=392.0;
00325                     pc.printf("\n\r--- Generazione SOL = %.2f Hz ampiezza nominale ---\n\r", fFreq);
00326                     bStop = false;
00327                 } break;
00328                 // LA
00329                 case 'a':
00330                 case 'A':
00331                 {
00332                     fFreq=440.0; // frequenza della sinusoide LA da generare
00333                     pc.printf("\n\r--- Generazione LA = %.2f Hz ampiezza nominale ---\n\r", fFreq);
00334                     bStop = false;
00335                 } break;
00336                 //SI
00337                 case 'b':
00338                 case 'B':
00339                 {
00340                     fFreq=493.88;// frequenza della sinusoide SI da generare
00341                     pc.printf("\n\r--- Generazione SI = %.2f Hz ampiezza nominale ---\n\r", fFreq);
00342                     bStop = false;
00343                 } break;
00344                 
00345                 // pausa
00346                 case ' ':
00347                 {
00348                     bStop=true;
00349                     pc.printf("\n\r--- Generation Stopped ---\n\r");
00350                 } break;
00351                 default:
00352                 {
00353                     bStop=true; // se la nota non è riconosciuta blocca la generazione
00354                     pc.printf("\n\r--- Wrong Tone ---\n\r");
00355                 } break;  
00356             } // switch (cReadChar)
00357             
00358             // genera la frequenza relativa alla nota che è stata selezionata
00359             fAmp = 1.0; // coefficiente per il quale viene moltiplicato l'ampiezza massima
00360             fDeltaT = 1.0/(fFreq*SAMPLESINENUM);
00361             CalculateSinewave(32767, (32767*fAmp), (PI/2.0)); // generazione della sinusoide con valori nominali
00362             SampleOutTicker.attach(&SampleOut,fDeltaT); // avvia output della sinusoide per generazione
00363        }
00364         else // se non è stato premuto nessun tasto diagnostica
00365         {
00366            
00367         } 
00368      }   
00369  
00370    
00371 }