Beispiel #1
0
/**
 * First part of subpacket decoding:
 *  decode raw stream bytes and read gain info.
 *
 * @param q                 pointer to the COOKContext
 * @param inbuffer          pointer to raw stream data
 * @param gains_ptr         array of current/prev gain pointers
 */
static inline void decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p,
                                         const uint8_t *inbuffer,
                                         cook_gains *gains_ptr)
{
    int offset;

    offset = decode_bytes(inbuffer, q->decoded_bytes_buffer,
                          p->bits_per_subpacket / 8);
    init_get_bits(&q->gb, q->decoded_bytes_buffer + offset,
                  p->bits_per_subpacket);
    decode_gain_info(&q->gb, gains_ptr->now);

    /* Swap current and previous gains */
    FFSWAP(int *, gains_ptr->now, gains_ptr->previous);
}
Beispiel #2
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);
}