Example #1
0
File: _lpc.c Project: yekm/talkbox
/*
 * 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;
}
Example #2
0
File: _lpc.c Project: yekm/talkbox
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;
}
Example #3
0
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;

}
Example #4
0
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);
}