Slow playback of mp3 data

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Slow playback of mp3 data

2,499 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by praveen.9123 on Sun May 04 23:06:26 MST 2014
Dear Support team,

We have integrated helix mp3 decoder on LPC4330 xplorer board. In current setup, we are writing executable to SPIFI memory and loading it to RAM for the execution.

Configurations of my setup:
--> Core frequency of M4:   204 MHz
--> SPIFI clock freequency: 68 MHz
--> mp3 decoder is optimized to ARM assembly
--> sdio peripheral clock frequency is 204 MHz - Reading mp3 data from sdcard using FAT32 file system.
--> Using DMA-I2S setup for PCM rendering

The problem which we are facing with the above configurations and setup is listening slow playback compared to the original mp3 track. i.e. 3 seconds worth of data is taking 6 seconds for rendering.

Could yo please suggest us at the earliest?
Could you also pls suggest on how to profile the decoding/rendering blocks?
*** xTaskGetTickCount() is always returning 0 ***

Regards,
Praveen
Labels (1)
0 Kudos
Reply
11 Replies

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bavarian on Mon May 26 09:13:02 MST 2014
Hi Praveen,

I see in the map file that your code runs from SPIFI, which is too slow for the MP3 decoder at higher data rates.
I think I got it running at 32kHz from SPIFI, but no chance above that.

After startup you need to relocate the time critical code into the internal SRAM, at least all mp3 decoder objects.

Regards,
NXP Support Team.
0 Kudos
Reply

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by praveen.9123 on Mon May 26 01:38:26 MST 2014
Hai Bavarian,
Thanks for you reply. The below attached map file i have uploaded was generated in LpcXpresso(IDE) for lpc4330 core where i have mapped to SPIFI memory interface.

Regards,
Praveen.
0 Kudos
Reply

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by praveen.9123 on Sun May 25 23:41:53 MST 2014
Hai Bavarian,
    Thanks for you reply. The below attached map file i have uploaded was generated in LpcXpresso(IDE) for lpc4330 core where i have mapped to SPIFI memory interface.

Regards,
Praveen.
0 Kudos
Reply

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bavarian on Fri May 23 04:23:45 MST 2014
Hello Praveen,

there is no general restriction somewhere for data rates.
In my Internet Radio example I can play MP3 files from the SD card with 256kbps and 320kbps at a sample rate of 44.1kHz.

The problems you see can come from 3 different sources:


[list=1]
  [*]  The clock input for the I2S interface is wrong. Pretty unlikely, as you normally don't change this dynamically.

  [*]  The clock setting for the I2S interface is wrong. That's relatively easy to check by reading out the respective clock registers. If you don't do any dynamic changes on these registers then it's also unlikely.

  [*]  The MP3 decoder doesn't have enough time to finish the job. In my Internet Radio example it obviously has, but there the code is executed from internal flash. You execute from SPIFI and from internal SRAM, but maybe you code partitioning is not good enough. The complete MP3 decoder should be executed from internal RAM, if you forget to relocate something which is constantly used, then the slower execution from SPIFI will slow the system down. You could send me the map file of your project for a crosscheck.

Regards,
NXP Support Team
[/list]
0 Kudos
Reply

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by praveen.9123 on Tue May 20 22:36:31 MST 2014
Hi Bavarian,
  These is the actual code for I2S configuration which works for below 48Kbps(bit-rate) and 16Khz sampling frequency or 24Khz Sampling frequency with little delay in it, but works fine.

If you don't mind check the below code whether it is correct or not.

When i used for above 48kbps the Delay is more i don't know why it happens. Please help me to play mp3 stream data with more than 48kbps(bit-rate), It will be helpful to me.


