Stefano Fasciani / ARMmbedFMsinth

Dependencies:   ADXL345 AUDIO_DISCO_F746NG BSP_DISCO_F746NG LCD_DISCO_F746NG SDRAM_DISCO_F746NG TS_DISCO_F746NG mbed-dev

Fork of Workshop_5 by Stefano Fasciani

Files at this revision

API Documentation at this revision

Comitter:
stefanofasciani
Date:
Tue Aug 23 06:34:53 2016 +0000
Parent:
1:00e079bad171
Child:
3:cd1cb0003a3d
Commit message:
First Commit

Changed in this revision

ADXL345.lib Show annotated file Show diff for this revision Revisions of this file
AUDIO_DISCO_F746NG.lib Show annotated file Show diff for this revision Revisions of this file
LCD_DISCO_F746NG.lib Show annotated file Show diff for this revision Revisions of this file
TS_DISCO_F746NG.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-dev.lib Show annotated file Show diff for this revision Revisions of this file
sinth.cpp Show annotated file Show diff for this revision Revisions of this file
sinth.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADXL345.lib	Tue Aug 23 06:34:53 2016 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/aberk/code/ADXL345/#bd8f0f20f433
--- a/AUDIO_DISCO_F746NG.lib	Thu Mar 24 20:51:24 2016 +0000
+++ b/AUDIO_DISCO_F746NG.lib	Tue Aug 23 06:34:53 2016 +0000
@@ -1,1 +1,1 @@
-https://developer.mbed.org/teams/ST/code/AUDIO_DISCO_F746NG/#6f035eff38e4
+http://developer.mbed.org/users/stefanofasciani/code/AUDIO_DISCO_F746NG/#0b1ed1d2140d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LCD_DISCO_F746NG.lib	Tue Aug 23 06:34:53 2016 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/ST/code/LCD_DISCO_F746NG/#d44525b1de98
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TS_DISCO_F746NG.lib	Tue Aug 23 06:34:53 2016 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/ST/code/TS_DISCO_F746NG/#fe0cf5e2960f
--- a/main.cpp	Thu Mar 24 20:51:24 2016 +0000
+++ b/main.cpp	Tue Aug 23 06:34:53 2016 +0000
@@ -1,136 +1,160 @@
-#include "mbed.h"
-#include "AUDIO_DISCO_F746NG.h"
-#include "SDRAM_DISCO_F746NG.h"
+//***********
+// WORKSHOP 4
+//***********
+
+// Author: Stefano Fasciani - stefanofasciani@stefanofasciani.com
+// Date 7/8/2016
+// FM Sinth for DISCO_F746NG and ADXL345
 
+// Frequency Modulation Sound SYnthesis With Fixed Parameters Displayed on LCD
+
+
+#include "sinth.h"
+
+
+ADXL345 accelerometer(D11,D12,D13,D10);
+TS_DISCO_F746NG ts;
+TS_StateTypeDef TS;
 AUDIO_DISCO_F746NG audio;
-// audio IN_OUT buffer is stored in the SDRAM, SDRAM needs to be initialized and FMC enabled
 SDRAM_DISCO_F746NG sdram;
-
-DigitalOut led_green(LED1);
-DigitalOut led_red(LED2);
+LCD_DISCO_F746NG lcd;
 Serial pc(USBTX, USBRX);
 
-typedef enum
-{
-    BUFFER_OFFSET_NONE = 0,
-    BUFFER_OFFSET_HALF = 1,
-    BUFFER_OFFSET_FULL = 2,
-}BUFFER_StateTypeDef;
+
+//FM Synthesis Parameters
+float amplitude = 0.5; //numbers between 0.0 and 1.0
+float pitch = 400; // numbers between 50 and 5000
+float modrate = 0; // numbers between -1000 and 1000
+float moddepth = 0; //numbers between -1000 and 1000
+float filter = 1.0f; //numbers between 0.0 (full filter) and 1.0 (do not filter)
+
+
 
