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
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 ******/
}