/* Configure I2S for Audio Format input */
Status Chip_I2S_Config(LPC_I2S_Type *I2Sx, uint8_t TRMode, Chip_I2S_Audio_Format_Type *audio_format)
{
uint32_t pClk;
uint32_t x, y;
uint64_t divider;
uint16_t dif;
uint16_t x_divide = 0, y_divide = 0;
uint32_t N;
uint16_t err, ErrorOptimal = 0xFFFF;

pClk = (uint64_t)Chip_Clock_GetRate(CLK_APB1_I2S);

/* divider is a fixed point number with 16 fractional bits */
divider = (((uint64_t)(audio_format->SampleRate) * 2 * (audio_format->WordWidth) * 2) << 16) / pClk;
/* find N that make x/y <= 1 -> divider <= 2^16 */
for (N = 64; N > 0; N--) {
if ((divider * N) < (1 << 16)) {
break;
}
}
if (N == 0) {
return ERROR;
}
divider *= N;
for (y = 255; y > 0; y--) {
x = y * divider;
if (x & (0xFF000000)) {
continue;
}
dif = x & 0xFFFF;
if (dif > 0x8000) {
err = 0x10000 - dif;
}
else {
err = dif;
}
if (err == 0) {
y_divide = y;
break;
}
else if (err < ErrorOptimal) {
ErrorOptimal = err;
y_divide = y;
}
}
x_divide = ((uint64_t)y_divide * (audio_format->SampleRate) * 2 * (audio_format->WordWidth) * N * 2) / pClk;
if (x_divide >= 256) {
x_divide = 0xFF;
}
if (x_divide == 0) {
x_divide = 1;
}
if (audio_format->WordWidth <= 8) {
IP_I2S_SetWordWidth(I2Sx, TRMode, I2S_WORDWIDTH_8);
}
else if (audio_format->WordWidth <= 16) {
IP_I2S_SetWordWidth(I2Sx, TRMode, I2S_WORDWIDTH_16);
}
else {
IP_I2S_SetWordWidth(I2Sx, TRMode, I2S_WORDWIDTH_32);
}
IP_I2S_SetMono(I2Sx, TRMode, (audio_format->ChannelNumber) == 1 ? I2S_MONO : I2S_STEREO);
IP_I2S_SetMasterSlaveMode(I2Sx, TRMode, I2S_MASTER_MODE);
IP_I2S_SetWS_Halfperiod(I2Sx, TRMode, audio_format->WordWidth - 1);
IP_I2S_ModeConfig(I2Sx, TRMode, I2S_TXMODE_CLKSEL(0), !I2S_TXMODE_4PIN_ENABLE, !I2S_TXMODE_MCENA);
IP_I2S_SetBitRate(I2Sx, TRMode, N - 1);
IP_I2S_SetXYDivider(I2Sx, TRMode, x_divide, y_divide);
return SUCCESS;
}

Best Regards,
Praveen
0 Kudos
Reply

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by praveen.9123 on Sun May 18 21:23:10 MST 2014
Hai Bavarian,
 
          Thanks for your reply. I will check it and update you.

Regards,
Praveen.
0 Kudos
Reply

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bavarian on Wed May 14 08:32:17 MST 2014
Hello Praveen,

can you check if the result of this function gives you the correct values ( x_divide, y_divide) for the given chip frequency and the actual sample rate?
Maybe the algorithm provides wrong results.

And don't say "But this comes from NXP!". Even then it could contains bugs   8-)

But I would be happy if you can confirm if the result is ok or not. If not, then I'm taking the action to get it fixed.

Regards,
NXP Support Team
0 Kudos
Reply

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by praveen.9123 on Wed May 07 23:33:32 MST 2014
Hi Bavarian,

You have correctly zeroed the issue.

We looked into I2S configurations and modified. There is an issue in setting the registers TXBITRATE and TXRATE.
Modified the code and now it is working for the streams <= 48 kbps. Still facing issue with high bitrate streams (> 48 kbps).

Please find the code snippet I2S configurations below and correct me if any issues with high bitrate streams.

