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.