Skipping audio

05 Oct 2011

I have this problem with the code I am writing. I am writing code much like a reverse effects guitar pedal. But it is usb sound card as well and plays windows sound in reverse and you can plug guitar in and mix with windows sounds. My problem is with the timer0 at the moment anything above 8000khz and I get skipping audio becuase the timer is ticking too fast for the audio I think. Do you have any ideas as to how I can fix the skipping audio at 32khz and above.

Here is the code.

/*
 * 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 ( DataIn >= DataOut ) {              /* Buffer Data Count */
      cnt = DataIn - DataOut;
    } else {
      cnt = B_S + DataIn - DataOut;
    }
        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;
   if ( DataOut >= B_S )                   /* Adjust Buffer Out Index */
      DataOut -= B_S;
    //if (val < 0) VUM -= val;                /* Accumulate Neg Value */
    //else         VUM += val;                /* Accumulate Pos Value */
    val  *= Volume;                         /* Apply Volume Level */
    val >>= 6;                             /* 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 = 10 * 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 *= -1;//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 *= -1;//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 */

   }
06 Oct 2011

<<quote>>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.

<</quote>>

I was told this not sure if that would fix the skipping audio? Not sure how I would do it as well.

06 Oct 2011

Gert van den Berg 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.

I was told this not sure if that would fix the skipping audio? Not sure how I would do it as well.