/* Rate 1/4 CCSDS turbo encoder */

void turbo(int m[N],int c[4*N+16],int perm[N]) {
	/* Convolutional encoder tables */
	int nexts[16][2]={{0,1},{2,3},{4,5},{6,7},{9,8},{11,10},{13,12},{15,14},
		{1,0},{3,2},{5,4},{7,6},{8,9},{10,11},{12,13},{14,15}};
	int term[16]={0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0};
	int enc[16][2]={{0,15},{10,5},{12,3},{6,9},{4,11},{14,1},{8,7},{2,13},
		{0,15},{10,5},{12,3},{6,9},{4,11},{14,1},{8,7},{2,13}};

	int statea=0,stateb=0,inp,outa,outb;
	int i;

	for (i=0;i<N+4;i++) {
		inp=(i>=N)?term[statea]:m[i];	/* Encode message */
		outa=enc[statea][inp];
		statea=nexts[statea][inp];

		inp=(i>=N)?term[stateb]:m[perm[i]];	/* Encode interleaved message */
		outb=enc[stateb][inp];
		stateb=nexts[stateb][inp];

		*c++=outa & 1;     /* out0a */	/* Multiplex results */
		*c++=outa>>2 & 1;  /* out2a */
		*c++=outa>>3 & 1;  /* out3a */
		*c++=outb>>1 & 1;  /* out1b */
	}
}