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); }
/** * 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); } } }
/** * 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; }
/** * 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; }
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; } }
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); }