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

Dependencies:   mbed

Fork of amplificatore_bomboni_rev1 by Amaldi

Amplificatore.cpp

Committer:
pinofal
Date:
2018-06-18
Revision:
7:cc303710b1bc
Parent:
Sound-Generation.cpp@ 6:be1561f8c63c

File content as of revision 7:cc303710b1bc:

// 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 2000000 // durata della semibreve in microsecondi = 4sec
#define MINIMA SEMIBREVE/2  
#define SEMIMINIMA SEMIBREVE/4 
#define CROMA SEMIBREVE/8  
#define SEMICROMA CROMA/16  
#define BISCROMA SEMIBREVE/32 
#define SEMIBISCROMA SEMIBREVE/64 


// definizione della frequenza delle note ottava centrale del pianoforte
#define p 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 int bGenerate = false;
// 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(bGenerate==0)
    {
    }
    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] = {p,        G1,     G1,     G1,     E1b,     p,     F1,     F1,     F1,     D1};
    // durata delle note del brano
    float fLengthSymphonyN5[SYMPHONYN5DURATION] ={CROMA,    CROMA,  CROMA,  CROMA,  MINIMA, CROMA,  CROMA,  CROMA,  CROMA,  MINIMA};
   
    // numero di note che compongono il brano
    #define MINUETTODURATION 20 // numero di note che compongono il brano
    // note del brano
    float fNoteMinuetto [SYMPHONYN5DURATION] = {p,        G1,     G1,     G1,     E1b,     p,     F1,     F1,     F1,     D1};
    // durata delle note del brano
    float fLengthMinuetto[SYMPHONYN5DURATION] ={CROMA,    CROMA,  CROMA,  CROMA,  MINIMA, CROMA,  CROMA,  CROMA,  CROMA,  MINIMA};
  
    // indice per i cicli
    int nIndex;
    
    //inizializza variabili
    bGenerate=false;
    cReadChar = 0;
    nSampleOutIndex=0;
    nSampleOutCount=0;
    
    
    // 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");
    
    
    
    // test dei LED
    led1=1; //Verde
    wait_ms(500);
    led1=0;
    led2=1; // Blu
    wait_ms(500);
    led2=0;
    led3=1; //Rosso
    wait_ms(500);
    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");
    
    // acquisisce il tipo di suono da generare
    while(!pc.readable())
    {
    }   
    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");
    
    // acquisisce lo spartito da generare
    while(!pc.readable())
    {
    }   
    cScore = pc.getc();   
        
    
    // suona lo spartito selezionato   
    if(cScore =='6')
    {
        // abilita la generazione di suoni
        bGenerate=true;
        
        fAmp = 1.0; // coefficiente per il quale viene moltiplicato l'ampiezza massima
        
        // genera la frequenza relativa alla nota selezionata, da nIndex, nello spartito
        bGenerate=fNoteSymphonyN5[0];
        fFreq=fNoteSymphonyN5[0];
        if(bGenerate !=0) 
        {
            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_us(fLengthSymphonyN5[1]);
        
        // accento sulla nota
        bGenerate=false;
        wait_us(fLengthSymphonyN5[1]/5);
        bGenerate=true;
        
        bGenerate=fNoteSymphonyN5[1];
        fFreq=fNoteSymphonyN5[1];
        if(bGenerate !=0)
        {
            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_us(fLengthSymphonyN5[1]);
        
        // accento sulla nota
        bGenerate=false;
        wait_us(fLengthSymphonyN5[1]/5);
        bGenerate=true;
        
        bGenerate=fNoteSymphonyN5[2];
        fFreq=fNoteSymphonyN5[2];
        if(bGenerate !=0) 
        {
            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_us(fLengthSymphonyN5[2]);
        
        // accento sulla nota
        bGenerate=false;
        wait_us(fLengthSymphonyN5[2]/5);
        bGenerate=true;
        
        bGenerate=fNoteSymphonyN5[3];
        fFreq=fNoteSymphonyN5[3];
        if(bGenerate !=0)
        {
            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_us(fLengthSymphonyN5[3]);
        
        // accento sulla nota
        bGenerate=false;
        wait_us(fLengthSymphonyN5[3]/5);
        bGenerate=true;
        
        bGenerate=fNoteSymphonyN5[4];
        fFreq=fNoteSymphonyN5[4];
        if(bGenerate !=0)
        {
            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_us(fLengthSymphonyN5[4]);
        
        // accento sulla nota
        bGenerate=false;
        wait_us(fLengthSymphonyN5[4]/5);
        //bGenerate=true;
        
        pc.printf("\r\n premi tasto");    
        while(!pc.readable())
        {
        }
        
        
        // coefficiente per il quale viene moltiplicato l'ampiezza massima
        fAmp = 1.0; 
                
        // genera le note indicate nell'array spartito con la durata indicata nell'array length 
        for(nIndex=0; nIndex<SYMPHONYN5DURATION; nIndex++)
        {
            bGenerate=fNoteSymphonyN5[nIndex];
            fFreq=fNoteSymphonyN5[nIndex];
            if(bGenerate !=0)
            {
                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_us(fLengthSymphonyN5[nIndex]);
            
            // accento sulla nota
            bGenerate=false;
            wait_us(fLengthSymphonyN5[nIndex]/5);
            bGenerate=true;
        }
        // dopo la lettura dello spartito disattiva suoni
        bGenerate = false;
    }
    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);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } break;
                        // RE#/MIb
                        case 'r':
                        case 'R':
                        {
                            fFreq=311.13;
                            pc.printf("\n\r--- Generazione Mib = %.2f Hz ampiezza nominale ---\n\r", fFreq);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } break;
                        
                        // SOL
                        case 'j':
                        case 'J':
                        {
                            fFreq=392.0;
                            pc.printf("\n\r--- Generazione SOL = %.2f Hz ampiezza nominale ---\n\r", fFreq);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } 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);
                            bGenerate = true;
                        } break;
                        
                        // pausa
                        case ' ':
                        {
                            bGenerate = false;
                            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);
                           bGenerate = false;
                        } break;
                        
                        default:
                        {
                           bGenerate = false; // 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 ******/
}