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.

TAS2560: Audio I2s

Part Number: TAS2560

Dear Sir,

I have finally got the TAS2560 to play sound on 8 khz 16 bit. However the sound is not turning out the way it is suppose to . I have attached two files

1) which plays an audio file which says  "Walk sign is on for all crossing" 

2) a 1 khz sign wave generated with below function:

uint32_t generate_stereo_tone(uint16_t *buffer, unsigned int sample_rate, double duration, double frequency, bool reset, uint16_t writeBufferSize)
{
    unsigned int num_samples = (unsigned int)(sample_rate * duration);
    short amplitude = 32767; // 16-bit maximum amplitude
    static unsigned int k = 0;
    uint16_t maxBufferSize=(writeBufferSize/2)-1;
    int addr=0;
    uint16_t test=0;

    if (reset == true || k>=num_samples)
    {
        k =1;
    }
    else{
        for (unsigned int i = k; i < num_samples; i++)
        {
            double time = (double)i / sample_rate;

           buffer[2 * (i-k)+1] = (short)(amplitude * sin(2 * M_PI * frequency * time)); // Left channel
           buffer[2 * (i - k)] = 0;                                           // Right channel (silence)


            if ((i - k) ==maxBufferSize)
            {
                k = i;
                return (num_samples-i);
            }
        }
    }
}

1 khz.m4aWalk SIgn On.m4a

Can you please advise what must be the problem, some times it feels like i am not feed it enough data , but seems hard to believe as I have 4 writeBuffers of 1024bytes each below is my i2x setup code :

void I2S_Setup()
{
    // Initialize the I2S driver
    I2S_init();
    I2S_Params i2sParams;

    // Initialize I2S opening parameters
    //     I2S_Params i2sParams;
    I2S_Params_init(&i2sParams);
    i2sParams.samplingFrequency = SAMPLE_RATE;
    i2sParams.fixedBufferLength = WRITE_BUF_LENGTH * 2;
    i2sParams.bitsPerWord = 16;
    i2sParams.writeCallback = writeCallbackFxn;
    i2sParams.readCallback = readCallbackFxn;
    i2sParams.errorCallback = errCallbackFxn;
    i2sParams.CCLKDivider = 4;
    i2sParams.isDMAUnused = true;

    i2sHandle = I2S_open(CONFIG_I2S_0, &i2sParams);

    I2S_startClocks(i2sHandle);
}

This is my Play thread :

void *playAudioThread(void *arg0)
{

    int k;
    I2S_Transaction *lastAchievedTransaction;
    bool static firstTime = true;
    uint32_t offset;

    uint32_t events;
    printf("Transaction1 address = 0x%x  writeBuf1 address = 0x%x\n", &i2sWrite1, &writeBuf1);
    printf("Transaction2 address = 0x%x  writeBuf2 address = 0x%x\n", &i2sWrite2, &writeBuf2);
    printf("Transaction3 address = 0x%x  writeBuf3 address = 0x%x\n", &i2sWrite3, &writeBuf3);
    printf("Transaction4 address = 0x%x  writeBuf4 address = 0x%x\n\n\n", &i2sWrite4, &writeBuf4);


    //initAudioBuffers();
   
    I2S_Setup();

    uint32_t bytesRemaining = 0;

    while (1)
    {

        if (playStop == true)
        {
            if(firstTime == true)
            {
                initAudioBuffers();
                bytesRemaining=preload_Config_AudioBuffers(writeBuf1, writeBuf2, writeBuf3, writeBuf4, playFile, 0, WRITE_BUF_LENGTH);
                firstTime = false;
                I2S_setWriteQueueHead(i2sHandle, &i2sWrite1);
                I2S_startWrite(i2sHandle);
                offset=0;
            }


            if (writeFinished == true)
            {

                if(transactionFinished != NULL)
                {


                    // Need a critical section to be sure to have corresponding bufPtr and bufSize
                     uintptr_t key = HwiP_disable();
                     uint16_t *buf = transactionFinished->bufPtr;
                     uint16_t bufLength = transactionFinished->bufSize / sizeof(uint16_t);
                     bytesRemaining = loadAudioChunk(buf, playFile, offset, WRITE_BUF_LENGTH);
                     offset=offset+WRITE_BUF_LENGTH;
                     HwiP_restore(key);
                     List_put(&i2sWriteList, (List_Elem*)transactionFinished);
                    // audio_console_print_function(console_debug,"Reload Buffer");
                }

//
                if (bytesRemaining <= 0x100)
                {
                   endTicks = Clock_getTicks();
                    elapsedTimeTicks = endTicks - startTicks;
                    Task_sleep(CLOCK_MS(150));
                    I2S_stopWrite(i2sHandle);
                    // I2S_stopClocks(i2sHandle);
                    StopSound();
                    bytesRemaining = 0;
                    firstTime = true;
                    playStop=false;
                    writeFinished = false;
                    audio_console_print_function(console_debug,"Sound file Played");
                }
                writeFinished = false;
                //audio_console_print_function(console_debug,"transaction complete %x ,bytes remaining %d, no of completions: %d",transactionFinished, bytesRemaining,transactionFinished->numberOfCompletions);
            }
            else
            {
                 Task_sleep(CLOCK_MS(5));
            }
        }
        else
        {
            Task_sleep(CLOCK_MS(100));
            I2S_stopWrite(i2sHandle);
        }
    }
}

