示例#1
0
static int decode_subpacket(COOKContext *q, const uint8_t *inbuffer,
                            int sub_packet_size, int16_t *outbuffer) {
    /* packet dump */
//    for (i=0 ; i<sub_packet_size ; i++) {
//        av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]);
//    }
//    av_log(NULL, AV_LOG_ERROR, "\n");

    decode_bytes_and_gain(q, inbuffer, &q->gains1);

    if (q->joint_stereo) {
        joint_decode(q, q->decode_buffer_1, q->decode_buffer_2);
    } else {
        mono_decode(q, q->decode_buffer_1);

        if (q->nb_channels == 2) {
            decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, &q->gains2);
            mono_decode(q, q->decode_buffer_2);
        }
    }

    mlt_compensate_output(q, q->decode_buffer_1, &q->gains1,
                          q->mono_previous_buffer1, outbuffer, 0);

    if (q->nb_channels == 2) {
        if (q->joint_stereo) {
            mlt_compensate_output(q, q->decode_buffer_2, &q->gains1,
                                  q->mono_previous_buffer2, outbuffer, 1);
        } else {
            mlt_compensate_output(q, q->decode_buffer_2, &q->gains2,
                                  q->mono_previous_buffer2, outbuffer, 1);
        }
    }
    return q->samples_per_frame * sizeof(int16_t);
}
示例#2
0
/**
 * Cook subpacket decoding. This function returns one decoded subpacket,
 * usually 1024 samples per channel.
 *
 * @param q                 pointer to the COOKContext
 * @param inbuffer          pointer to the inbuffer
 * @param outbuffer         pointer to the outbuffer
 */
static void decode_subpacket(COOKContext *q, COOKSubpacket* p, const uint8_t *inbuffer, int16_t *outbuffer) {
    int sub_packet_size = p->size;
    /* packet dump */
//    for (i=0 ; i<sub_packet_size ; i++) {
//        av_log(q->avctx, AV_LOG_ERROR, "%02x", inbuffer[i]);
//    }
//    av_log(q->avctx, AV_LOG_ERROR, "\n");
    memset(q->decode_buffer_1,0,sizeof(q->decode_buffer_1));
    decode_bytes_and_gain(q, p, inbuffer, &p->gains1);

    if (p->joint_stereo) {
        joint_decode(q, p, q->decode_buffer_1, q->decode_buffer_2);
    } else {
        mono_decode(q, p, q->decode_buffer_1);

        if (p->num_channels == 2) {
            decode_bytes_and_gain(q, p, inbuffer + sub_packet_size/2, &p->gains2);
            mono_decode(q, p, q->decode_buffer_2);
        }
    }

    mlt_compensate_output(q, q->decode_buffer_1, &p->gains1,
                          p->mono_previous_buffer1, outbuffer, p->ch_idx);

    if (p->num_channels == 2) {
        if (p->joint_stereo) {
            mlt_compensate_output(q, q->decode_buffer_2, &p->gains1,
                                  p->mono_previous_buffer2, outbuffer, p->ch_idx + 1);
         } else {
            mlt_compensate_output(q, q->decode_buffer_2, &p->gains2,
                                  p->mono_previous_buffer2, outbuffer, p->ch_idx + 1);
         }
     }

}
示例#3
0
文件: cook.c 项目: GenomeXP/mpc-hc
/**
 * Cook subpacket decoding. This function returns one decoded subpacket,
 * usually 1024 samples per channel.
 *
 * @param q                 pointer to the COOKContext
 * @param inbuffer          pointer to the inbuffer
 * @param outbuffer         pointer to the outbuffer
 */
static int decode_subpacket(COOKContext *q, COOKSubpacket *p,
                            const uint8_t *inbuffer, float **outbuffer)
{
    int sub_packet_size = p->size;
    int res;

    memset(q->decode_buffer_1, 0, sizeof(q->decode_buffer_1));
    decode_bytes_and_gain(q, p, inbuffer, &p->gains1);

    if (p->joint_stereo) {
        if ((res = joint_decode(q, p, q->decode_buffer_1, q->decode_buffer_2)) < 0)
            return res;
    } else {
        if ((res = mono_decode(q, p, q->decode_buffer_1)) < 0)
            return res;

        if (p->num_channels == 2) {
            decode_bytes_and_gain(q, p, inbuffer + sub_packet_size / 2, &p->gains2);
            if ((res = mono_decode(q, p, q->decode_buffer_2)) < 0)
                return res;
        }
    }

    mlt_compensate_output(q, q->decode_buffer_1, &p->gains1,
                          p->mono_previous_buffer1,
                          outbuffer ? outbuffer[p->ch_idx] : NULL);

    if (p->num_channels == 2) {
        if (p->joint_stereo)
            mlt_compensate_output(q, q->decode_buffer_2, &p->gains1,
                                  p->mono_previous_buffer2,
                                  outbuffer ? outbuffer[p->ch_idx + 1] : NULL);
        else
            mlt_compensate_output(q, q->decode_buffer_2, &p->gains2,
                                  p->mono_previous_buffer2,
                                  outbuffer ? outbuffer[p->ch_idx + 1] : NULL);
    }

    return 0;
}
示例#4
0
文件: cook.c 项目: GenomeXP/mpc-hc
/**
 * function for decoding joint stereo data
 *
 * @param q                 pointer to the COOKContext
 * @param mlt_buffer1       pointer to left channel mlt coefficients
 * @param mlt_buffer2       pointer to right channel mlt coefficients
 */