------------------------------------------------------------------------------------------------------------------------------------------------------------
/* Configure I2S for Audio Format input */
Status Chip_I2S_Config(LPC_I2S_Type *I2Sx, uint8_t TRMode, Chip_I2S_Audio_Format_Type *audio_format)
{
    uint32_t pClk;
    uint32_t x, y;
    uint64_t divider;
    uint16_t dif;
    uint16_t x_divide = 0, y_divide = 0;
    uint32_t N;
    uint16_t err, ErrorOptimal = 0xFFFF;

    pClk = (uint64_t)Chip_Clock_GetRate(CLK_APB1_I2S);

    /* divider is a fixed point number with 16 fractional bits */
    //divider = (((uint64_t)(audio_format->SampleRate) * 2 * (audio_format->WordWidth) * 2) << 16) / pClk;

    N = ((audio_format->ChannelNumber)*(audio_format->WordWidth));

    if (N == 0) {
        return ERROR;
    }

    //divider *= N;
    divider = ((uint64_t)(audio_format->SampleRate * N * 2) << 16) / pClk;
    for (y = 255; y > 0; y--) {
        x = y * divider;
        if (x & (0xFF000000)) {
            continue;
        }
        dif = x & 0xFFFF;
        if (dif > 0x8000) {
            err = 0x10000 - dif;
        }
        else {
            err = dif;
        }
        if (err == 0) {
            y_divide = y;
            break;
        }
        else if (err < ErrorOptimal) {
            ErrorOptimal = err;
            y_divide = y;
        }
    }

    x_divide = ((uint64_t)y_divide * (audio_format->SampleRate) * 2 * (audio_format->WordWidth) * N * 2) / pClk;
    if (x_divide >= 256) {
        x_divide = 0xFF;
    }
    if (x_divide == 0) {
        x_divide = 1;
    }
    if (audio_format->WordWidth <= 8) {
        IP_I2S_SetWordWidth(I2Sx, TRMode, I2S_WORDWIDTH_8);
    }
    else if (audio_format->WordWidth <= 16) {
        IP_I2S_SetWordWidth(I2Sx, TRMode, I2S_WORDWIDTH_16);
    }
    else {
        IP_I2S_SetWordWidth(I2Sx, TRMode, I2S_WORDWIDTH_32);
    }
    IP_I2S_SetMono(I2Sx, TRMode, (audio_format->ChannelNumber) == 1 ? I2S_MONO : I2S_STEREO);
    IP_I2S_SetMasterSlaveMode(I2Sx, TRMode, I2S_MASTER_MODE);
    IP_I2S_SetWS_Halfperiod(I2Sx, TRMode, audio_format->WordWidth - 1);
    IP_I2S_ModeConfig(I2Sx, TRMode, I2S_TXMODE_CLKSEL(0), !I2S_TXMODE_4PIN_ENABLE, !I2S_TXMODE_MCENA);
    IP_I2S_SetBitRate(I2Sx, TRMode, N-1);
    IP_I2S_SetXYDivider(I2Sx, TRMode, x_divide, y_divide);

    return SUCCESS;
}
------------------------------------------------------------------------------------------------------------------------------------------------------------

Thanks,
Praveen
0 Kudos
Reply

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by praveen.9123 on Wed May 07 23:22:45 MST 2014
We have used mp3 stream of 128 kbps, which was not working. Currently we have tested with few streams of <= 48 kbps, and are working fine.
Could you pls suggest us if you have any inputs on why it is not working with high bitrate streams?
I will mention the I2S configurations in below response.
0 Kudos
Reply

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bavarian on Mon May 05 04:00:02 MST 2014
Hello Praveen,

with "slow playback" you mean that you hear the music on half of the speed ?

If this is the case then you most likely have a problem on the I2S side and not on the MP3 decoding side.

[list]
  [*]  The data you get from the SD card is in a first step just a bunch of bytes, regardless what the system frequencies are. For this type of application the read process from the card is not really time critical.
  [*]  The MP3 decoder identifies the bitrate of the MP3 file and decodes the data accordingly.
  [*]  The stereo PCM data is then provided to the I2S interface, which is set up to operate correctly for the sample rate of the audio data. E.g. 48 kHz or 44.1 kHz.
[/list]

I think that in your software the input frequency for the I2S block is wrong, so that the audio data is given to the outside CODEC at only half of the speed.

[list]
  [*]  This is the I2S setup call:  I2S_setup(mp3FrameInfo.samprate, mp3FrameInfo.nChans, mp3FrameInfo.bitsPerSample);
  [*]  I don't think that things go wrong here, except if you have changed settings in the functions called by this setup.
  [*]  If the clock tree setting for the I2S block in the system_init functions is wrong, then you will hear it finally on the loudspeaker even if everything inbetween seems to work fine.
[/list]


Regards,
NXP Support Team
0 Kudos
Reply

2,444 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by schisanoa on Mon May 05 00:32:22 MST 2014
Maybe you can try by reducing the datarate of the MP3 file. what datarate you are using now?
0 Kudos
Reply