/* * Levinson-Durbin recursion on one array. Output arrays are put into * alpccoeff, klpccoeff and elpc. */ int array_levinson_1d(PyArrayObject *arr, long order, PyArrayObject** alpccoeff, PyArrayObject **klpccoeff, PyArrayObject **elpc) { double *tmp; npy_intp alpc_size = (order + 1); npy_intp klpc_size = order; npy_intp elpc_size = 1; *alpccoeff = (PyArrayObject*)PyArray_SimpleNew(1, &alpc_size, PyArray_DOUBLE); if(*alpccoeff == NULL) { return -1; } *klpccoeff = (PyArrayObject*)PyArray_SimpleNew(1, &klpc_size, NPY_DOUBLE); if(*klpccoeff == NULL) { goto clean_alpccoeff; } *elpc = (PyArrayObject*)PyArray_SimpleNew(1, &elpc_size, NPY_DOUBLE); if(*elpc == NULL) { goto clean_klpccoeff; } tmp = malloc(sizeof(*tmp) * order); if (tmp == NULL) { goto clean_elpc; } levinson((double*)(arr->data), order, (double*)((*alpccoeff)->data), (double*)((*elpc)->data), (double*)((*klpccoeff)->data), tmp); free(tmp); return 0; clean_elpc: Py_DECREF(*elpc); clean_klpccoeff: Py_DECREF(*klpccoeff); clean_alpccoeff: Py_DECREF(*alpccoeff); return -1; }
int array_levinson_nd(PyArrayObject *arr, long order, PyArrayObject** alpccoeff, PyArrayObject **klpccoeff, PyArrayObject **elpc) { double *acoeff, *kcoeff, *tmp; double *err; double *data; npy_int rank; npy_intp alpc_size[NPY_MAXDIMS]; npy_intp klpc_size[NPY_MAXDIMS]; npy_intp elpc_size[NPY_MAXDIMS]; npy_int n, nrepeat; int i; rank = PyArray_NDIM(arr); if (rank < 2) { return -1; } nrepeat = 1; for (i = 0; i < rank - 1; ++i) { nrepeat *= PyArray_DIM(arr, i); alpc_size[i] = PyArray_DIM(arr, i); klpc_size[i] = PyArray_DIM(arr, i); elpc_size[i] = PyArray_DIM(arr, i); } alpc_size[rank-1] = order + 1; klpc_size[rank-1] = order; *alpccoeff = (PyArrayObject*)PyArray_SimpleNew(rank, alpc_size, PyArray_DOUBLE); if(*alpccoeff == NULL) { return -1; } *klpccoeff = (PyArrayObject*)PyArray_SimpleNew(rank, klpc_size, NPY_DOUBLE); if(*klpccoeff == NULL) { goto clean_alpccoeff; } *elpc = (PyArrayObject*)PyArray_SimpleNew(rank-1, elpc_size, NPY_DOUBLE); if(*elpc == NULL) { goto clean_klpccoeff; } tmp = malloc(sizeof(*tmp) * order); if (tmp == NULL) { goto clean_elpc; } data = (double*)arr->data; acoeff = (double*)((*alpccoeff)->data); kcoeff = (double*)((*klpccoeff)->data); err = (double*)((*elpc)->data); n = PyArray_DIM(arr, rank-1); for(i = 0; i < nrepeat; ++i) { levinson(data, order, acoeff, err, kcoeff, tmp); data += n; acoeff += order + 1; kcoeff += order; err += 1; } free(tmp); return 0; clean_elpc: Py_DECREF(*elpc); clean_klpccoeff: Py_DECREF(*klpccoeff); clean_alpccoeff: Py_DECREF(*alpccoeff); return -1; }
void coder_ld8a( int ana[] /* output: analysis parameters */ ) { /* LPC coefficients */ FLOAT Aq_t[(MP1)*2]; /* A(z) quantized for the 2 subframes */ FLOAT Ap_t[(MP1)*2]; /* A(z) with spectral expansion */ FLOAT *Aq, *Ap; /* Pointer on Aq_t and Ap_t */ /* Other vectors */ FLOAT h1[L_SUBFR]; /* Impulse response h1[] */ FLOAT xn[L_SUBFR]; /* Target vector for pitch search */ FLOAT xn2[L_SUBFR]; /* Target vector for codebook search */ FLOAT code[L_SUBFR]; /* Fixed codebook excitation */ FLOAT y1[L_SUBFR]; /* Filtered adaptive excitation */ FLOAT y2[L_SUBFR]; /* Filtered fixed codebook excitation */ FLOAT g_coeff[5]; /* Correlations between xn, y1, & y2: <y1,y1>, <xn,y1>, <y2,y2>, <xn,y2>,<y1,y2>*/ /* Scalars */ int i, j, i_subfr; int T_op, T0, T0_min, T0_max, T0_frac; int index; FLOAT gain_pit, gain_code; int taming; /*------------------------------------------------------------------------* * - Perform LPC analysis: * * * autocorrelation + lag windowing * * * Levinson-durbin algorithm to find a[] * * * convert a[] to lsp[] * * * quantize and code the LSPs * * * find the interpolated LSPs and convert to a[] for the 2 * * subframes (both quantized and unquantized) * *------------------------------------------------------------------------*/ { /* Temporary vectors */ FLOAT r[MP1]; /* Autocorrelations */ FLOAT rc[M]; /* Reflexion coefficients */ FLOAT lsp_new[M]; /* lsp coefficients */ FLOAT lsp_new_q[M]; /* Quantized lsp coeff. */ /* LP analysis */ autocorr(p_window, M, r); /* Autocorrelations */ lag_window(M, r); /* Lag windowing */ levinson(r, Ap_t, rc); /* Levinson Durbin */ az_lsp(Ap_t, lsp_new, lsp_old); /* Convert A(z) to lsp */ /* LSP quantization */ qua_lsp(lsp_new, lsp_new_q, ana); ana += 2; /* Advance analysis parameters pointer */ /*--------------------------------------------------------------------* * Find interpolated LPC parameters in all subframes * * The interpolated parameters are in array Aq_t[]. * *--------------------------------------------------------------------*/ int_qlpc(lsp_old_q, lsp_new_q, Aq_t); /* Compute A(z/gamma) */ weight_az(&Aq_t[0], GAMMA1, M, &Ap_t[0]); weight_az(&Aq_t[MP1], GAMMA1, M, &Ap_t[MP1]); /* update the LSPs for the next frame */ copy(lsp_new, lsp_old, M); copy(lsp_new_q, lsp_old_q, M); } /*----------------------------------------------------------------------* * - Find the weighted input speech w_sp[] for the whole speech frame * * - Find the open-loop pitch delay for the whole speech frame * * - Set the range for searching closed-loop pitch in 1st subframe * *----------------------------------------------------------------------*/ residu(&Aq_t[0], &speech[0], &exc[0], L_SUBFR); residu(&Aq_t[MP1], &speech[L_SUBFR], &exc[L_SUBFR], L_SUBFR); { FLOAT Ap1[MP1]; Ap = Ap_t; Ap1[0] = (F)1.0; for(i=1; i<=M; i++) Ap1[i] = Ap[i] - (F)0.7 * Ap[i-1]; syn_filt(Ap1, &exc[0], &wsp[0], L_SUBFR, mem_w, 1); Ap += MP1; for(i=1; i<=M; i++) Ap1[i] = Ap[i] - (F)0.7 * Ap[i-1]; syn_filt(Ap1, &exc[L_SUBFR], &wsp[L_SUBFR], L_SUBFR, mem_w, 1); } /* Find open loop pitch lag for whole speech frame */ T_op = pitch_ol_fast(wsp, L_FRAME); /* Range for closed loop pitch search in 1st subframe */ T0_min = T_op - 3; if (T0_min < PIT_MIN) T0_min = PIT_MIN; T0_max = T0_min + 6; if (T0_max > PIT_MAX) { T0_max = PIT_MAX; T0_min = T0_max - 6; } /*------------------------------------------------------------------------* * Loop for every subframe in the analysis frame * *------------------------------------------------------------------------* * To find the pitch and innovation parameters. The subframe size is * * L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times. * * - find the weighted LPC coefficients * * - find the LPC residual signal * * - compute the target signal for pitch search * * - compute impulse response of weighted synthesis filter (h1[]) * * - find the closed-loop pitch parameters * * - encode the pitch delay * * - find target vector for codebook search * * - codebook search * * - VQ of pitch and codebook gains * * - update states of weighting filter * *------------------------------------------------------------------------*/ Aq = Aq_t; /* pointer to interpolated quantized LPC parameters */ Ap = Ap_t; /* pointer to weighted LPC coefficients */ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { /*---------------------------------------------------------------* * Compute impulse response, h1[], of weighted synthesis filter * *---------------------------------------------------------------*/ h1[0] = (F)1.0; set_zero(&h1[1], L_SUBFR-1); syn_filt(Ap, h1, h1, L_SUBFR, &h1[1], 0); /*-----------------------------------------------* * Find the target vector for pitch search: * *----------------------------------------------*/ syn_filt(Ap, &exc[i_subfr], xn, L_SUBFR, mem_w0, 0); /*-----------------------------------------------------------------* * Closed-loop fractional pitch search * *-----------------------------------------------------------------*/ T0 = pitch_fr3_fast(&exc[i_subfr], xn, h1, L_SUBFR, T0_min, T0_max, i_subfr, &T0_frac); index = enc_lag3(T0, T0_frac, &T0_min, &T0_max, PIT_MIN, PIT_MAX, i_subfr); *ana++ = index; if (i_subfr == 0) *ana++ = parity_pitch(index); /*-----------------------------------------------------------------* * - find filtered pitch exc * * - compute pitch gain and limit between 0 and 1.2 * * - update target vector for codebook search * * - find LTP residual. * *-----------------------------------------------------------------*/ syn_filt(Ap, &exc[i_subfr], y1, L_SUBFR, mem_zero, 0); gain_pit = g_pitch(xn, y1, g_coeff, L_SUBFR); /* clip pitch gain if taming is necessary */ taming = test_err(T0, T0_frac); if( taming == 1){ if (gain_pit > GPCLIP) { gain_pit = GPCLIP; } } for (i = 0; i < L_SUBFR; i++) xn2[i] = xn[i] - y1[i]*gain_pit; /*-----------------------------------------------------* * - Innovative codebook search. * *-----------------------------------------------------*/ index = ACELP_code_A(xn2, h1, T0, sharp, code, y2, &i); *ana++ = index; /* Positions index */ *ana++ = i; /* Signs index */ /*------------------------------------------------------* * - Compute the correlations <y2,y2>, <xn,y2>, <y1,y2>* * - Vector quantize gains. * *------------------------------------------------------*/ corr_xy2(xn, y1, y2, g_coeff); *ana++ =qua_gain(code, g_coeff, L_SUBFR, &gain_pit, &gain_code, taming); /*------------------------------------------------------------* * - Update pitch sharpening "sharp" with quantized gain_pit * *------------------------------------------------------------*/ sharp = gain_pit; if (sharp > SHARPMAX) sharp = SHARPMAX; if (sharp < SHARPMIN) sharp = SHARPMIN; /*------------------------------------------------------* * - Find the total excitation * * - update filters' memories for finding the target * * vector in the next subframe (mem_w0[]) * *------------------------------------------------------*/ for (i = 0; i < L_SUBFR; i++) exc[i+i_subfr] = gain_pit*exc[i+i_subfr] + gain_code*code[i]; update_exc_err(gain_pit, T0); for (i = L_SUBFR-M, j = 0; i < L_SUBFR; i++, j++) mem_w0[j] = xn[i] - gain_pit*y1[i] - gain_code*y2[i]; Aq += MP1; /* interpolated LPC parameters for next subframe */ Ap += MP1; } /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_FRAME: * * speech[], wsp[] and exc[] * *--------------------------------------------------*/ copy(&old_speech[L_FRAME], &old_speech[0], L_TOTAL-L_FRAME); copy(&old_wsp[L_FRAME], &old_wsp[0], PIT_MAX); copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL); return; }
int main(int argc,char **argv) { if(argc < 2) { fprintf(stderr,"Usage : %s <input.sela>\n",argv[0]); return -1; } FILE *infile = fopen(argv[1],"rb"); if(infile == NULL) { fprintf(stderr,"Error while opening input.\n"); return -1; } int sample_rate,temp,i,j = 0; unsigned char opt_lpc_order; const int frame_sync = 0xAA55FF00; const int corr = 1 << 20; unsigned int frame_count = 0; const short Q = 20; short bps; unsigned short num_ref_elements,num_residue_elements,samples_per_channel; unsigned char channels,curr_channel,rice_param_ref,rice_param_residue; PacketList list; audio_format fmt; pthread_t play_thread; signed short signed_decomp_ref[MAX_LPC_ORDER]; unsigned short compressed_ref[MAX_LPC_ORDER]; unsigned short compressed_residues[BLOCK_SIZE]; unsigned short decomp_ref[MAX_LPC_ORDER]; short s_ref[MAX_LPC_ORDER]; short s_rcv_samples[BLOCK_SIZE]; unsigned short decomp_residues[BLOCK_SIZE]; short s_residues[BLOCK_SIZE]; int rcv_samples[BLOCK_SIZE]; int lpc[MAX_LPC_ORDER + 1]; double ref[MAX_LPC_ORDER]; double lpc_mat[MAX_LPC_ORDER][MAX_LPC_ORDER]; fread(&sample_rate,sizeof(int),1,infile); fread(&bps,sizeof(short),1,infile); fread(&channels,sizeof(unsigned char),1,infile); fprintf(stderr,"Sample rate : %d Hz\n",sample_rate); fprintf(stderr,"Bits per sample : %d\n",bps); fprintf(stderr,"Channels : %d\n",channels); fmt.sample_rate = sample_rate; fmt.num_channels = channels; fmt.bits_per_sample = bps; initialize_pulse(&fmt); PacketQueueInit(&list); //Start playback thread pthread_create(&play_thread,NULL,&playback_func,(void *)(&list)); //Main loop while(feof(infile) == 0) { short *buffer = (short *)malloc(sizeof(short) * BLOCK_SIZE * channels); fread(&temp,sizeof(int),1,infile);//Read from input if(temp == frame_sync) { for(i = 0; i < channels; i++) { fread(&curr_channel,sizeof(unsigned char),1,infile); //Read rice_params,bytes,encoded lpc_coeffs from input fread(&rice_param_ref,sizeof(unsigned char),1,infile); fread(&num_ref_elements,sizeof(unsigned short),1,infile); fread(&opt_lpc_order,sizeof(unsigned char),1,infile); fread(compressed_ref,sizeof(unsigned short),num_ref_elements,infile); //Read rice_params,bytes,encoded residues from input fread(&rice_param_residue,sizeof(unsigned char),1,infile); fread(&num_residue_elements,sizeof(unsigned short),1,infile); fread(&samples_per_channel,sizeof(unsigned short),1,infile); fread(compressed_residues,sizeof(unsigned short),num_residue_elements,infile); //Decode compressed reflection coefficients and residues char decoded_lpc_num = rice_decode_block(rice_param_ref,compressed_ref,opt_lpc_order,decomp_ref); assert(decoded_lpc_num == opt_lpc_order); short decomp_residues_num = rice_decode_block(rice_param_residue,compressed_residues,samples_per_channel,decomp_residues); assert(decomp_residues_num == samples_per_channel); //unsigned to signed unsigned_to_signed(opt_lpc_order,decomp_ref,s_ref); unsigned_to_signed(samples_per_channel,decomp_residues,s_residues); //Dequantize reflection coefficients dqtz_ref_cof(s_ref,opt_lpc_order,Q,ref); //Generate lpc coefficients levinson(NULL,opt_lpc_order,ref,lpc_mat); lpc[0] = 0; for(int k = 0; k < opt_lpc_order; k++) lpc[k+1] = corr * lpc_mat[opt_lpc_order - 1][k]; //Generate original calc_signal(s_residues,samples_per_channel,opt_lpc_order,Q,lpc,rcv_samples); //Copy_to_short for(int k = 0; k < samples_per_channel; k++) s_rcv_samples[k] = rcv_samples[k]; //Combine samples from all channels for(int k = 0; k < samples_per_channel; k++) buffer[channels * k + i] = s_rcv_samples[k]; } PacketNode *node=(PacketNode *)malloc(sizeof(PacketNode)); node->packet = (char *)buffer; node->packet_size = samples_per_channel * channels * sizeof(short); PacketQueuePut(&list,node);//Insert in list } else { fprintf(stderr,"Sync lost\n"); break; } } pthread_join(play_thread,NULL); destroy_pulse(); fclose(infile); return 0; }
/* Autocorrelation-based LPC analysis Performs the LPC analysis on a given frame... returns the lpc coefficients Input arguments xx: input buffer pointer aa: LPC coefficients pointer (output) size: size of the input buffer (xx) nlpc: LPC order, i.e., number of LPC coefficients SC (2008/05/06): Incoroporating cepstral lifting */ void LPFormantTracker::getAi(dtype* xx, dtype* aa) { int i0; //dtype temp_frame[maxBufLen + maxNLPC]; // Utility buffer for various filtering operations //dtype R[maxNLPC]; // lpc fit Autocorrelation estimate int nlpcplus1 = nLPC + 1; for(i0 = 0; i0 < nlpcplus1; i0++) temp_frame[i0] = 0; // Window input //SC vecmu1: vector multiply //SC hwin: a Hanning window DSPF_dp_vecmul(xx, winFunc, &temp_frame[nlpcplus1], bufferSize); // Apply a Hanning window // TODO: Check temp_frame size //////////////////////////////////////////////////// //SC(2008/05/07) ----- Cepstral lifting ----- if (bCepsLift){ for (i0=0;i0<nFFT;i0++){ if (i0 < bufferSize){ ftBuf1[i0 * 2] = temp_frame[nlpcplus1 + i0]; ftBuf1[i0 * 2 + 1]=0; } else{ ftBuf1[i0 * 2] = 0; ftBuf1[i0 * 2 + 1] = 0; } } DSPF_dp_cfftr2(nFFT, ftBuf1, fftc, 1); bit_rev(ftBuf1, nFFT); // Now ftBuf1 is X for (i0 = 0; i0 < nFFT; i0++){ if (i0 <= nFFT / 2){ ftBuf2[i0 * 2] = log(sqrt(ftBuf1[i0*2]*ftBuf1[i0*2]+ftBuf1[i0*2+1]*ftBuf1[i0*2+1])); // Optimize ftBuf2[i0 * 2 + 1]=0; } else{ ftBuf2[i0 * 2] = ftBuf2[(nFFT - i0) * 2]; ftBuf2[i0 * 2 + 1]=0; } } DSPF_dp_icfftr2(nFFT, ftBuf2, fftc, 1); bit_rev(ftBuf2, nFFT); // Now ftBuf2 is Xceps: the cepstrum for (i0 = 0; i0 < nFFT; i0++){ if (i0 < cepsWinWidth || i0 > nFFT - cepsWinWidth){ // Adjust! ftBuf1[i0 * 2] = ftBuf2[i0 * 2] / nFFT; // Normlize the result of the previous IFFT ftBuf1[i0 * 2 + 1] = 0; } else{ ftBuf1[i0 * 2] = 0; ftBuf1[i0 * 2 + 1] = 0; } } // Now ftBuf1 is Xcepw: the windowed cepstrum DSPF_dp_cfftr2(nFFT,ftBuf1,fftc,1); bit_rev(ftBuf1,nFFT); for (i0=0;i0<nFFT;i0++){ if (i0<=nFFT/2){ ftBuf2[i0*2]=exp(ftBuf1[i0*2]); ftBuf2[i0*2+1]=0; } else{ ftBuf2[i0*2]=ftBuf2[(nFFT-i0)*2]; ftBuf2[i0*2+1]=0; } } DSPF_dp_icfftr2(nFFT,ftBuf2,fftc,1); // Need normalization bit_rev(ftBuf2,nFFT); for (i0 = 0; i0 < bufferSize / 2; i0++){ temp_frame[nlpcplus1 + bufferSize / 2 + i0] = ftBuf2[i0 * 2] / nFFT; } for (i0 = 1; i0 < bufferSize / 2; i0++){ temp_frame[nlpcplus1 + bufferSize / 2 - i0] = ftBuf2[i0 * 2] / nFFT; } temp_frame[nlpcplus1] = 0.0; } //~SC(2008/05/07) ----- Cepstral lifting ----- /////////////////////////////////////////////////////////// // Find autocorrelation values DSPF_dp_autocor(R, temp_frame, bufferSize, nlpcplus1); //SC Get LPC coefficients by autocorrelation // Get unbiased autocorrelation for(i0 = 0; i0 < nlpcplus1; i0++) R[i0] /= bufferSize; // levinson recursion levinson(R, aa, nlpcplus1); }