[Ffmpeg-devel] thp audio decoder

Spidy spidy
Sun Apr 1 20:54:54 CEST 2007


Hi, all!
I am writing a thp audio decoder for a THP format(In fact i right
full THP playback as a GSoC qualification task, and all videos both
with audio or not works fine,but soundd seems to play just one sample
instead of 16),i had encountered problem and i don't know what is the reason, i give to
audio decoder one packet and if i decode all audio samples then
projecting size becomes nearly 4 times bigger than needed, but if i
skip every 4th sample than sound is hearable but of very bad  quality
with much noise. I think i do not understand sth about how must
samples return and what difference AVCodecContext fields such as
bitrate or frequency means, cos if i change them there is no
difference.

I have included into avcode/adpcm.c own type:
--------------------------------------
typedef struct ADPCMThpFrameHeader {
    uint32_t channelSize;
    uint32_t numSamples;
    int16_t tableFC[16];
    int16_t tableSC[16];
    int16_t channel1Prev1;
    int16_t channel1Prev2; 
    int16_t channel2Prev1;
    int16_t channel2Prev2;
} ADPCMThpFrameHeader;
-------------------------------------
own nibble expand function:
------------------------------
static inline short adpcm_thp_expand_nibble(ADPCMThpFrameHeader *frameHeader, int8_t nibble,
                                            int8_t firstByte, int st)
{
        
        int8_t temp = 0;
        uint8_t index = (firstByte >> 4) & 0x7;
        uint8_t exponent = firstByte & 0xf;
        float factor1;
        float factor2; 
        float tab1, tab2;
        if ((nibble & 0x08))  {
                nibble = (nibble - 1);
                nibble = nibble ^ 0x07;
        }
        if (!st)  {  //first channel
                tab1 = (float)(frameHeader->tableFC[2*index] >> 11) + (float)((frameHeader->tableFC[2*index] &
0x07ff)/pow(2,11));
                tab2 = (float)(frameHeader->tableFC[2*index + 1] >> 11) + (float)((frameHeader->tableFC[2*index + 1] &
0x07ff)/pow(2,11));
                factor1 = (float)(tab1/(float)(pow(2.f,11)));
                factor2 = (float)(tab2/(float)(pow(2.f,11)));
                temp = (int8_t)(frameHeader->channel1Prev1*factor1 + frameHeader->channel1Prev2*factor2 + (nibble &
0x0f)*(2^exponent));
                //av_log(NULL, AV_LOG_ERROR, "temp = %i\n", temp);
                frameHeader->channel1Prev2 = frameHeader->channel1Prev1;
                frameHeader->channel1Prev1 = temp;
        }
        else  {     //second channel
//              factor1 = frameHeader->tableSC[2*index]/pow(2.f,11);
//              factor2 = frameHeader->tableSC[2*index + 1]/pow(2.f,11);
//              temp += frameHeader->channel2Prev1*factor1 + frameHeader->channel2Prev2*factor2 + (nibble &
0x0f)*(2^exponent); 
//              frameHeader->channel2Prev2 = frameHeader->channel2Prev1;
//              frameHeader->channel2Prev1 = temp;
        }
        return temp;
}
-------------------------------------------

and added a case to adpcm_decode_frame

------------------------------------------

case CODEC_ID_ADPCM_THP:
        
        frameHeader->channelSize = (uint32_t)(src[3] + (src[2] << 8) + (src[1] << 16) + (src[0] << 24));
        src += 4;
        frameHeader->numSamples = (uint32_t)(src[3] + (src[2] << 8) + (src[1] << 16) + (src[0] << 24));
        src += 4;
        for (i=0; i<16; i++)  {
            frameHeader->tableFC[i] = (int16_t)(src[1] + (src[0] << 8));
            src += 2;
        }
        for (i=0; i<16; i++)  { 
            frameHeader->tableSC[i] = (int16_t)(src[1] + (src[0] << 8));
            src += 2;
        }
        frameHeader->channel1Prev1 = (int16_t)(src[1] + (src[0] << 8));
        src += 2;
        frameHeader->channel1Prev2 = (int16_t)(src[1] + (src[0] << 8));
        src += 2;
        frameHeader->channel2Prev1 = (int16_t)(src[1] + (src[0] << 8));
        src += 2;
        frameHeader->channel2Prev2 = (int16_t)(src[1] + (src[0] << 8));
        src += 2;
        m = (buf_size - 80) >> st;
        //m = frameHeader->channelSize;
        int cnt=7;
        int8_t samp;
        int8_t firstByte;
        for (i=0; i<m/4; i++)  {
            if (cnt == 7)  {
                firstByte = src[i];
                cnt = 0;
            }
            else  {
                *samples++ = adpcm_thp_expand_nibble(frameHeader, (src[i] & 0x0f), firstByte, 0);
                samp = 0;
                if (st)  {
                //av_log(NULL,AV_LOG_ERROR,"rr\n");
                        samp = adpcm_thp_expand_nibble(frameHeader, (src[i+m] & 0x0f), firstByte, 1);
                        //*samples++ = samp;
                } 
                

                *samples++ = adpcm_thp_expand_nibble(frameHeader, src[i] & 0xf0, firstByte, 0);
                if (st)  {
                        samp = adpcm_thp_expand_nibble(frameHeader, (src[i+m] & 0xf0), firstByte, 1);
                        //*samples++ = samp;
                } 
                //

                cnt++;
            } 
        }
        

        break;
--------------------------------------------------


It must read m bytes but then it expands and to not inserted
responsible to time.
May be you could help me and say where is the error.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: thp.c
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070401/fbc419b8/attachment.asc>



More information about the ffmpeg-devel mailing list