doku newon / Mbed 2 deprecated Peach_AudioChannelDividerAndCompensator

Dependencies:   DokuFFTPACK DokuUSBDevice DokuUSBHost DokuUSBHostWithIso mbed

Fork of Peach_AudioChannelDividerAndCompensator by doku newon

Files at this revision

API Documentation at this revision

Comitter:
dokunewon
Date:
Mon Oct 19 02:49:24 2015 +0000
Parent:
11:064c590a51f9
Commit message:
refine buffer adjustment. adding comments. using MACROS for constant.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Mon Oct 19 00:27:51 2015 +0000
+++ b/main.cpp	Mon Oct 19 02:49:24 2015 +0000
@@ -26,126 +26,153 @@
 #define USB_HOST_CH     0
 #endif
 
-#define IN_DWORDS               32768                       //data size in long word buffer 32767 sample stereo
+//data size of receiving buffer in long word (32767samples 16bit stereo)
+#define IN_DWORDS               32768                       
 #define IN_BANKS                2
-#define OUT_DWORDS              (3 * IN_DWORDS)             //data size in long word buffer 32767 sample stereo * 3 
+//data size of sending buffer in long word (32767samples 16bit 6ch)
+#define OUT_DWORDS              (3 * IN_DWORDS)             
 #define OUT_BANKS               2
-#define NULL_DWORDS             (48 * 2 * 6 * 100 / 4)      //silenc sound data for 100msec
+//data size of silence data in long word (48ksps 16bit 6ch 100msec)
+#define NULL_DWORDS             (48 * 2 * 6 * 100 / 4)      
 
+//shows USB audio is attached or not
 extern int USB_Audio_Attached;
+//receiving buffer (2 banks)
 static volatile uint32_t BufR[IN_BANKS][IN_DWORDS];
+//sending buffer (2 banks)
 static volatile uint32_t BufW[OUT_BANKS][OUT_DWORDS];
+//silence data buffer to adjust buffer volume
 static volatile uint32_t BufNull[NULL_DWORDS] = {};
-int Recover = 1;
-int FFTOverFlow = 0;
+//overflow flag of FFT
+int FFTOverFlow = 0;                                        
 
-DigitalIn  button(USER_BUTTON0);
+//push button on the board
+DigitalIn  button(USER_BUTTON0);                            
 
-DigitalOut LedR(LED1);
+//shows adjustment for buffer short or full is done
+DigitalOut LedR(LED1);                                      
 DigitalOut LedG(LED2);
-DigitalOut LedB(LED3);
+//shows FFT is in process
+DigitalOut LedB(LED3);                                      
 
-//USBDAC
+//USBDAC host
 USBHostDac *pusbdac;
 
+//receive buffer bank 0 or 1 ready
+Semaphore semR0(0);
+Semaphore semR1(0);
+//send buffer bank 0 or 1 ready
 Semaphore semW0(0);
-Semaphore semR0(0);
 Semaphore semW1(0);
-Semaphore semR1(0);
 
+Semaphore *semR[2] = {&semR0, &semR1}; 
+Semaphore *semW[2] = {&semW0, &semW1}; 
+
+//measures latency of semaphore waiting
 Timer Tmr;
 
-#define TARGET_BUFFER_MARGIN    20          //88 for buffer full at 11 ITDs
-#define OUT_BYTE_PER_MILISEC    (48*2*6)    //48ksps 2byte 6ch / milisec
+//target latency for buffer slack in mili sec (88msec for buffer full at 11 ITDs)
+#define TARGET_LATENCY          40
+//allowance of latency
+//latency is controled in TARGET_LATENCY - LATENCY_ALLOWANCE to TARGET_LATENCY + LATENCY_ALLOWANCE
+#define LATENCY_ALLOWANCE       30
+//output byte number to get 1msecond adjustment (48ksps 16bit 6ch at 1milisec)
+#define OUT_BYTE_PER_MILISEC    (48*2*6)    
 