-#define AUDIO_BLOCK_SIZE   ((uint32_t)512)
-#define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */
-#define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */
-__IO uint32_t  audio_rec_buffer_state = BUFFER_OFFSET_NONE;
-static uint8_t SetSysClock_PLL_HSE_200MHz();
+void get_parameters(){
+        
+    char temp_string[20];
+    
+    //read input data
+    ts.GetState(&TS);
+    accelerometer.getOutput(acc_readings);
+    
+    
+    if(TS.touchDetected){
+        //map to synthesis parameters
+        amplitude = 0.5; //map(get_touch_vertical(),0.0,1.0);
+    }
+    else {
+        amplitude = 0;    
+    }
+    
+    
+    pitch = get_note_pitch(); //map(get_touch_horizontal(),50.0,5000.0);
+    
+    modrate = map(get_acc_horizontal(), //input
+                    0, //modrate range minimum (not less than -1000)
+                    200.0); //modrate range maximum (not higher than 1000)
+    
+    moddepth = map(get_acc_vertical(), //input
+                    -100.0, //moddepth range minimum (not less than -1000)
+                    100.0); //moddepth range maximum (not higher than 1000)
+    
+    
+    
+    filter = map(get_touch_vertical(), //input
+                    0.0, //filter range minimum (not less than 0.0)
+                    0.7); //filter range maximum (not higher than 1.0)
+    
+    
+    //update display
+    switch(update_round){
+    case 0:
+        sprintf(temp_string,"%f",amplitude); lcd.DisplayStringAt(250, LINE(1),(uint8_t *)temp_string, LEFT_MODE);
+    case 1:
+        sprintf(temp_string,"%f",pitch); lcd.DisplayStringAt(250, LINE(3),(uint8_t *)temp_string, LEFT_MODE);
+    case 2:
+        sprintf(temp_string,"%f",modrate); lcd.DisplayStringAt(250, LINE(5),(uint8_t *)temp_string, LEFT_MODE);
+    case 3:
+        sprintf(temp_string,"%f",moddepth); lcd.DisplayStringAt(250, LINE(7),(uint8_t *)temp_string, LEFT_MODE);
+    case 4:
+        sprintf(temp_string,"%f",filter); lcd.DisplayStringAt(250, LINE(9),(uint8_t *)temp_string, LEFT_MODE);
+    }
+    update_round++;
+    if(update_round>4)update_round=0;
+    
+    return;    
+}
+
+
+
 int main()
 {
+    
+    //initialize touch screen
+    ts.Init(lcd.GetXSize(), lcd.GetYSize());
+    wait(0.2);
+    
+    // lcd initialization to display synthesis parameter
+    lcd.Clear(LCD_COLOR_BLACK);
+    display_keyboard();
+    lcd.SetBackColor(LCD_COLOR_BLACK);
+    lcd.SetTextColor(LCD_COLOR_LIGHTBLUE);
+    lcd.DisplayStringAt(10, LINE(1),(uint8_t *)"AMPLITUDE    :", LEFT_MODE); 
+    lcd.DisplayStringAt(10, LINE(3),(uint8_t *)"PITCH (Hz)   :", LEFT_MODE); 
+    lcd.DisplayStringAt(10, LINE(5),(uint8_t *)"MOD.RATE (Hz):", LEFT_MODE); 
+    lcd.DisplayStringAt(10, LINE(7),(uint8_t *)"MOD.DEPTH    :", LEFT_MODE);
+    lcd.DisplayStringAt(10, LINE(9),(uint8_t *)"FILTER       :", LEFT_MODE);
+    
+    wait(0.2);
+
+    
+    //initialize accelerometer
+    accelerometer.getDevId();
+    accelerometer.setPowerControl(0x00);
+    accelerometer.setDataFormatControl(0x0B);   
+    accelerometer.setDataRate(ADXL345_3200HZ);
+    accelerometer.setPowerControl(0x08);
+    wait(0.2);
+
+    //sound synthesis initialization
+    init_sin_table();
     SetSysClock_PLL_HSE_200MHz();
     pc.baud(9600);
-
-    pc.printf("\n\nAUDIO LOOPBACK EXAMPLE START:\n");
-    led_red = 0;
-  
-    pc.printf("\nAUDIO RECORD INIT OK\n");
-    pc.printf("Microphones sound streamed to headphones\n");
-    
-    /* Initialize SDRAM buffers */
-    memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);
-    memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
-    audio_rec_buffer_state = BUFFER_OFFSET_NONE;
-
-    /* Start Recording */
-    audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE);
-
-    /* Start Playback */
+    memset((void *)out_buffer, 0, AUDIO_BLOCK_SIZE*2*sizeof(uint16_t));    
+    audio_out_buffer_state = BUFFER_OFFSET_NONE;
     audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
