inserito selezione della forma d'onda sinusoidale o quadra inserito genrazione dello spartito alla selezione '6' inserito doppio array note e durata inserito accento sulle note
Fork of amplificatore_bomboni_rev1 by
Sound-Generation.cpp
- Committer:
- pinofal
- Date:
- 2018-05-16
- Revision:
- 2:93bba36e0c06
- Child:
- 3:3895d3f389b5
File content as of revision 2:93bba36e0c06:
// Tested : NUCLEO F207ZG #include "mbed.h" // Definizione periferiche Serial pc(USBTX, USBRX); AnalogOut OutWave(PA_5); //DigitalOut DigitalWave(PA_5); DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); // definizione della frequenza delle note ottava centrale del pianoforte #define C 261.63 #define Cd 277.18 #define Db 277.18 #define D 293.66 #define Dd 311.13 #define Eb 311.13 #define E 329.63 #define F 349.23 #define Fd 369.99 #define Gb 369.99 #define G 392.9 #define Gd 415.3 #define Ab 415.3 #define A 440.0 #define Ad 466.16 #define Bb 466.16 #define B 493.18 // numero di campioni che compongono un periodo della sinusoide in Output sull'ADC #define SAMPLESINENUM 45// consigliabile avere multipli di 45 // parametri dell'onda coseno da generare #define PI (3.141592653589793238462) #define AMPLITUDE 32767 //(1.0) // x * 3.3V #define PHASE (PI/2) // 2*pi è un periodo #define OFFSET 32767 //(0x7FFF) // numero di note componenti la scala diatonica #define NUMTONE 120 // Output LED di diagnostica DigitalOut led(LED1); // ticker per la generazione dell'onda con DAC Ticker SampleOutTicker; // Buffer contenente la sinusoide da porre in output. unsigned short usaSine[SAMPLESINENUM]; // prototipo di funzione che genera i campioni della sinusoide da utilizzare per la generazione tramite DAC void CalculateSinewave(void); // carattere in arrivo dal PC volatile char cReadChar; // indice, nell'array, del campione da porre in output volatile int nSampleOutIndex; // contatore dei campioni in output sul DAC volatile int nSampleOutCount; // Periodo di generazione campioni in output DeltaT = T/NumSample double fDeltaT; // amplificazione per il dato da spedire sull'ADC volatile double fAmp; //volatile double fAmpNew; // flag per bloccare la generazione del segnale volatile bool bStop; // frequenza segnale da generare volatile double fFreq; // periodo della sinusoide da generare double fPeriod; double dDiatonic[NUMTONE]; //**************************** // Create the sinewave buffer //**************************** void CalculateSinewave(int nOffset, int nAmplitude, double fPhase) { // variabile contenente l'angolo in radianti double fRads; // indici per i cicli int nIndex; // passo in frequenza fissato dal numero di campioni in cui voglio dividere un periodo di sinusoide: DeltaF = 360°/NUMSAMPLE double fDeltaF; // angolo per il quale bisogna calcolare il valore di sinusoide: fAngle = nIndex*DeltaF double fAngle; fDeltaF = 360.0/SAMPLESINENUM; for (nIndex = 0; nIndex < SAMPLESINENUM; nIndex++) { fAngle = nIndex*fDeltaF; // angolo per il quale bisogna calcolare il campione di sinusoide fRads = (PI * fAngle)/180.0; // Convert degree in radian //usaSine[nIndex] = AMPLITUDE * cos(fRads + PHASE) + OFFSET; usaSine[nIndex] = nAmplitude * cos(fRads + fPhase) + nOffset; } } //********************************************** // Crea le frequenze delle note del pianoforte //********************************************** void CreateDiatonic() { int nTono; int nOttava; // ottava centrale = ottava 4 dDiatonic[4*12+0]=261.63; // C dDiatonic[4*12+1]=277.18; // C#/Db dDiatonic[4*12+2]=293.66; // D dDiatonic[4*12+3]=311.13; // D#/Eb dDiatonic[4*12+4]=329.63; // E dDiatonic[4*12+5]=349.23; // F dDiatonic[4*12+6]=369.99; // F#/Gb dDiatonic[4*12+7]=392.00; // G dDiatonic[4*12+8]=415.30; // G#/Ab dDiatonic[4*12+9]=440.00; // A dDiatonic[4*12+10]=466.16; // A#/Bb dDiatonic[4*12+11]=493.88; // B // dalla ottava 5 alla 9 for(nOttava=5; nOttava<9; nOttava++) { for(nTono=0; nTono<12; nTono++) { dDiatonic[(nOttava*12)+nTono]=dDiatonic[((nOttava-1)*12)+nTono]*2; } } // dalla ottava 0 alla 3 for(nOttava=3; nOttava>=0; nOttava--) { for(nTono=0; nTono<12; nTono++) { dDiatonic[(nOttava*12)+nTono]=dDiatonic[((nOttava+1)*12)+nTono]/2; } } } //*************************** // generazione sample da DAC //*************************** void SampleOut() { // se è stato inviato il comando Stop, non fare niente fino a nuovo comando if(bStop) { } else // se non è stato inviato il comando di bStop continua { // output del campione della forma d'onda OutWave.write_u16(usaSine[nSampleOutIndex]); // incrementa l'indice del campione in output, modulo NUMSAMPLE: se NUMSAMPLE è 360, nSampleOutIndex va da 0 a 359 nSampleOutIndex++; if(nSampleOutIndex >= SAMPLESINENUM) { nSampleOutIndex=0; } } } //******************* // Loop Principale //******************* int main() { // configura velocità della comunicazione seriale su USB-VirtualCom e invia messaggio di benvenuto pc.baud(921600); //921600 bps // messaggio di benvenuto pc.printf("\r\nHallo Amaldi Students - Exercise 9 \r\n"); pc.printf("\r\n*** SineWave Generation ***\r\n"); //inizializza variabili cReadChar = 0; nSampleOutIndex=0; nSampleOutCount=0; bStop=true; // test dei LED led1=1; //Verde wait_ms(1000); led1=0; led2=1; // Blu wait_ms(1000); led2=0; led3=1; //Rosso wait_ms(1000); led3=0; while(true) { // verifica se è arrivato un carattere dalla seriale del pc if(pc.readable()) { cReadChar = pc.getc(); // Read hyperterminal // genera la nota corrispondente al carattere ricevuto switch(cReadChar) { //DO case 'c': case 'C': { fFreq=261.63;// frequenza della sinusoide DO da generare pc.printf("\n\r--- Generazione DO = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; // RE case 'd': case 'D': { fFreq=293.66;// frequenza della sinusoide RE da generare pc.printf("\n\r--- Generazione RE = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; // RE#/MIb case 'm': case 'M': { fFreq=311.13; pc.printf("\n\r--- Generazione Mib = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; case 'e': case 'E': { fFreq=329.63; // frequenza della sinusoide MI da generare pc.printf("\n\r--- Generazione MI = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; case 'f': case 'F': { fFreq=349.23;// frequenza della sinusoide FA da generare pc.printf("\n\r--- Generazione FA = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; // SOL case 'g': case 'G': { fFreq=392.0; pc.printf("\n\r--- Generazione SOL = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; // LA case 'a': case 'A': { fFreq=440.0; // frequenza della sinusoide LA da generare pc.printf("\n\r--- Generazione LA = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; //SI case 'b': case 'B': { fFreq=493.88;// frequenza della sinusoide SI da generare pc.printf("\n\r--- Generazione SI = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; // pausa case ' ': { bStop=true; pc.printf("\n\r--- Generation Stopped ---\n\r"); } break; default: { bStop=true; // se la nota non è riconosciuta blocca la generazione pc.printf("\n\r--- Wrong Tone ---\n\r"); } break; } // switch (cReadChar) // genera la frequenza relativa alla nota che è stata selezionata fAmp = 0.1; // coefficiente per il quale viene moltiplicato l'ampiezza massima fDeltaT = 1.0/(fFreq*SAMPLESINENUM); CalculateSinewave(32767, (32767*fAmp), (PI/2.0)); // generazione della sinusoide con valori nominali SampleOutTicker.attach(&SampleOut,fDeltaT); // avvia output della sinusoide per generazione } else // se non è stato premuto nessun tasto { } } /******* START ONDA DIGITALE FUNZIONA ***** led1=1; led2=1; led3=1; while(true) { DigitalWave=0; //wait_us(2024); //SI //wait_us(2551); //SOL wait_us(1515); //MI DigitalWave=1; wait_us(1515); } ****** END ONDA DIGITALE FUNZIONA ******/ }