Important update: Arm Announces End of Life Timeline for Mbed. This site will be archived in July 2026. Read the full announcement.
Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
standard Generic Usb audio media device reverse effect

/*---------------------------------------------------------------------------- * Name: usbmain.c * Purpose: USB Audio Class Demo * Version: V1.20 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce * and distribute executable files created using this software for use * on NXP Semiconductors LPC microcontroller devices only. Nothing else * gives you the right to use this software. * * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. *---------------------------------------------------------------------------*/ #include "LPC17xx.h" /* LPC17xx definitions */ #include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbhw.h" #include "usbcore.h" #include "usbaudio.h" uint8_t Mute; /* Mute State */ uint32_t Volume; /* Volume Level */ #if USB_DMA uint32_t *InfoBuf = (uint32_t *)(DMA_BUF_ADR); short *DataBuf = (short *)(DMA_BUF_ADR + 4*P_C); #else uint32_t InfoBuf[P_C]; short DataBuf[B_S]; /* Data Buffer */ #endif uint16_t DataOut; /* Data Out Index */ uint16_t DataIn; /* Data In Index */ uint8_t DataRun; /* Data Stream Run State */ uint16_t PotVal; /* Potenciometer Value */ uint32_t VUM; /* VU Meter */ uint32_t Tick; /* Time Tick */ uint32_t arg; //uint32_t con; //uint32_t power; int semihost_powerdown() { uint32_t arg; return __semihost(USR_POWERDOWN, &arg); } /* * Get Potenciometer Value */ void get_potval (void) { uint32_t val; LPC_ADC->ADCR |= 0x01000000; /* Start A/D Conversion */ do { val = LPC_ADC->ADGDR; /* Read A/D Data Register */ } while ((val & 0x80000000) == 0); /* Wait for end of A/D Conversion */ LPC_ADC->ADCR &= ~0x01000000; /* Stop A/D Conversion */ PotVal = ((val >> 8) & 0xF8) + /* Extract Potenciometer Value */ ((val >> 7) & 0x08); } /* * Timer Counter 0 Interrupt Service Routine * executed each 31.25us (32kHz frequency) */ void TIMER0_IRQHandler(void) { long val; uint32_t cnt; if (DataRun) { /* Data Stream is running */ val = DataBuf[DataOut]; /* Get Audio Sample */ cnt = (DataIn - DataOut) & (B_S - 1); /* Buffer Data Count */ if (cnt == (B_S - P_C*P_S)) { /* Too much Data in Buffer */ DataOut++; /* Skip one Sample */ } if (cnt > (P_C*P_S)) { /* Still enough Data in Buffer */ DataOut++; /* Update Data Out Index */ } DataOut &= B_S - 1; /* Adjust Buffer Out Index */ if (val < 0) VUM -= val; /* Accumulate Neg Value */ else VUM += val; /* Accumulate Pos Value */ val *= Volume; /* Apply Volume Level */ val >>= 16; /* Adjust Value */ val += 0x8000; /* Add Bias */ val &= 0xFFFF; /* Mask Value */ } else { val = 0x8000; /* DAC Middle Point */ } if (Mute) { val = 0x8000; /* DAC Middle Point */ } //if (Mute){ //semihost_powerdown();} LPC_DAC->DACR = val & 0xFFC0; /* Set Speaker Output */ if ((Tick++ & 0x03FF) == 0) { /* On every 1024th Tick */ get_potval(); /* Get Potenciometer Value */ if (VolCur == 0x8000) { /* Check for Minimum Level */ Volume = 0; /* No Sound */ } else { Volume = VolCur * PotVal; /* Chained Volume Level */ } val = VUM >> 20; /* Scale Accumulated Value */ VUM = 0; /* Clear VUM */ if (val > 7) val = 7; /* Limit Value */ } LPC_TIM0->IR = 1; /* Clear Interrupt Flag */ } /***************************************************************************** ** Main Function main() ******************************************************************************/ int main (void) { volatile uint32_t pclkdiv, pclk; semihost_powerdown(); SystemInit(); LPC_PINCON->PINSEL1 &=~((0x03<<18)|(0x03<<20)); /* P0.25, A0.0, function 01, P0.26 AOUT, function 10 */ LPC_PINCON->PINSEL1 |= ((0x01<<18)|(0x02<<20)); /* Enable CLOCK into ADC controller */ LPC_SC->PCONP |= (1 << 12); LPC_ADC->ADCR = 0x00200E04; /* ADC: 10-bit AIN2 @ 4MHz */ LPC_DAC->DACR = 0x00008000; /* DAC Output set to Middle Point */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ /* Bit 2~3 is for TIMER0 */ pclkdiv = (LPC_SC->PCLKSEL0 >> 2) & 0x03; switch ( pclkdiv ) { case 0x00: default: pclk = SystemFrequency/4; break; case 0x01: pclk = SystemFrequency; break; case 0x02: pclk = SystemFrequency/2; break; case 0x03: pclk = SystemFrequency/8; break; } LPC_TIM0->MR0 = pclk/DATA_FREQ - 1; /* TC0 Match Value 0 */ LPC_TIM0->MCR = 3; /* TCO Interrupt and Reset on MR0 */ LPC_TIM0->TCR = 1; /* TC0 Enable */ NVIC_EnableIRQ(TIMER0_IRQn); USB_Init(); /* USB Initialization */ USB_Connect(TRUE); /* USB Connect */ /********* The main Function is an endless loop ***********/ while( 1 ); } int result; /****************************************************************************** ** End Of File ******************************************************************************/
Throw a dog a bone will you
/*---------------------------------------------------------------------------- * Name: usbmain.c * Purpose: USB Audio Class Demo * Version: V1.20 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce * and distribute executable files created using this software for use * on NXP Semiconductors LPC microcontroller devices only. Nothing else * gives you the right to use this software. * * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. *---------------------------------------------------------------------------*/ #include "LPC17xx.h" /* LPC17xx definitions */ #include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbhw.h" #include "usbcore.h" #include "usbaudio.h" uint8_t Mute; /* Mute State */ uint32_t Volume; /* Volume Level */ #if USB_DMA uint32_t *InfoBuf = (uint32_t *)(DMA_BUF_ADR); short *DataBuf = (short *)(DMA_BUF_ADR + 4*P_C); #else uint32_t InfoBuf[P_C]; short DataBuf[B_S]; /* Data Buffer */ #endif uint16_t DataOut; /* Data Out Index */ uint16_t DataIn; /* Data In Index */ int DataOut = 0; int Direction = 1; uint8_t DataRun; /* Data Stream Run State */ uint16_t PotVal; /* Potenciometer Value */ uint32_t VUM; /* VU Meter */ uint32_t Tick; /* Time Tick */ uint32_t arg; //uint32_t con; //uint32_t power; int semihost_powerdown() { uint32_t arg; return __semihost(USR_POWERDOWN, &arg); } /* * Get Potenciometer Value */ void get_potval (void) { uint32_t val; LPC_ADC->ADCR |= 0x01000000; /* Start A/D Conversion */ do { val = LPC_ADC->ADGDR; /* Read A/D Data Register */ } while ((val & 0x80000000) == 0); /* Wait for end of A/D Conversion */ LPC_ADC->ADCR &= ~0x01000000; /* Stop A/D Conversion */ PotVal = ((val >> 8) & 0xF8) + /* Extract Potenciometer Value */ ((val >> 7) & 0x08); } /* * Timer Counter 0 Interrupt Service Routine * executed each 31.25us (32kHz frequency) */ void TIMER0_IRQHandler(void) { long val; uint32_t cnt; if (DataRun) { /* Data Stream is running */ val = DataBuf[DataOut]; /* Get Audio Sample */ if (DataOut < 0) { // Now have a chunk to be played back DataRun = val; // Reverse the direction of playback and recording Direction *= -1; DataOut = 0; } else if (DataOut >= DataRun) { // Now have a chunk to be played back DataRun = val; // Reverse the direction of playback and recording Direction *= -1; DataOut = DataRun - 1; } } } } //cnt = (DataIn - DataOut) & (B_S - 1); /* Buffer Data Count */ //if (cnt == (B_S - P_C*P_S)) { /* Too much Data in Buffer */ //DataOut++; /* Skip one Sample */ } //if (cnt > (P_C*P_S)) { /* Still enough Data in Buffer */ //DataOut++; /* Update Data Out Index */ } //DataOut &= B_S - 1; /* Adjust Buffer Out Index */ if (val < 0) VUM -= val; /* Accumulate Neg Value */ else VUM += val; /* Accumulate Pos Value */ val *= Volume; /* Apply Volume Level */ val >>= 16; /* Adjust Value */ val += 0x8000; /* Add Bias */ val &= 0xFFFF; /* Mask Value */ } else { val = 0x8000; /* DAC Middle Point */ } if (Mute) { val = 0x8000; /* DAC Middle Point */ } //if (Mute){ //semihost_powerdown();} LPC_DAC->DACR = val & 0xFFC0; /* Set Speaker Output */ if ((Tick++ & 0x03FF) == 0) { /* On every 1024th Tick */ get_potval(); /* Get Potenciometer Value */ if (VolCur == 0x8000) { /* Check for Minimum Level */ Volume = 0; /* No Sound */ } else { Volume = VolCur * PotVal; /* Chained Volume Level */ } val = VUM >> 20; /* Scale Accumulated Value */ VUM = 0; /* Clear VUM */ if (val > 7) val = 7; /* Limit Value */ } LPC_TIM0->IR = 1; /* Clear Interrupt Flag */ } /***************************************************************************** ** Main Function main() ******************************************************************************/ int main (void) { volatile uint32_t pclkdiv, pclk; semihost_powerdown(); SystemInit(); LPC_PINCON->PINSEL1 &=~((0x03<<18)|(0x03<<20)); /* P0.25, A0.0, function 01, P0.26 AOUT, function 10 */ LPC_PINCON->PINSEL1 |= ((0x01<<18)|(0x02<<20)); /* Enable CLOCK into ADC controller */ LPC_SC->PCONP |= (1 << 12); LPC_ADC->ADCR = 0x00200E04; /* ADC: 10-bit AIN2 @ 4MHz */ LPC_DAC->DACR = 0x00008000; /* DAC Output set to Middle Point */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ /* Bit 2~3 is for TIMER0 */ pclkdiv = (LPC_SC->PCLKSEL0 >> 2) & 0x03; switch ( pclkdiv ) { case 0x00: default: pclk = SystemFrequency/4; break; case 0x01: pclk = SystemFrequency; break; case 0x02: pclk = SystemFrequency/2; break; case 0x03: pclk = SystemFrequency/8; break; } LPC_TIM0->MR0 = pclk/DATA_FREQ - 1; /* TC0 Match Value 0 */ LPC_TIM0->MCR = 3; /* TCO Interrupt and Reset on MR0 */ LPC_TIM0->TCR = 1; /* TC0 Enable */ NVIC_EnableIRQ(TIMER0_IRQn); USB_Init(); /* USB Initialization */ USB_Connect(TRUE); /* USB Connect */ /********* The main Function is an endless loop ***********/ while( 1 ); } int result; /****************************************************************************** ** End Of File ******************************************************************************/
Come on stop being a spoilsport am I close??
/*---------------------------------------------------------------------------- * Name: usbmain.c * Purpose: USB Audio Class Demo * Version: V1.20 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce * and distribute executable files created using this software for use * on NXP Semiconductors LPC microcontroller devices only. Nothing else * gives you the right to use this software. * * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. *---------------------------------------------------------------------------*/ #include "LPC17xx.h" /* LPC17xx definitions */ #include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbhw.h" #include "usbcore.h" #include "usbaudio.h" uint8_t Mute; /* Mute State */ uint32_t Volume; /* Volume Level */ #if USB_DMA uint32_t *InfoBuf = (uint32_t *)(DMA_BUF_ADR); short *DataBuf = (short *)(DMA_BUF_ADR + 4*P_C); #else uint32_t InfoBuf[P_C]; short DataBuf[B_S]; /* Data Buffer */ #endif uint16_t DataOut; /* Data Out Index */ uint16_t DataIn; /* Data In Index */ uint8_t DataRun; /* Data Stream Run State */ uint16_t PotVal; /* Potenciometer Value */ uint32_t VUM; /* VU Meter */ uint32_t Tick; /* Time Tick */ /* * Get Potenciometer Value */ void get_potval (void) { uint32_t val; LPC_ADC->ADCR |= 0x01000000; /* Start A/D Conversion */ do { val = LPC_ADC->ADGDR; /* Read A/D Data Register */ } while ((val & 0x80000000) == 0); /* Wait for end of A/D Conversion */ LPC_ADC->ADCR &= ~0x01000000; /* Stop A/D Conversion */ PotVal = ((val >> 8) & 0xF8) + /* Extract Potenciometer Value */ ((val >> 7) & 0x08); } /* * Timer Counter 0 Interrupt Service Routine * executed each 31.25us (32kHz frequency) */ void TIMER0_IRQHandler(void) { long val; uint32_t cnt; int Direction = 1; int ChunkSize = 9024; if (DataRun) { /* Data Stream is running */ val = DataBuf[DataOut]; /* Get Audio Sample */ cnt = (DataIn - DataOut) & (B_S - 1); /* Buffer Data Count */ if (cnt == (B_S - P_C*P_S)) { /* Too much Data in Buffer */ DataOut++; /* Skip one Sample */ } if (cnt > (P_C*P_S)) { /* Still enough Data in Buffer */ DataOut++; /* Update Data Out Index */ } DataOut &= B_S - 1; /* Adjust Buffer Out Index */ if (val < 0) VUM -= val; /* Accumulate Neg Value */ else VUM += val; /* Accumulate Pos Value */ if (val < 0) { // Now have a chunk to be played back DataRun = 1; // Reverse the direction of playback and recording Direction *= -1; val = 0; } else if (val >= ChunkSize) { // Now have a chunk to be played back DataRun = 1; // Reverse the direction of playback and recording Direction *= -1; val = ChunkSize - 1; } } } //val *= Volume; /* Apply Volume Level */ //val >>= 16; /* Adjust Value */ //val += 0x8000; /* Add Bias */ //val &= 0xFFFF; /* Mask Value */ //} else { //val = 0x8000; /* DAC Middle Point */ //} //if (Mute) { //val = 0x8000; /* DAC Middle Point */ //} // LPC_DAC->DACR = val & 0xFFC0; /* Set Speaker Output */ //if ((Tick++ & 0x03FF) == 0) { /* On every 1024th Tick */ //get_potval(); /* Get Potenciometer Value */ //if (VolCur == 0x8000) { /* Check for Minimum Level */ // Volume = 0; /* No Sound */ //} else { //Volume = VolCur * PotVal; /* Chained Volume Level */ //} //val = VUM >> 20; /* Scale Accumulated Value */ //VUM = 0; /* Clear VUM */ //if (val > 7) val = 7; /* Limit Value */ //} // LPC_TIM0->IR = 1; /* Clear Interrupt Flag */ //} /***************************************************************************** ** Main Function main() ******************************************************************************/ int main (void) { volatile uint32_t pclkdiv, pclk; SystemInit(); LPC_PINCON->PINSEL1 &=~((0x03<<18)|(0x03<<20)); /* P0.25, A0.0, function 01, P0.26 AOUT, function 10 */ LPC_PINCON->PINSEL1 |= ((0x01<<18)|(0x02<<20)); /* Enable CLOCK into ADC controller */ LPC_SC->PCONP |= (1 << 12); LPC_ADC->ADCR = 0x00200E04; /* ADC: 10-bit AIN2 @ 4MHz */ LPC_DAC->DACR = 0x00008000; /* DAC Output set to Middle Point */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ /* Bit 2~3 is for TIMER0 */ pclkdiv = (LPC_SC->PCLKSEL0 >> 2) & 0x03; switch ( pclkdiv ) { case 0x00: default: pclk = SystemFrequency/4; break; case 0x01: pclk = SystemFrequency; break; case 0x02: pclk = SystemFrequency/2; break; case 0x03: pclk = SystemFrequency/8; break; } LPC_TIM0->MR0 = pclk/DATA_FREQ - 1; /* TC0 Match Value 0 */ //LPC_TIM0->MCR = 3; /* TCO Interrupt and Reset on MR0 */ // LPC_TIM0->TCR = 1; /* TC0 Enable */ NVIC_EnableIRQ(TIMER0_IRQn); USB_Init(); /* USB Initialization */ USB_Connect(TRUE); /* USB Connect */ /********* The main Function is an endless loop ***********/ while( 1 ); } /****************************************************************************** ** End Of File ******************************************************************************/
Anycloser hhahaha
/*---------------------------------------------------------------------------- * Name: usbmain.c * Purpose: USB Audio Class Demo * Version: V1.20 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce * and distribute executable files created using this software for use * on NXP Semiconductors LPC microcontroller devices only. Nothing else * gives you the right to use this software. * * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. *---------------------------------------------------------------------------*/ #include "LPC17xx.h" /* LPC17xx definitions */ #include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbhw.h" #include "usbcore.h" #include "usbaudio.h" uint8_t Mute; /* Mute State */ uint32_t Volume; /* Volume Level */ #if USB_DMA uint32_t *InfoBuf = (uint32_t *)(DMA_BUF_ADR); short *DataBuf = (short *)(DMA_BUF_ADR + 4*P_C); #else uint32_t InfoBuf[P_C]; short DataBuf[B_S]; /* Data Buffer */ #endif uint16_t DataOut; /* Data Out Index */ uint16_t DataIn; /* Data In Index */ uint8_t DataRun; /* Data Stream Run State */ uint16_t PotVal; /* Potenciometer Value */ uint32_t VUM; /* VU Meter */ uint32_t Tick; /* Time Tick */ uint32_t arg; //uint32_t con; //uint32_t power; //int semihost_powerdown() { // uint32_t arg; //return __semihost(USR_POWERDOWN, &arg); //} /* * Get Potenciometer Value */ void get_potval (void) { uint32_t val; LPC_ADC->ADCR |= 0x01000000; /* Start A/D Conversion */ do { val = LPC_ADC->ADGDR; /* Read A/D Data Register */ } while ((val & 0x80000000) == 0); /* Wait for end of A/D Conversion */ LPC_ADC->ADCR &= ~0x01000000; /* Stop A/D Conversion */ PotVal = ((val >> 8) & 0xF8) + /* Extract Potenciometer Value */ ((val >> 7) & 0x08); } /* * Timer Counter 0 Interrupt Service Routine * executed each 31.25us (32kHz frequency) */ void TIMER0_IRQHandler(void) { long val; uint32_t cnt; long val1; int Direction = 1; int ChunkSize = 9024; if (DataRun) { /* Data Stream is running */ val = DataBuf[DataOut]; val1 = DataBuf[DataOut]; /* Get Audio Sample */ cnt = (DataIn - DataOut) & (B_S - 1); /* Buffer Data Count */ if (cnt == (B_S - P_C*P_S)) { /* Too much Data in Buffer */ DataOut++; /* Skip one Sample */ } if (cnt > (P_C*P_S)) { /* Still enough Data in Buffer */ DataOut++; /* Update Data Out Index */ } DataOut &= B_S - 1; /* Adjust Buffer Out Index */ if (val < 0) VUM -= val; /* Accumulate Neg Value */ else VUM += val; /* Accumulate Pos Value */ val *= Volume; /* Apply Volume Level */ val >>= 16; /* Adjust Value */ val += 0x8000; /* Add Bias */ val &= 0xFFFF; /* Mask Value */ } else { val = 0x8000; /* DAC Middle Point */ } if (Mute) { val = 0x8000; /* DAC Middle Point */ } if (val1 < 0) { // Now have a chunk to be played back DataRun = 1; // Reverse the direction of playback and recording Direction *= -1; val1 = 0; } else if (val1 >= ChunkSize) { // Now have a chunk to be played back DataRun = 1; // Reverse the direction of playback and recording Direction *= -1; val1 = ChunkSize - 1; } //if (Mute){ //semihost_powerdown();} LPC_DAC->DACR = val & 0xFFC0; /* Set Speaker Output */ LPC_DAC->DACR = val1 & 0xFFC0; if ((Tick++ & 0x03FF) == 0) { /* On every 1024th Tick */ get_potval(); /* Get Potenciometer Value */ if (VolCur == 0x8000) { /* Check for Minimum Level */ Volume = 0; /* No Sound */ } else { Volume = VolCur * PotVal; /* Chained Volume Level */ } val = VUM >> 20; /* Scale Accumulated Value */ VUM = 0; /* Clear VUM */ if (val > 7) val = 7; /* Limit Value */ } LPC_TIM0->IR = 1; /* Clear Interrupt Flag */ } /***************************************************************************** ** Main Function main() ******************************************************************************/ int main (void) { volatile uint32_t pclkdiv, pclk; //semihost_powerdown(); SystemInit(); LPC_PINCON->PINSEL1 &=~((0x03<<18)|(0x03<<20)); /* P0.25, A0.0, function 01, P0.26 AOUT, function 10 */ LPC_PINCON->PINSEL1 |= ((0x01<<18)|(0x02<<20)); /* Enable CLOCK into ADC controller */ LPC_SC->PCONP |= (1 << 12); LPC_ADC->ADCR = 0x00200E04; /* ADC: 10-bit AIN2 @ 4MHz */ LPC_DAC->DACR = 0x00008000; /* DAC Output set to Middle Point */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ /* Bit 2~3 is for TIMER0 */ pclkdiv = (LPC_SC->PCLKSEL0 >> 2) & 0x03; switch ( pclkdiv ) { case 0x00: default: pclk = SystemFrequency/4; break; case 0x01: pclk = SystemFrequency; break; case 0x02: pclk = SystemFrequency/2; break; case 0x03: pclk = SystemFrequency/8; break; } LPC_TIM0->MR0 = pclk/DATA_FREQ - 1; /* TC0 Match Value 0 */ LPC_TIM0->MCR = 3; /* TCO Interrupt and Reset on MR0 */ LPC_TIM0->TCR = 1; /* TC0 Enable */ NVIC_EnableIRQ(TIMER0_IRQn); USB_Init(); /* USB Initialization */ USB_Connect(TRUE); /* USB Connect */ /********* The main Function is an endless loop ***********/ while( 1 ); } int result; /****************************************************************************** ** End Of File ******************************************************************************/
Can somebody tell me.. the Mbed is capable of doing this right someone said... reverse the sample index ordering??
I want the mbed to do it not windows.
use a ringbuffer and read and write in opposite directions.
DMA can only do one direction AFAIK (counting up) so you need to write a buffer in reverse direction in software and let the DMA do the playback part. You can use two buffers and switch them on the 'end-of-DMA' interrupt for example. You can also use a simple ticker interrupt and read and write a ringbuffer on each 'tick', again with opposite directions.
Gert van der Knokke wrote:
use a ringbuffer and read and write in opposite directions.
DMA can only do one direction AFAIK (counting up) so you need to write a buffer in reverse direction in software and let the DMA do the playback part. You can use two buffers and switch them on the 'end-of-DMA' interrupt for example. You can also use a simple ticker interrupt and read and write a ringbuffer on each 'tick', again with opposite directions.
You will have to point to a example, not sure what you mean
I have just done this code tho still does not work , should I not be able to do the same that was done with the guitar code http://mbed.org/users/mbed2f/programs/EnterYodaonereverseeffectsguitar/lukza3/docs/main_8cpp_source.html
As you can see in the code below.. put the audio in a buffer write the buffer to the speaker then put more audio in the buffer .. just look at code below.. I can't explain but the same thing as adam code..
freeing and writing reading from the buffer where a space was made from the previous write??
Audio goes into the chunk and play the chunk backwards
It should be as simple as the audio goes into Mbed memory and then mbed plays it backwards.. it should be that easy just like the guitar code of adams:)
I can't explain in words if you look at code I think I am close to doing it this way:)
/*---------------------------------------------------------------------------- * Name: usbmain.c * Purpose: USB Audio Class Demo * Version: V1.20 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce * and distribute executable files created using this software for use * on NXP Semiconductors LPC microcontroller devices only. Nothing else * gives you the right to use this software. * * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. *---------------------------------------------------------------------------*/ #include "LPC17xx.h" /* LPC17xx definitions */ #include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbhw.h" #include "usbcore.h" #include "usbaudio.h" uint8_t Mute; /* Mute State */ uint32_t Volume; /* Volume Level */ #if USB_DMA uint32_t *InfoBuf = (uint32_t *)(DMA_BUF_ADR); short *DataBuf = (short *)(DMA_BUF_ADR + 4*P_C); #else uint32_t InfoBuf[P_C]; short DataBuf[B_S]; /* Data Buffer */ #endif uint16_t DataOut; /* Data Out Index */ uint16_t DataIn; /* Data In Index */ uint8_t DataRun; /* Data Stream Run State */ uint16_t PotVal; /* Potenciometer Value */ uint32_t VUM; /* VU Meter */ uint32_t Tick; /* Time Tick */ uint32_t arg; //uint32_t con; //uint32_t power; //int semihost_powerdown() { // uint32_t arg; //return __semihost(USR_POWERDOWN, &arg); //} /* * Get Potenciometer Value */ void get_potval (void) { uint32_t val; LPC_ADC->ADCR |= 0x01000000; /* Start A/D Conversion */ do { val = LPC_ADC->ADGDR; /* Read A/D Data Register */ } while ((val & 0x80000000) == 0); /* Wait for end of A/D Conversion */ LPC_ADC->ADCR &= ~0x01000000; /* Stop A/D Conversion */ PotVal = ((val >> 8) & 0xF8) + /* Extract Potenciometer Value */ ((val >> 7) & 0x08); } /* * Timer Counter 0 Interrupt Service Routine * executed each 31.25us (32kHz frequency) */ void TIMER0_IRQHandler(void) { long val; // uint32_t cnt; long val1; int Direction = 1; int ChunkSize = 9024; { unsigned short ReadSample = 0xFFFF; if (DataRun) { /* Data Stream is running */ //val = DataBuf[DataOut]; val1 = DataBuf[DataOut]; LPC_DAC->DACR = val1 & 0xFFC0; /* Get Audio Sample */ } val = DataOut; ReadSample = val1 ; //DataBuf[DataOut] = ReadSample = DataRun; DataBuf[DataOut] = ReadSample; val += Direction; if (val < 0) { // Now have a chunk to be played back DataRun = 1; // Reverse the direction of playback and recording Direction *= -1; val = 0; } else if (val >= ChunkSize) { // Now have a chunk to be played back DataRun = 1; // Reverse the direction of playback and recording Direction *= -1; val = ChunkSize - 1; //cnt = (DataIn - DataOut) & (B_S - 1); /* Buffer Data Count */ //if (cnt == (B_S - P_C*P_S)) { /* Too much Data in Buffer */ //DataOut++; /* Skip one Sample */ //} //if (cnt > (P_C*P_S)) { /* Still enough Data in Buffer */ //DataOut++; /* Update Data Out Index */ //} //DataOut &= B_S - 1; /* Adjust Buffer Out Index */ //if (val < 0) VUM -= val; /* Accumulate Neg Value */ //else VUM += val; /* Accumulate Pos Value */ //val *= Volume; /* Apply Volume Level */ //val >>= 16; /* Adjust Value */ //val += 0x8000; /* Add Bias */ //val &= 0xFFFF; /* Mask Value */ //} else { //val = 0x8000; /* DAC Middle Point */ //} //if (Mute) { //val = 0x8000; /* DAC Middle Point */ //} //if (Mute){ //semihost_powerdown();} //LPC_DAC->DACR = val & 0xFFC0; /* Set Speaker Output */ //LPC_DAC->DACR = val1 & 0xFFC0; //if ((Tick++ & 0x03FF) == 0) { /* On every 1024th Tick */ //get_potval(); /* Get Potenciometer Value */ //if (VolCur == 0x8000) { /* Check for Minimum Level */ //Volume = 0; /* No Sound */ //} else { //Volume = VolCur * PotVal; /* Chained Volume Level */ //} //val = VUM >> 20; /* Scale Accumulated Value */ //VUM = 0; /* Clear VUM */ //if (val > 7) val = 7; /* Limit Value */ //} LPC_TIM0->IR = 1; /* Clear Interrupt Flag */ } } } /***************************************************************************** ** Main Function main() ******************************************************************************/ int main (void) { volatile uint32_t pclkdiv, pclk; //semihost_powerdown(); SystemInit(); LPC_PINCON->PINSEL1 &=~((0x03<<18)|(0x03<<20)); /* P0.25, A0.0, function 01, P0.26 AOUT, function 10 */ LPC_PINCON->PINSEL1 |= ((0x01<<18)|(0x02<<20)); /* Enable CLOCK into ADC controller */ LPC_SC->PCONP |= (1 << 12); LPC_ADC->ADCR = 0x00200E04; /* ADC: 10-bit AIN2 @ 4MHz */ LPC_DAC->DACR = 0x00008000; /* DAC Output set to Middle Point */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ /* Bit 2~3 is for TIMER0 */ pclkdiv = (LPC_SC->PCLKSEL0 >> 2) & 0x03; switch ( pclkdiv ) { case 0x00: default: pclk = SystemFrequency/4; break; case 0x01: pclk = SystemFrequency; break; case 0x02: pclk = SystemFrequency/2; break; case 0x03: pclk = SystemFrequency/8; break; } LPC_TIM0->MR0 = pclk/DATA_FREQ - 1; /* TC0 Match Value 0 */ LPC_TIM0->MCR = 3; /* TCO Interrupt and Reset on MR0 */ LPC_TIM0->TCR = 1; /* TC0 Enable */ NVIC_EnableIRQ(TIMER0_IRQn); USB_Init(); /* USB Initialization */ USB_Connect(TRUE); /* USB Connect */ /********* The main Function is an endless loop ***********/ while( 1 ); } int result; /****************************************************************************** ** End Of File ******************************************************************************/
Oh well
/*---------------------------------------------------------------------------- * Name: usbmain.c * Purpose: USB Audio Class Demo * Version: V1.20 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce * and distribute executable files created using this software for use * on NXP Semiconductors LPC microcontroller devices only. Nothing else * gives you the right to use this software. * * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. *---------------------------------------------------------------------------*/ #include "LPC17xx.h" /* LPC17xx definitions */ #include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbhw.h" #include "usbcore.h" #include "usbaudio.h" uint8_t Mute; /* Mute State */ uint32_t Volume; /* Volume Level */ #if USB_DMA uint32_t *InfoBuf = (uint32_t *)(DMA_BUF_ADR); short *DataBuf = (short *)(DMA_BUF_ADR + 4*P_C); #else uint32_t InfoBuf[P_C]; short DataBuf[B_S]; /* Data Buffer */ #endif uint16_t DataOut; /* Data Out Index */ uint16_t DataIn; /* Data In Index */ uint8_t DataRun; /* Data Stream Run State */ uint16_t PotVal; /* Potenciometer Value */ uint32_t VUM; /* VU Meter */ uint32_t Tick; /* Time Tick */ uint32_t arg; //uint32_t con; //uint32_t power; //int semihost_powerdown() { // uint32_t arg; //return __semihost(USR_POWERDOWN, &arg); //} /* * Get Potenciometer Value */ void get_potval (void) { uint32_t val; LPC_ADC->ADCR |= 0x01000000; /* Start A/D Conversion */ do { val = LPC_ADC->ADGDR; /* Read A/D Data Register */ } while ((val & 0x80000000) == 0); /* Wait for end of A/D Conversion */ LPC_ADC->ADCR &= ~0x01000000; /* Stop A/D Conversion */ PotVal = ((val >> 8) & 0xF8) + /* Extract Potenciometer Value */ ((val >> 7) & 0x08); } /* * Timer Counter 0 Interrupt Service Routine * executed each 31.25us (32kHz frequency) */ void TIMER0_IRQHandler(void) { // long val; // uint32_t cnt; long val1; const uint32_t BufferSize = 15 * 1024; static unsigned short Buffer[BufferSize]; int Index = 0; int Direction = 1; int ChunkSize = BufferSize; { unsigned short ReadSample = 0xFFFF; val1 = DataBuf[DataOut]; Buffer[BufferSize] = val1; DataOut = Index; if (DataRun) { /* Data Stream is running */ //val = DataBuf[DataOut]; val1 = Buffer[Index]; LPC_DAC->DACR = val1 & 0xFFC0; /* Get Audio Sample */ } //Index = DataOut; ReadSample = val1 ; //DataBuf[DataOut] = ReadSample = DataRun; Buffer[Index] = ReadSample; Index += Direction; if (Index < 0) { // Now have a chunk to be played back DataRun = 1; // Reverse the direction of playback and recording Direction *= -1; Index = 0; } else if (Index >= ChunkSize) { // Now have a chunk to be played back DataRun = 1; // Reverse the direction of playback and recording Direction *= -1; Index = ChunkSize - 1; //cnt = (DataIn - DataOut) & (B_S - 1); /* Buffer Data Count */ //if (cnt == (B_S - P_C*P_S)) { /* Too much Data in Buffer */ //DataOut++; /* Skip one Sample */ //} //if (cnt > (P_C*P_S)) { /* Still enough Data in Buffer */ //DataOut++; /* Update Data Out Index */ //} //DataOut &= B_S - 1; /* Adjust Buffer Out Index */ //if (val < 0) VUM -= val; /* Accumulate Neg Value */ //else VUM += val; /* Accumulate Pos Value */ //val *= Volume; /* Apply Volume Level */ //val >>= 16; /* Adjust Value */ //val += 0x8000; /* Add Bias */ //val &= 0xFFFF; /* Mask Value */ //} else { //val = 0x8000; /* DAC Middle Point */ //} //if (Mute) { //val = 0x8000; /* DAC Middle Point */ //} //if (Mute){ //semihost_powerdown();} //LPC_DAC->DACR = val & 0xFFC0; /* Set Speaker Output */ //LPC_DAC->DACR = val1 & 0xFFC0; //if ((Tick++ & 0x03FF) == 0) { /* On every 1024th Tick */ //get_potval(); /* Get Potenciometer Value */ //if (VolCur == 0x8000) { /* Check for Minimum Level */ //Volume = 0; /* No Sound */ //} else { //Volume = VolCur * PotVal; /* Chained Volume Level */ //} //val = VUM >> 20; /* Scale Accumulated Value */ //VUM = 0; /* Clear VUM */ //if (val > 7) val = 7; /* Limit Value */ //} LPC_TIM0->IR = 1; /* Clear Interrupt Flag */ } } } /***************************************************************************** ** Main Function main() ******************************************************************************/ int main (void) { volatile uint32_t pclkdiv, pclk; //semihost_powerdown(); SystemInit(); LPC_PINCON->PINSEL1 &=~((0x03<<18)|(0x03<<20)); /* P0.25, A0.0, function 01, P0.26 AOUT, function 10 */ LPC_PINCON->PINSEL1 |= ((0x01<<18)|(0x02<<20)); /* Enable CLOCK into ADC controller */ LPC_SC->PCONP |= (1 << 12); LPC_ADC->ADCR = 0x00200E04; /* ADC: 10-bit AIN2 @ 4MHz */ LPC_DAC->DACR = 0x00008000; /* DAC Output set to Middle Point */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ /* Bit 2~3 is for TIMER0 */ pclkdiv = (LPC_SC->PCLKSEL0 >> 2) & 0x03; switch ( pclkdiv ) { case 0x00: default: pclk = SystemFrequency/4; break; case 0x01: pclk = SystemFrequency; break; case 0x02: pclk = SystemFrequency/2; break; case 0x03: pclk = SystemFrequency/8; break; } LPC_TIM0->MR0 = pclk/DATA_FREQ - 1; /* TC0 Match Value 0 */ LPC_TIM0->MCR = 3; /* TCO Interrupt and Reset on MR0 */ LPC_TIM0->TCR = 1; /* TC0 Enable */ NVIC_EnableIRQ(TIMER0_IRQn); USB_Init(); /* USB Initialization */ USB_Connect(TRUE); /* USB Connect */ /********* The main Function is an endless loop ***********/ while( 1 ); } int result; /****************************************************************************** ** End Of File ******************************************************************************/
Gert van der Knokke wrote:
write a buffer in reverse direction
Ok it's take a while to sink in sometimes, So the guitar code it not using DMA..how do I write a buffer in reverse direction... And the Mbed does this not to be done in a software app in windows because I don't want to do it that way..I want to plug it into anything like a hi fi or a cd player or maybe Squeezebox Touch.. anything that accepts a windows standard generic usb device, altho some of these will need spdif tho:) getting a head of myself tho and need to do just usb for now:)
We get working thanks you know who you are
/*---------------------------------------------------------------------------- * Name: usbmain.c * Purpose: USB Audio Class Demo * Version: V1.20 *---------------------------------------------------------------------------- * This software is supplied "AS IS" without any warranties, express, * implied or statutory, including but not limited to the implied * warranties of fitness for purpose, satisfactory quality and * noninfringement. Keil extends you a royalty-free right to reproduce * and distribute executable files created using this software for use * on NXP Semiconductors LPC microcontroller devices only. Nothing else * gives you the right to use this software. * * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. *---------------------------------------------------------------------------*/ #include "LPC17xx.h" /* LPC17xx definitions */ #include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbhw.h" #include "usbcore.h" #include "usbaudio.h" uint8_t Mute; /* Mute State */ uint32_t Volume; /* Volume Level */ #if USB_DMA uint32_t *InfoBuf = (uint32_t *)(DMA_BUF_ADR); short *DataBuf = (short *)(DMA_BUF_ADR + 4*P_C); #else uint32_t InfoBuf[P_C]; short DataBuf[B_S]; /* Data Buffer */ #endif uint16_t DataOut; /* Data Out Index */ uint16_t DataIn; /* Data In Index */ uint8_t DataRun; /* Data Stream Run State */ uint16_t PotVal; /* Potenciometer Value */ uint32_t VUM; /* VU Meter */ uint32_t Tick; /* Time Tick */ uint32_t arg; //uint32_t con; //uint32_t power; //int semihost_powerdown() { // uint32_t arg; //return __semihost(USR_POWERDOWN, &arg); //} /* * Get Potenciometer Value */ void get_potval (void) { uint32_t val; LPC_ADC->ADCR |= 0x01000000; /* Start A/D Conversion */ do { val = LPC_ADC->ADGDR; /* Read A/D Data Register */ } while ((val & 0x80000000) == 0); /* Wait for end of A/D Conversion */ LPC_ADC->ADCR &= ~0x01000000; /* Stop A/D Conversion */ PotVal = ((val >> 8) & 0xF8) + /* Extract Potenciometer Value */ ((val >> 7) & 0x08); } /* * Timer Counter 0 Interrupt Service Routine * executed each 31.25us (32kHz frequency) */ void TIMER0_IRQHandler(void) { long val; uint32_t cnt; unsigned short PlaySample; if (DataRun) { /* Data Stream is running */ val = DataBuf[DataOut]; /* Get Audio Sample */ cnt = (DataIn - DataOut) & (B_S - 1); /* Buffer Data Count */ if (cnt == (B_S - P_C*P_S)) { /* Too much Data in Buffer */ DataOut++; /* Skip one Sample */ } if (cnt > (P_C*P_S)) { /* Still enough Data in Buffer */ DataOut++; /* Update Data Out Index */ } DataOut &= B_S - 1; /* Adjust Buffer Out Index */ if (val < 0) VUM -= val; /* Accumulate Neg Value */ else VUM += val; /* Accumulate Pos Value */ val *= Volume; /* Apply Volume Level */ val >>= 16; /* Adjust Value */ val += 0x8000; /* Add Bias */ val &= 0xFFFF; /* Mask Value */ } else { val = 0x8000; /* DAC Middle Point */ } if (Mute) { val = 0x8000; /* DAC Middle Point */ } //if (Mute){ //semihost_powerdown();} /* ADAMGR: Inserting my May 30th reversing code here!!! */ { static const unsigned int BufferSize = 15 * 1024; static unsigned short Buffer[BufferSize]; static int Index = 0; static int Direction = 1; static int Playback = FALSE; static int ChunkSize = BufferSize; unsigned short ReadSample; /* Default PlaySample to the current sample from USB buffer. */ PlaySample = val; /* Read out the sample from the buffer to be played back */ if (Playback) { PlaySample = Buffer[Index]; } /* Obtain current audio sample from the USB buffer. */ ReadSample = (unsigned short)val; /* Record the sample into the buffer right where a space was freed up from the PlaySample read above */ Buffer[Index] = ReadSample; /* Increment the buffer pointer */ Index += Direction; /* Check to see if the chunk has been filled */ if (Index < 0) { /* Now have a chunk to be played back */ Playback = TRUE; /* Reverse the direction of playback and recording */ Direction = -Direction; Index = 0; } else if (Index >= ChunkSize) { /* Now have a chunk to be played back */ Playback = TRUE; /* Reverse the direction of playback and recording */ Direction = -Direction; Index = ChunkSize - 1; } } LPC_DAC->DACR = PlaySample & 0xFFC0; /* Set Speaker Output */ if ((Tick++ & 0x03FF) == 0) { /* On every 1024th Tick */ get_potval(); /* Get Potenciometer Value */ if (VolCur == 0x8000) { /* Check for Minimum Level */ Volume = 0; /* No Sound */ } else { Volume = VolCur * PotVal; /* Chained Volume Level */ } val = VUM >> 20; /* Scale Accumulated Value */ VUM = 0; /* Clear VUM */ if (val > 7) val = 7; /* Limit Value */ } LPC_TIM0->IR = 1; /* Clear Interrupt Flag */ } /***************************************************************************** ** Main Function main() ******************************************************************************/ int main (void) { volatile uint32_t pclkdiv, pclk; // semihost_powerdown(); SystemInit(); LPC_PINCON->PINSEL1 &=~((0x03<<18)|(0x03<<20)); /* P0.25, A0.0, function 01, P0.26 AOUT, function 10 */ LPC_PINCON->PINSEL1 |= ((0x01<<18)|(0x02<<20)); /* Enable CLOCK into ADC controller */ LPC_SC->PCONP |= (1 << 12); LPC_ADC->ADCR = 0x00200E04; /* ADC: 10-bit AIN2 @ 4MHz */ LPC_DAC->DACR = 0x00008000; /* DAC Output set to Middle Point */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ /* Bit 2~3 is for TIMER0 */ pclkdiv = (LPC_SC->PCLKSEL0 >> 2) & 0x03; switch ( pclkdiv ) { case 0x00: default: pclk = SystemFrequency/4; break; case 0x01: pclk = SystemFrequency; break; case 0x02: pclk = SystemFrequency/2; break; case 0x03: pclk = SystemFrequency/8; break; } LPC_TIM0->MR0 = pclk/DATA_FREQ - 1; /* TC0 Match Value 0 */ LPC_TIM0->MCR = 3; /* TCO Interrupt and Reset on MR0 */ LPC_TIM0->TCR = 1; /* TC0 Enable */ NVIC_EnableIRQ(TIMER0_IRQn); USB_Init(); /* USB Initialization */ USB_Connect(TRUE); /* USB Connect */ /********* The main Function is an endless loop ***********/ while( 1 ); } int result; /****************************************************************************** ** End Of File ******************************************************************************/
Here is the bin hope you have much fun as me
With the standard usb audio code, How could I make it play back sounds in reverse that is being played in windows, like the reverse effect code we have done. I have programs to do it such as sweep http://www.metadecks.org/software/sweep/
Would like to do it with out that as well tho:)
http://mbed.org/users/mbed2f/notebook/using-mbed-as-a-standard-generic-usb-audio-media-d/