Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Sound-Generation.cpp
- Committer:
- Vito1704
- Date:
- 2018-05-31
- Revision:
- 5:413f85118dd5
- Parent:
- 4:6225b049c06b
- Child:
- 6:be1561f8c63c
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 ******/
}