ftp.nice.ch/pub/next/unix/developer/_VoiceClass.s/VoiceClass/SrateConvert/codex_convert.c

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

#include <stdio.h>
#include <sound/sound.h>
#include <math.h>

/*  	This is a command line c function call to implement sampling rate conversion on a sound.
	This version does sinc table lookup interpolation on CODEX sounds only.
	The general version is found in srate_convert.c. Usage is:
	
	codex_convert factor filein fileout
*/
	


#define WIDTH 10		/* this controls the number of neighboring samples
				   which are used to interpolate the new samples.  The
				   processing time is linearly related to this width */
#define USE_TABLE TRUE		/* this controls whether a linearly interpolated lookup
				   table is used for sinc function calculation, or the
				   sinc is calculated by floating point trig function calls.  */
#define SAMPLES_PER_ZERO_CROSSING 10	/* this defines how finely the sinc function is sampled
					for storage in the table  */


float sinc_table[WIDTH * SAMPLES_PER_ZERO_CROSSING] = { 0.0 };

main(int argc,char *argv[])	/* sampling rate convert filename by factor.
					   factor should be less than 1.0 or file must
					   be pre-filtered to band-limit to NewSrate/2.	*/
{
    extern double t_sinc(double x),make_sinc();
    char *file_name_in,*file_name_out;
    float fact;
    double temp1=0.0,temp2=0.0,time=0.0,factor;
    unsigned char *codex_data_in,*codex_data_out;
    int i=0,j,left_limit,right_limit,num_samples;
    SNDSoundStruct *sound_in,*sound_out;
    
    if (argc!=4) {
        fprintf(stderr,"usage: srate_convert factor filein fileout\n");
	exit(0);
    }
    file_name_in = argv[2];
    file_name_out = argv[3];
    sscanf(argv[1],"%f",&fact);
    factor = fact;
    if (factor<0.01 || factor>100) {
        fprintf(stderr,"Your factor is a little extreme!!!\n");
	exit(0);
    }
    printf("Converting by: %f file: %s to file: %s\n",factor,file_name_in,file_name_out);
    SNDReadSoundfile(file_name_in,&sound_in);
    num_samples = sound_in->dataSize;
    				/* allocate an output sound and set data pointers */
    if (sound_in->dataFormat == 1) {		
        SNDAlloc(&sound_out, (int) ((double) num_samples / factor),
			 sound_in->dataFormat, sound_in->samplingRate, 1, 4);    
	codex_data_in = (unsigned char *) sound_in + sound_in->dataLocation;
	codex_data_out = (unsigned char *) sound_out + sound_out->dataLocation;
   }
   else {
        fprintf(stderr,"CODEX sounds only for this version!!!\n");
	exit(0);
   }
    make_sinc();

    while (time < num_samples)	{
	temp1 = 0.0;
	temp2 = 0.0;
	left_limit = time - WIDTH + 1;	/* leftmost neighboring sample used for interp.*/
	right_limit = time + WIDTH;	/* rightmost leftmost neighboring sample used for interp.*/
	if (left_limit<0) left_limit = 0;
	if (right_limit>num_samples) right_limit = num_samples;
	for (j=left_limit;j<right_limit;j++)	{
	    temp1 += SNDiMulaw(codex_data_in[j]) * t_sinc(time - j);
	    codex_data_out[i] = SNDMulaw((short) temp1);
	}
	i++;
	time += factor;
    }
    SNDWait(SNDWriteSoundfile(file_name_out,sound_out));
    SNDFree(sound_in);
    SNDFree(sound_out);
    return;
}

#define PI 3.14159263

make_sinc()
{
    int i;
    double temp,win_freq,win;
    win_freq = PI / WIDTH / SAMPLES_PER_ZERO_CROSSING;
    sinc_table[0] = 1.0;
    for (i=1;i<WIDTH * SAMPLES_PER_ZERO_CROSSING;i++)	{
        temp = (double) i * PI / SAMPLES_PER_ZERO_CROSSING;
	sinc_table[i] = sin(temp) / temp;
	win = 0.5 + 0.5 * cos(win_freq * i);
	sinc_table[i] *= win;
    }
    return;
}

double linear_interp(double first_number,double second_number,double fraction)
{
    return (first_number + ((second_number - first_number) * fraction));
}

double t_sinc(double x)
{
    int low;
    double temp,delta;
    if (fabs(x)>WIDTH-1)
        return 0.0;
    else {
        temp = fabs(x) * (double) SAMPLES_PER_ZERO_CROSSING;
        low = temp;					/* these are interpolation steps */
        delta = temp - low;				/* and can be ommited if desired */
        return linear_interp(sinc_table[low],sinc_table[low + 1],delta);
				/* for no interpolation case, return sinc_table[low]	*/
    }
}

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