This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Streaming voice through C5505+CC2520 interfacing: AIC3204 sampling + playback problem, ping-pong buffering

Other Parts Discussed in Thread: CC2520

Hi all,

I have a hardware interfacing of C5505 USB stick and CC2520 radio. My aim is to sample voice through AIC3204 and send it over radio. After sampling I intend apply speex codec to down convert the stream rate from 64kbps to 5.9kbps.

Now my question is about using ping-pong buffering with AIC3204.

(I have set 48Khz as the sampling frequency in AIC3204. AIC3204_rset( 30, 0x88). I also experimented with 8khz. AIC3204_rset( 30, 0xB0))

We know that ezdsp comes with tests, one of which is about sampling and playback through AIC3204. The code looks something like this

   while(1)
   {
        inputData1 = I2S0_W0_MSW_R;                 
        inputData2 = I2S0_W0_LSW_R;
       
        I2S0_W0_MSW_W = inputData1;
        I2S0_W0_LSW_W = inputData2;

   }

If I play a song on laptop, give the line-out to AIC line-in and then take AIC line-out over headphone, I can hear a good quality audio.

However, this processing in while loop is inefficient and not suitable to apply ping-pong buffering.

Thus to apply ping-pong buffering, I wrote an ISR routine with GPT through 16Khz timer. I get interrupt every 16Khz, I share it with sampling and playback turn by turn, thus each effectively getting 8Khz. I apply ping-pong buffering here as follows.

interrupt void ticker_ISR(void)
{
    if(interruptTurn == SAMPLE_AIC)
    {
                      
        interruptTurn = PLAYBACK_AIC;
       
        inputData1 = I2S0_W0_MSW_R;                 
        inputData2 = I2S0_W0_LSW_R;
           
        if(encBuffToUse == ENC_PING_BUFFER)
            encPingBuffer[indexEncoder] = inputData1;
        else
            encPongBuffer[indexEncoder] = inputData1;
   
        indexEncoder++;   
       
        if(encBuffToUse == ENC_PING_BUFFER)
            encPingBuffer[indexEncoder] = inputData2;
        else
            encPongBuffer[indexEncoder] = inputData2;
       
        indexEncoder++;
   
        if(indexEncoder == (2*FRAME_SIZE))
        {
            indexEncoder = 0;
       
            //for testing sampling and playback
            READY_TO_PLAY = 1;
           
            if(encBuffToUse == ENC_PING_BUFFER)
                encBuffToUse = ENC_PONG_BUFFER;
            else
                encBuffToUse = ENC_PING_BUFFER;
               
            //encodeFrame();       
        }           
   
    }
    else
    {

        interruptTurn = SAMPLE_AIC;


        if(READY_TO_PLAY)
        {
           
            //for testing sampling and playback
            if(encBuffToUse == ENC_PING_BUFFER)
                outputData1 = encPongBuffer[indexDecoder];
            else
                outputData2 = encPingBuffer[indexDecoder];
   
            indexDecoder++;
           
            if(encBuffToUse == ENC_PING_BUFFER)
                outputData1 = encPongBuffer[indexDecoder];
            else
                outputData2 = encPingBuffer[indexDecoder];
       
            indexDecoder++;
                       
       
            I2S0_W0_MSW_W = outputData1;
            I2S0_W0_LSW_W = outputData2;
             
              if(indexDecoder == (2*FRAME_SIZE))
              {
                  indexDecoder = 0;
              }
                               
        }
           
    }   
   
    // clearing the timer interrupt bit from IFR0 register
    CSL_CPU_REGS->IFR0 = CSL_CPU_REGS->IFR0 & 0xFFEF;
    //Clearing TIAF register bit corresponding to Timer0   
    (*iafrReg) = (*iafrReg)| (0x0001) ;
                
}

If you have noticed in this program, I am not applying encoding or decoding, but simply passing the buffers to playback so that sampling and playback can happen simultaneously. This is a test of ping-pong buffering before applying codec. This should sample voice from line-in and playback voice on line-out.

However, when I test this through line-in (laptop) and line-out (headphone) for a song or voice sample, I get very poor quality audio.I can recognize the song being played but pitch gets down suddenly. This is worse because I have not even applied codec.

And this is not because of low sampling frequency of AIC3204 (48Khz or 8Khz) as the while loop program gives good quality output. This is also not because of low sampling frequency of GPT (8khz) as I tried with 48Khz sampling as well.

Is this because of GPT overhead? How should I go about doing this then?

Or is this because of some AIC3204 setting?

Awaiting early reply.

Thanks in advance.

Vijay

  • Hi Vijay,

    I would use the DMA to copy samples from the codec over I2S. When the Ping-Pong buffer is full, you can use the DMA ISR to manage your Ping-Pong buffers, set a flag to begin the codec, etc.

    Your timer ISR is possibly not synchronized with the Ping-Pong buffers, which may cause distortion to the audio.

    If you attach your project, I can check out the codec commands and try to reproduce your noise.

    Also, you might find the C5505 eZdsp Audio Filter Demo useful. See http://code.google.com/p/c5505-ezdsp/

    Basically, this project reads from the codec, filter's the audio, and sends it back to the codec. DMA interrupts are used for synchronization.

    The C5515 and the C5515 eZdsp (also here) employ hardware ping-pong buffers in the DMA, which does make management easier on the programmer.

    Hope this helps,
    Mark

  • Hi Mark,

    Thanks for reply.

    Yes, I used the same demo program to employ ping pong buffering in my program. I tested quality (without speex encoder, decoder in between) with different sampling rates and it is satisfactory.

    However, now speex is giving trouble running on the platform. Either the quality is bad or the decoder is failing with stream corrupted error.

    Although, it may be orthogonal area to you, but if you are interested in running speex C55x, I can forward you the code. The code samples, encodes, decodes and plays back in real-time.

    Awaiting your reply on whether I should forward you the code.

    Cheers,

    Vijay

     

  • Yes Vijay,

    This sounds interesting. Please send me the code.

    You can either attach it here or email it to me at   

    Thanks,
    Mark

  • hi,

    i also want to run speex lib on c5515.

    pls suggest from where i can get it. if you can share your speex lib will be great.

    regards'

    manish