Test CBS-GPIO
Dependencies: mbed
Fork of Amplificatore_bomboni_rev2 by
Sound-Generation.cpp
- Committer:
- pinofal
- Date:
- 2018-05-31
- Revision:
- 6:be1561f8c63c
- Parent:
- 5:413f85118dd5
File content as of revision 6:be1561f8c63c:
// Tested : NUCLEO F207ZG #include "mbed.h" #include<stdlib.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 durata note #define SEMIBREVE 1000 // durata della semibreve in microsecondi #define MINIMA SEMIBREVE/2 #define SEMIMINIMA MINIMA/2 #define CROMA SEMIMINIMA/2 #define SEMICROMA CROMA/2 #define BISCROMA SEMICROMA/2 #define SEMIBISCROMA BISCROMA/2 // definizione della frequenza delle note ottava centrale del pianoforte #define m 0 #define C1 261.63 #define C1d 277.18 #define D1b 277.18 #define D1 293.66 #define D1d 311.13 #define E1b 311.13 #define E1 329.63 #define F1 349.23 #define F1d 369.99 #define G1b 369.99 #define G1 392.9 #define G1d 415.3 #define A1b 415.3 #define A1 440.0 #define A1d 466.16 #define B1b 466.16 #define B1 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; volatile char CReadMusic; // 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]; // tipo di suono da generare: 0=Sine, 1= Square char cSoundWave; // tipo di spartito selezionato char cScore; //**************************** // Create the sinewave buffer // // ATTENZIONE ----- SAREBBE MEGLIO CAMBIARE IL NOME DELLA FUNZIONE in CalculateWave[] !!!!! ---- //**************************** 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; // a seconda della selezione, genera una diversa forma d'onda // ATTENZIONE ----- SAREBBE MEGLIO CAMBIARE IL NOME DELL'ARRAY in usaWave[] !!!!! ---- if(cSoundWave=='0') { // genera forma d'onda sinusoidale 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; } } else { // genera forma d'onda quadra. for (nIndex = 0; nIndex < SAMPLESINENUM/2; nIndex++) { usaSine[nIndex] = nAmplitude*(1.0)+ nOffset; } for (nIndex = SAMPLESINENUM/2; nIndex < SAMPLESINENUM; nIndex++) { usaSine[nIndex] = nAmplitude*(-1.0)+ nOffset; } } } //*************************** // 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() { // numero di note che compongono il brano #define SYMPHONYN5DURATION 10 // numero di note che compongono il brano // note del brano float fNoteSymphonyN5 [SYMPHONYN5DURATION] = {m, G1, G1, G1, E1b, m, F1, F1, F1, D1}; // durata delle note del brano float fLengthSymphonyN5[SYMPHONYN5DURATION] ={CROMA, CROMA, CROMA, CROMA, MINIMA, CROMA, CROMA, CROMA, CROMA, MINIMA}; // indice per i cicli int nIndex; // 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*** Amaldi Vs Beethoven ***\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; pc.printf("\r\n*** Select SoundWave ***\r\n"); pc.printf("\r\n> 0: Sine ***\r\n"); pc.printf("\r\n> 1: Square ***\r\n"); while(pc.readable()) { // acquisisce il suono da generare cSoundWave = pc.getc(); } pc.printf("\r\n*** Select Score ***\r\n"); pc.printf("\r\n> 0: Lalala land ***\r\n"); pc.printf("\r\n> 1: Minuetto ***\r\n"); pc.printf("\r\n> 2: Prima invenzione ***\r\n"); pc.printf("\r\n> 3: Nona sinfonia ***\r\n"); pc.printf("\r\n> 4: When the saint go marching in ***\r\n"); pc.printf("\r\n> 5: Preludio ***\r\n"); pc.printf("\r\n> 6: Quinta Sinfonia ***\r\n"); pc.printf("\r\n> 7: Minuetto ***\r\n"); pc.printf("\r\n> 8: Minuetto ***\r\n"); pc.printf("\r\n> 9: Me Composer ***\r\n"); while(pc.readable()) { // acquisisce il suono da generare cScore = pc.getc(); } // suona lo spartito selezionato if(cScore == '6') { // abilita la generazione di suoni bStop=false; // genera le note indicate nell'array spartito con la durata indicata nell'array length for(nIndex=0; nIndex<SYMPHONYN5DURATION; nIndex++) { // genera la frequenza relativa alla nota selezionata, da nIndex, nello spartito fFreq=fNoteSymphonyN5[nIndex]; 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 //dopo aver generato la nota, attendi per un periodo pari alla durata della nota wait_ms(fLengthSymphonyN5[nIndex]); } } else { if(cScore=='9') { 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) { //La# case 'u': case 'U': { fFreq=466.16;// frequenza della sinusoide La# pc.printf("\n\r--- Generazione La#_SIb= %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; //sol# case 'y': case 'Y': { fFreq=415.3;// frequenza della sinusoide Sol# pc.printf("\n\r--- Generazione Sol#_LAb = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; //Sol_b case 't': case 'T': { fFreq=369.99;// frequenza della sinusoide Sol_b pc.printf("\n\r--- Generazione Solb_Fa# = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; //DO# case 'e': case 'E': { fFreq=277.18;// frequenza della sinusoide DO diesis pc.printf("\n\r--- Generazione DO# = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; //DO case 'd': case 'D': { 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 'f': case 'F': { 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 'r': case 'R': { fFreq=311.13; pc.printf("\n\r--- Generazione Mib = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; case 'g': case 'G': { 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 'h': case 'H': { 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 'j': case 'J': { fFreq=392.0; pc.printf("\n\r--- Generazione SOL = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; // LA case 'k': case 'K': { 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 'l': case 'L': { 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; //DO 5° case 'z': case 'Z': { fFreq=523.00;// frequenza della sinusoide SI da generare pc.printf("\n\r--- Generazione DO5 = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; //RE 5° case 'x': case 'X': { fFreq=587.00;// frequenza della sinusoide SI da generare pc.printf("\n\r--- Generazione RE5 = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } break; // pausa case ' ': { bStop = true; pc.printf("\n\r--- Generazione pausa = %.2f Hz ampiezza nominale ---\n\r", fFreq); } break; //prova case 'o': { fFreq=587.00; wait_ms(600); fFreq=392.00; wait_ms(300); fFreq=440.00; wait_ms(300); fFreq=493.88; wait_ms(300); fFreq=523.16; wait_ms(300); } break; //Stop case 'b': case 'B': { fFreq=0;// stop pc.printf("\n\r--- Generazione Stop = %.2f Hz ampiezza nominale ---\n\r", fFreq); bStop = false; } 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 { } } // while } // cScore = '9' } /******* 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 ******/ }