+//sound data sending task
 void UsbSend(void const* arg) 
 {
+    //usb host
+    USBHostDac * p_usbdac = (USBHostDac *)arg;
+    //bank number of buffer (0 or 1)
     int Bank = 0;
-    int Latency,Adjmsec;
-    USBHostDac * p_usbdac = (USBHostDac *)arg;
+    //waiting latency of semaphore
+    int Latency;
+    //adjust time in mili second
+    int Adjmsec;
+    //number of skipping byte 
     int SkipBytes;
 
     Tmr.start();
     for(;;) 
     {
-        //reset timer to measure waiting time of semahore
+        //riset adjusting display
+        LedR = 0;
+        //reset timer to measure latency of semaphore
         Tmr.reset();
-        if(! Bank)
-        {
-            //wait FFT result prepaired
-            semW0.wait();
-        }
-        else
-        {
-            //wait FFT result prepaired
-            semW1.wait();
-        }
+        semW[Bank]->wait();
+        //get latency
         Latency = Tmr.read_ms();
         printf("Latency:%d\n",Latency);
-        //if semahore's waiting time is too long , data shortage have happen
-        if(Latency > 70) 
+        //if semahore's latency is too large, data shortage has happen
+        if(Latency > (TARGET_LATENCY + LATENCY_ALLOWANCE)) 
         {
-            Adjmsec = Latency - 40;
-            //it is not nessesary to fill over ITD buffer size
-            if(Adjmsec > 40) Adjmsec = 40;
+            //get period for adjustment 
+            Adjmsec = Latency - TARGET_LATENCY;
+            if(Adjmsec > TARGET_LATENCY) Adjmsec = TARGET_LATENCY;
             printf("Recover %dmsec\n",Adjmsec);
-            //put null data into sending queue to prevent data shortage
+            //put silence data into sending queue to prevent data shortage
             p_usbdac->send((uint8_t *)BufNull, Adjmsec * OUT_BYTE_PER_MILISEC, false);
-            //no demand for data skip because buffer have some vacancy
+            //data skip is unnecessary for buffer have some vacancy
             SkipBytes = 0;
+            //Show adjusting happend
+            LedR = 1;
         }
-        //if semahore's waiting time is too short, buffer is nearly full
-        else if(Latency < 10)
+        //if semahore's latency is too small, buffer is nearly full
+        else if(Latency < (TARGET_LATENCY - LATENCY_ALLOWANCE))
         {
-            Adjmsec = 40 - Latency;
-            if(Adjmsec > 40) Adjmsec = 40;
+            //get period for adjustment 
+            Adjmsec = TARGET_LATENCY - Latency;
+            if(Adjmsec > TARGET_LATENCY) Adjmsec = TARGET_LATENCY;
             //decrease sending data, to make some vacancy on the buffer
             SkipBytes = Adjmsec * OUT_BYTE_PER_MILISEC;
             printf("Skip %dmsec %dByte\n",Adjmsec,SkipBytes);
+            //Show adjusting happend
+            LedR = 1;
         }
         else
         {
             //no demand for data skip because buffer have regular vacancy
             SkipBytes = 0;
         }
-        LedB = 1;
         //send music data
         p_usbdac->send((uint8_t *)&BufW[Bank][SkipBytes / 4], OUT_DWORDS * 4 - SkipBytes, false);
-        LedB = 0;
         //next bank
         Bank++;
         Bank &= 1;
     }
 }
 
