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