write callback

static void writeCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {

     // We must remove the previous transaction (the current one is not over)
       transactionFinished = (I2S_Transaction*)List_prev(&transactionPtr->queueElement);
//      audio_console_print_function(console_debug,"transaction complete prev%x",(I2S_Transaction*)List_prev(&transactionPtr->queueElement));
//      audio_console_print_function(console_debug,"transaction complete next%x",(I2S_Transaction*)List_next(&transactionPtr->queueElement));
    // audio_console_print_function(console_debug,"transaction complete %x",transactionFinished);
      if(transactionFinished != NULL){
          // Remove the finished transaction from the write queue
          List_remove(&i2sWriteList, (List_Elem*)transactionFinished);

          writeFinished=true;
      }
      if(status>I2S_TRANSACTION_SUCCESS)
      {
          audio_console_print_function(console_debug,"I2S Error %x", status);
      }
      if(status==I2S_ALL_TRANSACTIONS_SUCCESS)
      {
          audio_console_print_function(console_debug,"Buffer UnderRun");
          writeFinished=false;
      }


 }

  • Hi Nadeem,

    Could you confirm what is the input clock frequency? FS of 8kHz and 16-bit seem like a fairly low ratio. Please notice the minimum input clock frequency is 512kHz.

    Best regards,
    -Ivan Salazar
    Applications Engineer

  • Thanks for your reply.. 

    WCLK = 7.98khz

    BCLK =255.31 KHZ

    MCLK =12 MHZ

    Is this what you were asking for? This is what I am sending out from my I2S Port.

  • When I look as the wave , it seems like its clipping.. Another interesting i noticed there is always a pulse as shown in the video although no sound is being played. PLEASE IGNORE THE SOUND OF THE VIDEO...SOMETHING WAS BEING PLAY ON MY COMPUTER. THE VIDEO SIMPLY SHOWS THE OUTPUT FROM THE SPEAKER WITH NOTHING BEING PLAYED.

    When something is play the pulse still looks like a square wave , just increases in duration(pulse width increases). Maybe its clipping?

  • Hi Nadeem,

    Please notice this is a Class-D amplifier, so the output waveform is a PWM signal if not filtered with RC or LC filter for measurement. So that may be OK.
    Regarding the clock settings, I still think BCLK may be too low, I'll double check and provide further comments later today or early next week.

    Best regards,
    -Ivan Salazar
    Applications Engineer

  • Any update on this man?

    Thanks allot for your time..

  • Hi Nadeem,

    Haven't got time to test this yet, I'll try to setup some time for it this week.

    Best regards,
    -Ivan Salazar
    Applications Engineer

  • Hi Nadeem,

    I can't test with MCLK = 12MHz, however I tested with this setup, and it seems to work OK:

    • MCLK = 12.288MHz (1536 ratio to WCLK)
    • BCLK = 256kHz
    • WCLK = 8kHz

    For this test I used the End System Integration panel within PPC3, there you can select the clock source, its frequency and the sampling rate. If I try with 12MHz the output is noisy, but this is because I'm using 12.288MHz.

    You may test with this attached configuration I generated from PPC3:

    8K_12M_TAS2560.cfg

    Best regards,
    -Ivan Salazar
    Applications Engineer