-    audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2);
+    audio.OUT_Play((uint16_t*)out_buffer, AUDIO_BLOCK_SIZE * 2 * sizeof(int16_t));
 
   
     while (1) {
-        /* Wait end of half block recording */
-        while(audio_rec_buffer_state == BUFFER_OFFSET_HALF) {
-        }
-        audio_rec_buffer_state = BUFFER_OFFSET_NONE;
-        /* Copy recorded 1st half block */
-        memcpy((uint16_t *)(AUDIO_BUFFER_OUT), (uint16_t *)(AUDIO_BUFFER_IN), AUDIO_BLOCK_SIZE);
-        /* Wait end of one block recording */
-        while(audio_rec_buffer_state == BUFFER_OFFSET_FULL) {
-        }
-        audio_rec_buffer_state = BUFFER_OFFSET_NONE;
-        /* Copy recorded 2nd half block */
-        memcpy((uint16_t *)(AUDIO_BUFFER_OUT + (AUDIO_BLOCK_SIZE)), (uint16_t *)(AUDIO_BUFFER_IN + (AUDIO_BLOCK_SIZE)), AUDIO_BLOCK_SIZE);
+
+        while(audio_out_buffer_state != BUFFER_OFFSET_HALF);
+        audio_out_buffer_state = BUFFER_OFFSET_NONE;
+        get_parameters();
+        sint_osc();
+        copy_buffer(0);
+        
+        
+        while(audio_out_buffer_state != BUFFER_OFFSET_FULL);
+        audio_out_buffer_state = BUFFER_OFFSET_NONE;
+        get_parameters();
+        sint_osc();
+        copy_buffer(AUDIO_BLOCK_SIZE);
+             
     }
 }
-/*-------------------------------------------------------------------------------------
-       Callbacks implementation:
-           the callbacks API are defined __weak in the stm32746g_discovery_audio.c file
-           and their implementation should be done in the user code if they are needed.
-           Below some examples of callback implementations.
-  -------------------------------------------------------------------------------------*/
-/**
-  * @brief Manages the DMA Transfer complete interrupt.
-  * @param None
-  * @retval None
-  */
-void BSP_AUDIO_IN_TransferComplete_CallBack(void)
-{
-  audio_rec_buffer_state = BUFFER_OFFSET_FULL;
-  return;
-}
-
-/**
-  * @brief  Manages the DMA Half Transfer complete interrupt.
-  * @param  None
-  * @retval None
-  */
-void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
-{
-  audio_rec_buffer_state = BUFFER_OFFSET_HALF;
-  return;
-}
 