-void FFTSolve(void const* arg) {
+//FFT solving task
+void FFTSolve(void const* arg) 
+{
+    int Bank = 0;
     for(;;)  
     {  
-        semR0.wait();
-        LedG = 1;
-        //入力をフィルタして出力バッファに書き込む
-        FFTOverFlow = FLT_Filter((int16_t *)(BufW[0]),(int16_t *)(BufR[0]),!button);
-//      FFTOverFlow = FLT_Through((int16_t *)(BufW[0]),(int16_t *)BufR[0]);
-        LedG = 0;
-        semW0.release();
-        
-        semR1.wait();
-        LedG = 1;
-        //入力をフィルタして出力バッファに書き込む
-        FFTOverFlow = FLT_Filter((int16_t *)(BufW[1]),(int16_t *)(BufR[1]),!button);
-//      FFTOverFlow = FLT_Through((int16_t *)(BufW[1]),(int16_t *)BufR[1]);
-        LedG = 0;
-        semW1.release();
+        //wait for FFT sorce data ready
+        semR[Bank]->wait();
+        //show FFT is in work
+        LedB = 1;
+        //apply FIR filters and write the result on the buffer
+        FFTOverFlow = FLT_Filter((int16_t *)(BufW[Bank]),(int16_t *)(BufR[Bank]),!button);
+//      FFTOverFlow = FLT_Through((int16_t *)(BufW[Bank]),(int16_t *)BufR[Bank]);
+        //show FFT ended
+        LedB = 0;
+        //order to send the FFT result 
+        semW[Bank]->release();
+        //next bank
+        Bank++;
+        Bank &= 1;
     }
 }
 
-//receive 32768 sample of audio input from USB
+//receive 32768 sample of audio input from USB audio device
 int usbdevice_receive32k(USBAudio *paudio,uint32_t *Buf)
 {
     int i;
     
     //repat reading in 1 second
-    for(i = 0;i < 62;i++)
+    for(i = 0;i < 70;i++)
     {
         //attempting to read
         if(paudio->read32k(Buf))
@@ -165,8 +192,11 @@
 
 int main() 
 {
+    //receiving bank (0 or 1)
     int Bank = 0;
+    //receiving result
     int rc = 0;
+    //input mode 1:USB audio device 0:LINE-IN of USB DAC
     int InModeUSB = 1;
     
     printf("\n\nStarted\n");
@@ -174,7 +204,7 @@
     //initializing silence buffer
     memset((uint8_t *)BufNull,0,NULL_DWORDS * 4);
 
-    //USB sound device initialize
+    //USB audio device initialize
     static USBAudio audio(48000, 2, 8000, 1, 0x7180, 0x7500);
 
     //start Mass Strage Device host
@@ -191,14 +221,14 @@
         Thread::wait(500);
     }
     
-    //initializing FIR filters (setting up FFT and reading filter coefficient)
+    //initializing FIR filters (setting up FFT and reading filter coefficients)
     while(! FLT_Init())
     {
         printf("Filter initialization error\n");
         Thread::wait(500);
     }
 
-    //USBオーディオ送受信スレッドの生成
+    //create sending and FFT task
     Thread SendTask(UsbSend, &usbdac, osPriorityNormal, 1024 * 8);
     Thread FFTTask(FFTSolve, &usbdac, osPriorityNormal, 1024 * 8);
 
@@ -241,8 +271,6 @@
         //
         //      RECEIVING AUDIO DATA
         //
-        //show now in receive
-        if(! Bank) LedR = 1;
         //if using USB-INPUT
         if(InModeUSB)
         {
@@ -255,10 +283,8 @@
             //receive LINE-IN
             rc = usbdac.receive((uint8_t *)(BufR[Bank]), IN_DWORDS * 4);
         }
-        //receiving ends
-        LedR = 0;
         //
-        //      ERROR HANDLING and ALLOWING INPUT BUFFER
+        //      ERROR HANDLING and ORDERING TO START FFT
         //
         //if error occurs
         if(! rc)
@@ -274,15 +300,8 @@
         //if read correctly
         else
         {
-            //allow to use read buffer for FFT task
-            if(! Bank)
-            {
-                semR0.release();
-            }
-            else
-            {
-                semR1.release();
-            }      
+            //order to start FFT
+            semR[Bank]->release();
             //select next bank  
             Bank++;
             Bank &= 1;