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.