-static uint8_t SetSysClock_PLL_HSE_200MHz()
-{
-  RCC_ClkInitTypeDef RCC_ClkInitStruct;
-  RCC_OscInitTypeDef RCC_OscInitStruct;
-
-  // Enable power clock  
-  __PWR_CLK_ENABLE();
-  
-  // Enable HSE oscillator and activate PLL with HSE as source
-  RCC_OscInitStruct.OscillatorType      = RCC_OSCILLATORTYPE_HSE;
-  RCC_OscInitStruct.HSEState            = RCC_HSE_ON; /* External xtal on OSC_IN/OSC_OUT */
+/*
+CONNECTION DISCO_F746NG to ADXL345
+D10 -   SS      - CS
+D11 -   MOSI    - SDA
+D12 -   MISO    - SDO
+D13 -   SCK     - SCL
+3V3 -   VCC     - VCC
+GND -   GND     - GND
+*/
 
-  // Warning: this configuration is for a 25 MHz xtal clock only
-  RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_ON;
-  RCC_OscInitStruct.PLL.PLLSource       = RCC_PLLSOURCE_HSE;
-  RCC_OscInitStruct.PLL.PLLM            = 25;            // VCO input clock = 1 MHz (25 MHz / 25)
-  RCC_OscInitStruct.PLL.PLLN            = 400;           // VCO output clock = 400 MHz (1 MHz * 400)
-  RCC_OscInitStruct.PLL.PLLP            = RCC_PLLP_DIV2; // PLLCLK = 200 MHz (400 MHz / 2)
-  RCC_OscInitStruct.PLL.PLLQ            = 8;             // USB clock = 50 MHz (400 MHz / 8)
-  
-  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
-  {
-    return 0; // FAIL
-  }
+
+
 
-  // Activate the OverDrive to reach the 216 MHz Frequency
-  if (HAL_PWREx_EnableOverDrive() != HAL_OK)
-  {
-    return 0; // FAIL
-  }
-  
-  // Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
-  RCC_ClkInitStruct.ClockType      = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
-  RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK; // 200 MHz
-  RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;         // 200 MHz
-  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;           //  50 MHz
-  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;           // 100 MHz
-  
-  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
-  {
-    return 0; // FAIL
-  }
-  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_4);
-  return 1; // OK
-}
+
+
--- a/mbed-dev.lib	Thu Mar 24 20:51:24 2016 +0000
+++ b/mbed-dev.lib	Tue Aug 23 06:34:53 2016 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed-dev/#740f8f9b184c
+http://mbed.org/users/mbed_official/code/mbed-dev/#423e1876dc07
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sinth.cpp	Tue Aug 23 06:34:53 2016 +0000
@@ -0,0 +1,221 @@
+
+// Author: Stefano Fasciani - stefanofasciani@stefanofasciani.com
+// Date 7/8/2016
+// FM Sinth for DISCO_F746NG and ADXL345
+
+#include "sinth.h"
+
+float table[TABLE_SIZE];
+int16_t out_buffer[AUDIO_BLOCK_SIZE*2];
+float osc_buf[AUDIO_BLOCK_SIZE/2];
+__IO uint32_t  audio_out_buffer_state = BUFFER_OFFSET_NONE;
+float idx_1 = 0;
+float idx_2 = 0;
+float filt_old_samp = 0;
+static float frqTL = 0.04266666666667;
+static float two_pi_48k = 1.3089969389957471826927680763665e-4;
+int acc_readings[3];
+int update_round = 0;
+
+void BSP_AUDIO_OUT_TransferComplete_CallBack(void){
+  audio_out_buffer_state = BUFFER_OFFSET_FULL;
+  return;
+}
+
+
+void BSP_AUDIO_OUT_HalfTransfer_CallBack(void){
+  audio_out_buffer_state = BUFFER_OFFSET_HALF;
+  return;
+}
+
+uint8_t SetSysClock_PLL_HSE_200MHz()
+{
+  RCC_ClkInitTypeDef RCC_ClkInitStruct;
+  RCC_OscInitTypeDef RCC_OscInitStruct;
+
+  // Enable power clock  
+  __PWR_CLK_ENABLE();
+  
+  // Enable HSE oscillator and activate PLL with HSE as source
+  RCC_OscInitStruct.OscillatorType      = RCC_OSCILLATORTYPE_HSE;
+  RCC_OscInitStruct.HSEState            = RCC_HSE_ON; /* External xtal on OSC_IN/OSC_OUT */
+
+  // Warning: this configuration is for a 25 MHz xtal clock only
+  RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_ON;
+  RCC_OscInitStruct.PLL.PLLSource       = RCC_PLLSOURCE_HSE;
+  RCC_OscInitStruct.PLL.PLLM            = 25;            // VCO input clock = 1 MHz (25 MHz / 25)
+  RCC_OscInitStruct.PLL.PLLN            = 400;           // VCO output clock = 400 MHz (1 MHz * 400)
+  RCC_OscInitStruct.PLL.PLLP            = RCC_PLLP_DIV2; // PLLCLK = 200 MHz (400 MHz / 2)
+  RCC_OscInitStruct.PLL.PLLQ            = 8;             // USB clock = 50 MHz (400 MHz / 8)
+  
+  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+  {
+    return 0; // FAIL
+  }
+
+  // Activate the OverDrive to reach the 216 MHz Frequency
+  if (HAL_PWREx_EnableOverDrive() != HAL_OK)
+  {
+    return 0; // FAIL
+  }
+  
+  // Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
+  RCC_ClkInitStruct.ClockType      = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
+  RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK; // 200 MHz
+  RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;         // 200 MHz
+  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;           //  50 MHz
+  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;           // 100 MHz
+  
+  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
+  {
+    return 0; // FAIL
+  }
+  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_4);
+  return 1; // OK
+}
+
+void sint_osc(){
+    
+    int i;
+    float mod;
+    int indexBase;
+    float indexFract, value1, value2;
+    
+    for (i=0;i<AUDIO_BLOCK_SIZE/2;i++){
+        indexBase = floor(idx_2);
+        indexFract = idx_2 - (float)indexBase;
+        value1 = table[indexBase];
+        value2 = table[(indexBase+1)%TABLE_SIZE];
+        mod = moddepth*(value1 + ((value2 - value1) * indexFract));
+        
+        indexBase = floor(idx_1);
+        indexFract = idx_1 - (float)indexBase;
+        value1 = table[indexBase];
+        value2 = table[(indexBase+1)%TABLE_SIZE];
+        osc_buf[i] = amplitude*(value1 + ((value2 - value1) * indexFract)); 
+
+        idx_1 = idx_1 + ((frqTL * pitch) + mod);
+        while (idx_1 >= TABLE_SIZE){
+            idx_1 -= TABLE_SIZE;
+        }
+        while (idx_1 < 0){
+            idx_1 += TABLE_SIZE;
+        }
+        idx_2 = idx_2 + (frqTL * modrate);
+        while (idx_2 >= TABLE_SIZE){
+            idx_2 -= TABLE_SIZE;
+        }
+        while (idx_2 < 0){
+            idx_2 += TABLE_SIZE;
+        }
+        
+    }
+    
+    osc_buf[0] = filter*osc_buf[0] + (1-filter)*filt_old_samp;
+    for(i=1;i<AUDIO_BLOCK_SIZE/2;i++){
+        osc_buf[i] = filter*osc_buf[i] + (1-filter)*osc_buf[i-1];
+    }
+    filt_old_samp = osc_buf[(AUDIO_BLOCK_SIZE/2)-1];
+    
+    
+    return;
+}
+
+void copy_buffer(int offset){
+    int i;
+    for(i=0;i<AUDIO_BLOCK_SIZE/2;i++){
+            out_buffer[offset+(i*2)] = out_buffer[offset+(i*2)+1] = (int16_t)(30000*osc_buf[i]);
+    }
+    
+    return;
+}
+
+
+void init_sin_table(){
+    
+    int i;
+    for(i=0;i<TABLE_SIZE;i++){
+        table[i] = sinf((float)(two_pi_48k*(23.4375f)*(float)i));
+    }    
+    return;    
+}
+
+float map_full(float x, float in_min, float in_max, float out_min, float out_max) {
+  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
+
+float map(float x, float out_min, float out_max) {
+  return (x - 0.0f) * (out_max - out_min) / (1.0f - 0.0f) + out_min;
+}
+
+float get_touch_horizontal(){
+    float temp = map_full(TS.touchX[0],1,480,0.0,1.0);
+    if(temp > 1)temp=1;
+    else if(temp < 0)temp=0;
+    return temp;
+}
+
+float get_touch_vertical(){
+    float temp = map_full(TS.touchY[0],1,272,0.0,1.0);     
+    if(temp > 1)temp=1;
+    else if(temp < 0)temp=0;
+    return temp;
+}
+
+float get_acc_horizontal(){
+    float temp = map_full((float)(int16_t)acc_readings[1],230,-230,0.0,1.0); //for full range -/+256
+    if(temp > 1)temp=1;
+    else if(temp < 0)temp=0;
+    return temp;
+}
+
+float get_acc_vertical(){
+    float temp = map_full((float)(int16_t)acc_readings[0],230,-230,0.0,1.0); //for full range -/+256
+    if(temp > 1)temp=1;
+    else if(temp < 0)temp=0;
+    return temp;
+}
+
+void display_keyboard(){
+      
+      lcd.SetTextColor(LCD_COLOR_LIGHTRED);
+      lcd.FillRect(2,0,38,272);
+      lcd.FillRect(82,0,38,272);  
+      lcd.FillRect(162,0,38,272);  
+      lcd.FillRect(202,0,38,272);
+      lcd.FillRect(282,0,38,272);
+      lcd.FillRect(362,0,38,272);
+      lcd.FillRect(442,0,38,272);
+      
+      lcd.SetTextColor(LCD_COLOR_DARKRED);
+      lcd.FillRect(42,0,38,272);
+      lcd.FillRect(122,0,38,272);
+      lcd.FillRect(242,0,38,272);
+      lcd.FillRect(322,0,38,272);
+      lcd.FillRect(402,0,38,272);
+      
+      lcd.SetTextColor(LCD_COLOR_BLACK);
+      lcd.FillRect(1,21,480,232);
+      
+      return;
+}
+
+float get_note_pitch(){
+    
+    float pitch = 0;
+    
+    if((TS.touchX[0]>=1)&&(TS.touchX[0]<=40)) pitch = 523.25f;
+    else if((TS.touchX[0]>=41)&&(TS.touchX[0]<=80)) pitch = 554.37f;
+    else if((TS.touchX[0]>=81)&&(TS.touchX[0]<=120)) pitch = 587.33f;
+    else if((TS.touchX[0]>=121)&&(TS.touchX[0]<=160)) pitch = 622.25f;
+    else if((TS.touchX[0]>=161)&&(TS.touchX[0]<=200)) pitch = 659.25f;
+    else if((TS.touchX[0]>=201)&&(TS.touchX[0]<=240)) pitch = 698.46f;
+    else if((TS.touchX[0]>=241)&&(TS.touchX[0]<=280)) pitch = 739.99f;
+    else if((TS.touchX[0]>=281)&&(TS.touchX[0]<=320)) pitch = 783.99f;
+    else if((TS.touchX[0]>=321)&&(TS.touchX[0]<=360)) pitch = 830.61f;
+    else if((TS.touchX[0]>=361)&&(TS.touchX[0]<=400)) pitch = 880.00;
+    else if((TS.touchX[0]>=401)&&(TS.touchX[0]<=440)) pitch = 932.33;
+    else if((TS.touchX[0]>=441)&&(TS.touchX[0]<=480)) pitch = 987.77;
+    
+    return pitch;    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sinth.h	Tue Aug 23 06:34:53 2016 +0000
@@ -0,0 +1,54 @@
+
+// Author: Stefano Fasciani - stefanofasciani@stefanofasciani.com
+// Date 7/8/2016
+// FM Sinth for DISCO_F746NG and ADXL345
+
+
+#include "mbed.h"
+#include "AUDIO_DISCO_F746NG.h"
+#include "SDRAM_DISCO_F746NG.h"
+#include "LCD_DISCO_F746NG.h"
+#include "TS_DISCO_F746NG.h"
+#include "ADXL345.h"
+#include <math.h>
+
+#define AUDIO_BLOCK_SIZE    1024
+#define TABLE_SIZE          2048
+
+typedef enum{
+    BUFFER_OFFSET_NONE = 0,
+    BUFFER_OFFSET_HALF = 1,
+    BUFFER_OFFSET_FULL = 2,
+}BUFFER_StateTypeDef;
+
+float map(float x, float out_min, float out_max);
+void sint_osc();
+void copy_buffer(int offset);
+void init_sin_table();
+float get_touch_horizontal();
+float get_touch_vertical();
+float get_acc_horizontal();
+float get_acc_vertical();
+void display_keyboard();
+float get_note_pitch();
+uint8_t SetSysClock_PLL_HSE_200MHz();
+
+
+extern float table[];
+extern int16_t out_buffer[];
+extern float osc_buf[];
+extern __IO uint32_t  audio_out_buffer_state;
+extern float idx_1;
+extern float idx_2;
+extern float filt_old_samp;
+extern float frqTL;
+extern float two_pi_48k;
+extern int acc_readings[];
+extern int update_round;
+extern float amplitude;
+extern float pitch;
+extern float modrate;
+extern float moddepth;
+extern float filter;
+extern TS_StateTypeDef TS;
+extern LCD_DISCO_F746NG lcd;