Esercizio aggiornato

Dependencies:   mbed

Fork of Amaldi_9_Exercise_Sound-Generation by Amaldi

Sound-Generation.cpp

Committer:
Vito1704
Date:
2018-05-31
Revision:
5:413f85118dd5
Parent:
4:6225b049c06b

File content as of revision 5:413f85118dd5:

// 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 della frequenza delle note ottava centrale del pianoforte
#define m 0
#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;
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];

//****************************
// 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*** 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 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 macinin  ***\r\n");
    pc.printf("\r\n> 5: Preludio  ***\r\n");
    pc.printf("\r\n> 6:   ***\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");
    //dichiarazione array pause
      float pausa [7]; 
      pausa [1] = 1 ; //semibreve
      pausa [2] = 0.5; //minima
      pausa [3] = 0.25;//semiminima
      pausa [4] = 0.125;//croma
      pausa [5] = 0.0625;//semicroma
      pausa [6] = 0.03125;//semibiscroma 
    //dichiarazione matrice
     float note [25][7];
      note [1][1] =  261.63,1;//Do semibreve (Frequenza),(Tempo in s)
      note [1][2] =  261.63,0.5;//Do minima
      note [1][3] =  261.63,0.25;//Do semiminima
      note [1][4] =  261.63,0.125;//Do croma
      note [1][5] =  261.63,0.0625;//Do semicroma
      note [1][6] =  261.63,0.03125;//Do semibiscroma
      note [2][1] =  293.66,1;//Re semibreve
      note [2][2] =  293.66,0.5;//Re minima
      note [2][3] =  293.66,0.25;//Re semiminima
      note [2][4] =  293.66,0.125;//Re croma
      note [2][5] =  293.66,0.0625;//Re semicroma
      note [2][6] =  293.66,0.03125;//Re semibiscroma
      note [3][1] =  330.00,1;//Mi semibreve
      note [3][2] =  330.00,0.5;//Mi minima
      note [3][3] =  330.00,0.25;//Mi semiminima
      note [3][4] =  330.00,0.125;//Mi croma
      note [3][5] =  330.00,0.0625;//Mi semicroma
      note [3][6] =  330.00,0.03125;//Mi semibiscroma
      note [4][1] =  349.00,1;//Fa semibreve
      note [4][2] =  349.00,0.5;//Fa minima
      note [4][3] =  349.00,0.25;//Fa semiminima
      note [4][4] =  349.00,0.125;//Fa croma
      note [4][5] =  349.00,0.0625;//Fa semicroma
      note [4][6] =  349.00,0.03125;//Fa semibiscroma
      note [5][1] =  392.00,1;//Sol semibreve
      note [5][2] =  392.00,0.5;//Sol minima
      note [5][3] =  392.00,0.25;//Sol semiminima
      note [5][4] =  392.00,0.125;//Sol croma
      note [5][5] =  392.00,0.0625;//Sol semicroma
      note [5][6] =  392.00,0.03125;//Sol semibiscroma
      note [6][1] =  440.00,1;//La semibreve
      note [6][2] =  440.00,0.5;//la minima
      note [6][3] =  349.00,0.25;//La semiminima
      note [6][4] =  440.00,0.125;//La croma
      note [6][5] =  440.00,0.0625;//La semicroma
      note [6][6] =  440.00,0.03125;//La semibiscroma
      note [7][1] =  494.00,1;//Si semibreve
      note [7][2] =  494.00,0.5;//Si minima
      note [7][3] =  494.00,0.25;//Si semiminima
      note [7][4] =  494.00,0.125;//Si croma
      note [7][5] =  494.00,0.0625;//Si semicroma
      note [7][6] =  494.00,0.03125;//Si semibiscroma
      note [8][1] =  277.18,1;//Do# semibreve
      note [8][2] =  277.18,0.5;//Do# minima
      note [8][3] =  277.18,0.25;//Do# semiminima
      note [8][4] =  277.18,0.125;//Do# croma
      note [8][5] =  277.18,0.0625;//Do# semicroma
      note [8][6] =  277.18,0.03125;//Do# semibiscroma
      note [9][1] =  311.13,1;//Re# semibreve
      note [9][2] =  311.13,0.5;//Re# minima
      note [9][3] =  311.13,0.25;//Re# semiminima
      note [9][4] =  311.13,0.125;//Re#croma
      note [9][5] =  311.13,0.0625;//Re# semicroma
      note [9][6] =  311.13,0.03125;//Re# semibiscroma
      note [10][1] =  370.00,1;//Fa# semibreve
      note [10][2] =  370.00,0.5;//Fa# minima
      note [10][3] =  370.00,0.25;//fa# semiminima
      note [10][4] =  370.00,0.125;//Fa#croma
      note [10][5] =  370.00,0.0625;//Fa# semicroma
      note [10][6] =  370.00,0.03125;//Fa# semibiscroma
      note [11][1] =  370.00,1;//Fa# semibreve
      note [11][2] =  370.00,0.5;//Fa# minima
      note [11][3] =  370.00,0.25;//fa# semiminima
      note [11][4] =  370.00,0.125;//Fa#croma
      note [11][5] =  370.00,0.0625;//Fa# semicroma
      note [11][6] =  370.00,0.03125;//Fa# semibiscroma
      note [12][1] =  370.00,1;//Sol# semibreve
      note [12][2] =  370.00,0.5;//Sol# minima
      note [12][3] =  370.00,0.25;//Sol# semiminima
      note [12][4] =  370.00,0.125;//Sol#croma
      note [12][5] =  370.00,0.0625;//Sol# semicroma
      note [12][6] =  370.00,0.03125;//Sol# semibiscroma 
      note [13][1] =  370.00,1;//La# semibreve
      note [13][2] =  370.00,0.5;//La# minima
      note [13][3] =  370.00,0.25;//La# semiminima
      note [13][4] =  370.00,0.125;//La#croma
      note [13][5] =  370.00,0.0625;//La# semicroma
      note [13][6] =  370.00,0.03125;//La# semibiscroma
      note [14][1] =  523.00,1;//Do 5° semibreve 
      note [14][2] =  523.00,0.5;//Do 5° minima 
      note [14][3] =  523.00,0.25;//Do 5° semiminima 
      note [14][4] =  523.00,0.125;//Do 5° croma 
      note [14][5] =  523.00,0.0625;//Do 5° semicroma 
      note [14][6] =  523.00,0.03125;//Do 5° semibiscroma  
      note [15][1] =  523.00,1;//Do# 5° semibreve 
      note [15][2] =  523.00,0.5;//Do# 5° minima 
      note [15][3] =  523.00,0.25;//Do# 5° semiminima 
      note [15][4] =  523.00,0.125;//Do# 5° croma 
      note [15][5] =  523.00,0.0625;//Do# 5° semicroma 
      note [15][6] =  523.00,0.03125;//Do# 5° semibiscroma 
      note [16][1] =  622.00,1;//Re# 5° semibreve 
      note [16][2] =  622.00,0.5;//Re# 5° minima 
      note [16][3] =  622.00,0.25;//Re# 5° semiminima 
      note [16][4] =  622.00,0.125;//Re# 5° croma 
      note [16][5] =  622.00,0.0625;//Re# 5° semicroma 
      note [16][6] =  622.00,0.03125;//Re# 5° semibiscroma
      note [17][1] =  587.00,1;//Re 5° semibreve 
      note [17][2] =  587.00,0.5;//Re 5° minima 
      note [17][3] =  587.00,0.25;//Re 5° semiminima 
      note [17][4] =  587.00,0.125;//Re 5° croma 
      note [17][5] =  587.00,0.0625;//Re 5° semicroma 
      note [17][6] =  587.00,0.03125;//Re 5° semibiscroma   
      note [18][1] =  659.00,1;//Mi 5° semibreve 
      note [18][2] =  659.00,0.5;//Mi 5° minima 
      note [18][3] =  659.00,0.25;//Mi 5° semiminima 
      note [18][4] =  659.00,0.125;//Mi 5° croma 
      note [18][5] =  659.00,0.0625;//Mi 5° semicroma 
      note [18][6] =  659.00,0.03125;//Mi 5° semibiscroma 
      note [19][1] =  698.00,1;//Fa 5° semibreve 
      note [19][2] =  698.00,0.5;//Fa 5° minima 
      note [19][3] =  698.00,0.25;//Fa 5° semiminima 
      note [19][4] =  698.00,0.125;//Fa 5° croma 
      note [19][5] =  698.00,0.0625;//Fa 5° semicroma 
      note [19][6] =  698.00,0.03125;//Fa 5° semibiscroma 
      note [20][1] =  740.00,1;//Fa# 5° semibreve 
      note [20][2] =  740.00,0.5;//Fa# 5° minima 
      note [20][3] =  740.00,0.25;//Fa# 5° semiminima 
      note [20][4] =  740.00,0.125;//Fa# 5° croma 
      note [20][5] =  740.00,0.0625;//Fa# 5° semicroma 
      note [20][6] =  740.00,0.03125;//Fa# 5° semibiscroma 
      note [21][1] =  784.00,1;//Sol 5° semibreve 
      note [21][2] =  784.00,0.5;//Sol 5° minima 
      note [21][3] =  784.00,0.25;//Sol 5° semiminima 
      note [21][4] =  784.00,0.125;//Sol 5° croma 
      note [21][5] =  784.00,0.0625;//Sol 5° semicroma 
      note [21][6] =  784.00,0.03125;//Sol 5° semibiscroma 
      note [22][1] =  831.00,1;//Sol# 5° semibreve 
      note [22][2] =  831.00,0.5;//Sol# 5° minima 
      note [22][3] =  831.00,0.25;//Sol# 5° semiminima 
      note [22][4] =  831.00,0.125;//Sol# 5° croma 
      note [22][5] =  831.00,0.0625;//Sol# 5° semicroma 
      note [22][6] =  831.00,0.03125;//Sol# 5° semibiscroma  
      note [23][1] =  880.00,1;//La 5° semibreve 
      note [23][2] =  880.00,0.5;//La 5° minima 
      note [23][3] =  880.00,0.25;//La 5° semiminima 
      note [23][4] =  880.00,0.125;//La 5° croma 
      note [23][5] =  880.00,0.0625;//La 5° semicroma 
      note [23][6] =  880.00,0.03125;//La 5° semibiscroma  
      note [24][1] =  932.00,1;//La# 5° semibreve 
      note [24][2] =  932.00,0.5;//La# 5° minima 
      note [24][3] =  932.00,0.25;//La# 5° semiminima 
      note [24][4] =  932.00,0.125;//La# 5° croma 
      note [24][5] =  932.00,0.0625;//La# 5° semicroma 
      note [24][6] =  932.00,0.03125;//La# 5° semibiscroma 
      note [25][1] =  988.00,1;//Si 5° semibreve 
      note [25][2] =  988.00,0.5;//Si 5° minima 
      note [25][3] =  988.00,0.25;//Si 5° semiminima 
      note [25][4] =  988.00,0.125;//Si 5° croma 
      note [25][5] =  988.00,0.0625;//Si 5° semicroma 
      note [25][6] =  988.00,0.03125;//Si 5° semibiscroma     
    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
        {
           
        } 
     }   
 
    /******* 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 ******/
}