ftp.nice.ch/pub/next/unix/audio/cmix.s.tar.gz#/cmix/lpc/anallpc.c

This is anallpc.c in view mode; [Download] [Up]

#include "../H/sfheader.h"
#include <stdio.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <math.h>

/* Standalone analysis program, designed to read only integer, mono 
 * sound files.  Seems to be able to squeeze in 34 pole analysis.
 * cc -o anallpc anallpc.c -lsf -lndir -l42 -lm
 * Right now it is scaled to a maximum of 34 poles and a maximum
 * segment size of 500, which means that the frame slices must not
 * exceed 250.  On a separate i/d machine these can be comfortably
 * increased.  This program takes about 58k as scaled here. */

int NPOLE;
int FRAME;
int NPP1;

#define POLEMAX 100 
#define FLOAT 4
#define FRAMAX   1000 
#define NDATA 4 /* number of data values stored with frame */

main()
{
	int jj,slice,ii,counter;
	SFHEADER sfh;
        int pos;
	float coef[POLEMAX+NDATA],inskip,dur;
	char name[36];
	double errn,rms1,rms2,cc[40];
	short sigs[FRAMAX];
	int sigi[FRAMAX];
	long i,nsamps,begbyte,outskip;
	short *cyllist;
	int anal,sound,nbytes,nblpc,firstframe,nread;
	struct stat sfst;
	int result;

	fprintf(stderr,"Enter name of output data file\t");
	gets(name);
	if((anal = open(name,2)) < 0) {
		fprintf(stderr," Can't open data file\n");
		exit(1);
	}

	fprintf(stderr,"Enter name of soundfile to analyze\t");
	gets(name);
	readopensf(name,sound,sfh,sfst,"anallpc",result);
	if(result < 0) {
		exit(1);
	}
	printsf(&sfh);

	if(sfchans(&sfh) != 1) {
		fprintf(stderr," Can only analyze mono file, sorry\n");
		exit(1);
	}

	if(sfclass(&sfh) != SF_SHORT) {
		fprintf(stderr," Can only analyze integer file\n");
		exit(1);
	}


	fprintf(stderr,"Enter number of poles and frame size\t");
	scanf("%d %d",&NPOLE,&slice);
	if(NPOLE > POLEMAX) {   
		fprintf(stderr,"exceeds maximum allowed\n");
		exit(1);
	}

	FRAME = slice * 2;
	if(FRAME > FRAMAX) {
		fprintf(stderr,"exceeds maximum allowed\n");
		exit(1);
	}

	fprintf(stderr,"Specify input skip, and duration to analyze\t");
	scanf("%f %f",&inskip,&dur);

	begbyte = (long)(inskip * sfsrate(&sfh)) * (long)sfclass(&sfh);
	if(pos = sflseek(sound,begbyte,0) < 0) {
		fprintf(stderr,"Bad sflseek\n");
		exit(1);
	}

	fprintf(stderr,"Specify starting output frame number\t");
	scanf("%d",&firstframe);

	NPP1 = NPOLE+1;
	nblpc = (NPOLE + NDATA)*FLOAT;
	outskip = firstframe * nblpc;
	if((lseek(anal,outskip,0)) < 0) {
		fprintf(stderr,"Bad lseek on analysis file\n");
		exit(1);
	}
	nsamps = dur * sfsrate(&sfh);
	if((nread = read(sound, (char *)sigs, FRAME * sfclass(&sfh))) !=
	    FRAME * sfclass(&sfh)) {
		fprintf(stderr," Bad sfread, nread = %d\n",nread);
		exit(1);
	}


	for(i=0;i<FRAME;i++) sigi[i] = sigs[i];

	i = 0;
	counter = 1;
	while(i < nsamps) {

		alpol(sigi,&errn,&rms1,&rms2,cc);
		coef[0] = (float)rms2;
		coef[1] = (float)rms1;
		coef[2] = (float)errn;

		/*printf("%d %f %f %f %f\n",
			counter++,coef[0],coef[1],coef[2],coef[3]);
		*/

		coef[3] = 0.;  /*save for pitch of frame */

		for(jj=NDATA; jj<NPOLE+NDATA; jj++) /* reverse order and change sign */
			coef[jj] = (float)-cc[NPOLE-jj+(NDATA - 1)];  

		for(jj=0; jj<slice; jj++) {
			sigi[jj] = sigi[jj+slice];
		}

		if((nread=read(sound,(char *)(sigs+(short)slice),
     		      slice * sfclass(&sfh))) != slice * sfclass(&sfh)) {
			fprintf(stderr," bad read, n= %d\n",nread);
			exit(1);
		}
		for(jj=0;jj<slice;jj++) sigi[jj+slice] = sigs[jj+slice];


		if((nbytes = write(anal,(char *)coef,nblpc))!= nblpc) {
			printf(" write error, nbytes = %d\n",nbytes);
			exit(1);
		}
	}
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.