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: DokuFFTPACK DokuUSBDevice DokuUSBHost DokuUSBHostWithIso mbed
Fork of Peach_AudioChannelDividerAndCompensator by
Revision 12:d12709edf53d, committed 2015-10-19
- 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;