static int joint_decode(COOKContext *q, COOKSubpacket *p,
                        float *mlt_buffer_left, float *mlt_buffer_right)
{
    int i, j, res;
    int decouple_tab[SUBBAND_SIZE] = { 0 };
    float *decode_buffer = q->decode_buffer_0;
    int idx, cpl_tmp;
    float f1, f2;
    const float *cplscale;

    memset(decode_buffer, 0, sizeof(q->decode_buffer_0));

    /* Make sure the buffers are zeroed out. */
    memset(mlt_buffer_left,  0, 1024 * sizeof(*mlt_buffer_left));
    memset(mlt_buffer_right, 0, 1024 * sizeof(*mlt_buffer_right));
    if ((res = decouple_info(q, p, decouple_tab)) < 0)
        return res;
    if ((res = mono_decode(q, p, decode_buffer)) < 0)
        return res;
    /* The two channels are stored interleaved in decode_buffer. */
    for (i = 0; i < p->js_subband_start; i++) {
        for (j = 0; j < SUBBAND_SIZE; j++) {
            mlt_buffer_left[i  * 20 + j] = decode_buffer[i * 40 + j];
            mlt_buffer_right[i * 20 + j] = decode_buffer[i * 40 + 20 + j];
        }
    }

    /* When we reach js_subband_start (the higher frequencies)
       the coefficients are stored in a coupling scheme. */
    idx = (1 << p->js_vlc_bits) - 1;
    for (i = p->js_subband_start; i < p->subbands; i++) {
        cpl_tmp = cplband[i];
        idx -= decouple_tab[cpl_tmp];
        cplscale = q->cplscales[p->js_vlc_bits - 2];  // choose decoupler table
        f1 = cplscale[decouple_tab[cpl_tmp] + 1];
        f2 = cplscale[idx];
        q->decouple(q, p, i, f1, f2, decode_buffer,
                    mlt_buffer_left, mlt_buffer_right);
        idx = (1 << p->js_vlc_bits) - 1;
    }

    return 0;
}
示例#5
0
static void joint_decode(COOKContext *q, float* mlt_buffer1,
                         float* mlt_buffer2) {
    int i,j;
    int decouple_tab[SUBBAND_SIZE];
    float decode_buffer[1060];
    int idx, cpl_tmp,tmp_idx;
    float f1,f2;
    float* cplscale;

    memset(decouple_tab, 0, sizeof(decouple_tab));
    memset(decode_buffer, 0, sizeof(decode_buffer));

    /* Make sure the buffers are zeroed out. */
    memset(mlt_buffer1,0, 1024*sizeof(float));
    memset(mlt_buffer2,0, 1024*sizeof(float));
    decouple_info(q, decouple_tab);
    mono_decode(q, decode_buffer);

    /* The two channels are stored interleaved in decode_buffer. */
    for (i=0 ; i<q->js_subband_start ; i++) {
        for (j=0 ; j<SUBBAND_SIZE ; j++) {
            mlt_buffer1[i*20+j] = decode_buffer[i*40+j];
            mlt_buffer2[i*20+j] = decode_buffer[i*40+20+j];
        }
    }

    /* When we reach js_subband_start (the higher frequencies)
       the coefficients are stored in a coupling scheme. */
    idx = (1 << q->js_vlc_bits) - 1;
    for (i=q->js_subband_start ; i<q->subbands ; i++) {
        cpl_tmp = cplband[i];
        idx -=decouple_tab[cpl_tmp];
        cplscale = (float*)cplscales[q->js_vlc_bits-2];  //choose decoupler table
        f1 = cplscale[decouple_tab[cpl_tmp]];
        f2 = cplscale[idx-1];
        for (j=0 ; j<SUBBAND_SIZE ; j++) {
            tmp_idx = ((q->js_subband_start + i)*20)+j;
            mlt_buffer1[20*i + j] = f1 * decode_buffer[tmp_idx];
            mlt_buffer2[20*i + j] = f2 * decode_buffer[tmp_idx];
        }
        idx = (1 << q->js_vlc_bits) - 1;
    }
}
示例#6
0
static int decode_subpacket(COOKContext *q, uint8_t *inbuffer,
                            int sub_packet_size, int16_t *outbuffer) {
    int i,j;
    int value;
    float* tmp_ptr;

    /* packet dump */
//    for (i=0 ; i<sub_packet_size ; i++) {
//        av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]);
//    }
//    av_log(NULL, AV_LOG_ERROR, "\n");

    decode_bytes(inbuffer, q->decoded_bytes_buffer, sub_packet_size);
    init_get_bits(&q->gb, q->decoded_bytes_buffer, sub_packet_size*8);
    decode_gain_info(&q->gb, &q->gain_current);

    if(q->nb_channels==2 && q->joint_stereo==1){
        joint_decode(q, q->decode_buf_ptr[0], q->decode_buf_ptr[2]);

        /* Swap buffer pointers. */
        tmp_ptr = q->decode_buf_ptr[1];
        q->decode_buf_ptr[1] = q->decode_buf_ptr[0];
        q->decode_buf_ptr[0] = tmp_ptr;
        tmp_ptr = q->decode_buf_ptr[3];
        q->decode_buf_ptr[3] = q->decode_buf_ptr[2];
        q->decode_buf_ptr[2] = tmp_ptr;

        /* FIXME: Rethink the gainbuffer handling, maybe a rename?
           now/previous swap */
        q->gain_now_ptr = &q->gain_now;
        q->gain_previous_ptr = &q->gain_previous;
        for (i=0 ; i<q->nb_channels ; i++){

            cook_imlt(q, q->decode_buf_ptr[i*2], q->mono_mdct_output, q->mlt_tmp);
            gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,
                            q->gain_previous_ptr, q->previous_buffer_ptr[0]);

            /* Swap out the previous buffer. */
            tmp_ptr = q->previous_buffer_ptr[0];
            q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1];
            q->previous_buffer_ptr[1] = tmp_ptr;

            /* Clip and convert the floats to 16 bits. */
            for (j=0 ; j<q->samples_per_frame ; j++){
                value = lrintf(q->mono_mdct_output[j]);
                if(value < -32768) value = -32768;
                else if(value > 32767) value = 32767;
                outbuffer[2*j+i] = value;
            }
        }

        memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain));
        memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain));

    } else if (q->nb_channels==2 && q->joint_stereo==0) {
            /* channel 0 */
            mono_decode(q, q->decode_buf_ptr2[0]);

            tmp_ptr = q->decode_buf_ptr2[0];
            q->decode_buf_ptr2[0] = q->decode_buf_ptr2[1];
            q->decode_buf_ptr2[1] = tmp_ptr;

            memcpy(&q->gain_channel1[0], &q->gain_current ,sizeof(COOKgain));
            q->gain_now_ptr = &q->gain_channel1[0];
            q->gain_previous_ptr = &q->gain_channel1[1];

            cook_imlt(q, q->decode_buf_ptr2[0], q->mono_mdct_output,q->mlt_tmp);
            gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,
                            q->gain_previous_ptr, q->mono_previous_buffer1);

            memcpy(&q->gain_channel1[1], &q->gain_channel1[0],sizeof(COOKgain));


            for (j=0 ; j<q->samples_per_frame ; j++){
                value = lrintf(q->mono_mdct_output[j]);
                if(value < -32768) value = -32768;
                else if(value > 32767) value = 32767;
                outbuffer[2*j+1] = value;
            }

            /* channel 1 */
            //av_log(NULL,AV_LOG_ERROR,"bits = %d\n",get_bits_count(&q->gb));
            init_get_bits(&q->gb, q->decoded_bytes_buffer, sub_packet_size*8+q->bits_per_subpacket);

            q->gain_now_ptr = &q->gain_channel2[0];
            q->gain_previous_ptr = &q->gain_channel2[1];

            decode_gain_info(&q->gb, &q->gain_channel2[0]);
            mono_decode(q, q->decode_buf_ptr[0]);

            tmp_ptr = q->decode_buf_ptr[0];
            q->decode_buf_ptr[0] = q->decode_buf_ptr[1];
            q->decode_buf_ptr[1] = tmp_ptr;

            cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp);
            gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,
                            q->gain_previous_ptr, q->mono_previous_buffer2);

            /* Swap out the previous buffer. */
            tmp_ptr = q->previous_buffer_ptr[0];
            q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1];
            q->previous_buffer_ptr[1] = tmp_ptr;

            memcpy(&q->gain_channel2[1], &q->gain_channel2[0] ,sizeof(COOKgain));

            for (j=0 ; j<q->samples_per_frame ; j++){
                value = lrintf(q->mono_mdct_output[j]);
                if(value < -32768) value = -32768;
                else if(value > 32767) value = 32767;
                outbuffer[2*j] = value;
            }

    } else {
        mono_decode(q, q->decode_buf_ptr[0]);

        /* Swap buffer pointers. */
        tmp_ptr = q->decode_buf_ptr[1];
        q->decode_buf_ptr[1] = q->decode_buf_ptr[0];
        q->decode_buf_ptr[0] = tmp_ptr;

        /* FIXME: Rethink the gainbuffer handling, maybe a rename?
           now/previous swap */
        q->gain_now_ptr = &q->gain_now;
        q->gain_previous_ptr = &q->gain_previous;

        cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp);
        gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr,
                        q->gain_previous_ptr, q->mono_previous_buffer1);

        /* Clip and convert the floats to 16 bits */
        for (j=0 ; j<q->samples_per_frame ; j++){
            value = lrintf(q->mono_mdct_output[j]);
            if(value < -32768) value = -32768;
            else if(value > 32767) value = 32767;
            outbuffer[j] = value;
        }
        memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain));
        memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain));
    }
    return q->samples_per_frame * sizeof(int16_t);
}