solaris\sun studio porting

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2880 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris
2006-09-30 02:40:39 +00:00
parent 4c0d89aace
commit 32fce49ba3
45 changed files with 26427 additions and 29 deletions

View File

@@ -0,0 +1,183 @@
/**********************************************************************
compareresample.c
Real-time library interface by Dominic Mazzoni
Based on resample-1.7:
http://www-ccrma.stanford.edu/~jos/resample/
License: LGPL - see the file LICENSE.txt for more information
**********************************************************************/
#include "../include/libresample.h"
#include <samplerate.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#define MIN(A, B) (A) < (B)? (A) : (B)
void dostat(char *name, float *d1, float *d2, int len)
{
int i;
double sum, sumsq, err, rmserr;
sum = 0.0;
sumsq = 0.0;
for(i=0; i<len; i++) {
double diff = d1[i] - d2[i];
sum += fabs(diff);
sumsq += diff * diff;
}
err = sum / len;
rmserr = sqrt(sumsq / len);
printf(" %s: Avg err: %f RMS err: %f\n", name, err, rmserr);
}
void runtest(float *src, int srclen,
float *ans, int anslen,
double factor)
{
struct timeval tv0, tv1;
int dstlen = (int)(srclen * factor);
float *dst_rs = (float *)malloc((dstlen+100) * sizeof(float));
float *dst_rabbit = (float *)malloc((dstlen+100) * sizeof(float));
void *handle;
SRC_DATA rabbit;
double deltat;
int srcblocksize = srclen;
int dstblocksize = dstlen;
int i, out, out_rabbit, o, srcused;
int statlen, srcpos;
/* do resample */
for(i=0; i<dstlen+100; i++)
dst_rs[i] = -99.0;
gettimeofday(&tv0, NULL);
handle = resample_open(1, factor, factor);
out = 0;
srcpos = 0;
for(;;) {
int srcBlock = MIN(srclen-srcpos, srcblocksize);
int lastFlag = (srcBlock == srclen-srcpos);
o = resample_process(handle, factor,
&src[srcpos], srcBlock,
lastFlag, &srcused,
&dst_rs[out], MIN(dstlen-out, dstblocksize));
srcpos += srcused;
if (o >= 0)
out += o;
if (o < 0 || (o == 0 && srcpos == srclen))
break;
}
resample_close(handle);
gettimeofday(&tv1, NULL);
deltat =
(tv1.tv_sec + tv1.tv_usec * 0.000001) -
(tv0.tv_sec + tv0.tv_usec * 0.000001);
if (o < 0) {
printf("Error: resample_process returned an error: %d\n", o);
}
if (out <= 0) {
printf("Error: resample_process returned %d samples\n", out);
free(dst_rs);
return;
}
printf(" resample: %.3f seconds, %d outputs\n", deltat, out);
/* do rabbit (Erik's libsamplerate) */
for(i=0; i<dstlen+100; i++)
dst_rabbit[i] = -99.0;
rabbit.data_in = src;
rabbit.data_out = dst_rabbit;
rabbit.input_frames = srclen;
rabbit.output_frames = dstlen;
rabbit.input_frames_used = 0;
rabbit.output_frames_gen = 0;
rabbit.end_of_input = 1;
rabbit.src_ratio = factor;
gettimeofday(&tv0, NULL);
/* src_simple(&rabbit, SRC_SINC_BEST_QUALITY, 1); */
src_simple(&rabbit, SRC_SINC_FASTEST, 1);
/* src_simple(&rabbit, SRC_LINEAR, 1); */
gettimeofday(&tv1, NULL);
deltat =
(tv1.tv_sec + tv1.tv_usec * 0.000001) -
(tv0.tv_sec + tv0.tv_usec * 0.000001);
out_rabbit = rabbit.output_frames_gen;
printf(" rabbit : %.3f seconds, %d outputs\n",
deltat, out_rabbit);
statlen = MIN(out, out_rabbit);
if (anslen > 0)
statlen = MIN(statlen, anslen);
if (ans) {
dostat("resample ", dst_rs, ans, statlen);
dostat("rabbit ", dst_rabbit, ans, statlen);
}
dostat( "RS vs rabbit", dst_rs, dst_rabbit, statlen);
free(dst_rs);
free(dst_rabbit);
}
int main(int argc, char **argv)
{
int i, srclen;
float *src, *ans;
printf("\n*** sin wave, factor = 1.0 *** \n\n");
srclen = 100000;
src = malloc(srclen * sizeof(float));
for(i=0; i<srclen; i++)
src[i] = sin(i/100.0);
runtest(src, srclen, src, srclen, 1.0);
printf("\n*** sin wave, factor = 0.25 *** \n\n");
srclen = 100000;
for(i=0; i<srclen; i++)
src[i] = sin(i/100.0);
ans = malloc((srclen/4) * sizeof(float));
for(i=0; i<srclen/4; i++)
ans[i] = sin(i/25.0);
runtest(src, srclen, ans, srclen/4, 0.25);
free(ans);
printf("\n*** sin wave, factor = 4.0 *** \n\n");
srclen = 20000;
for(i=0; i<srclen; i++)
src[i] = sin(i/100.0);
ans = malloc((srclen*4) * sizeof(float));
for(i=0; i<srclen*4; i++)
ans[i] = sin(i/400.0);
runtest(src, srclen, ans, srclen*4, 4.0);
free(ans);
free(src);
return 0;
}

View File

@@ -0,0 +1,213 @@
/**********************************************************************
resample-sndfile.c
Written by Dominic Mazzoni
Based on resample-1.7:
http://www-ccrma.stanford.edu/~jos/resample/
License: LGPL - see the file LICENSE.txt for more information
**********************************************************************/
#include "../include/libresample.h"
#include <sndfile.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/time.h>
#define MIN(A, B) (A) < (B)? (A) : (B)
void usage(char *progname)
{
fprintf(stderr, "Usage: %s -by <ratio> <input> <output>\n", progname);
fprintf(stderr, " %s -to <rate> <input> <output>\n", progname);
fprintf(stderr, "\n");
exit(-1);
}
int main(int argc, char **argv)
{
SNDFILE *srcfile, *dstfile;
SF_INFO srcinfo, dstinfo;
SF_FORMAT_INFO formatinfo;
char *extension;
void **handle;
int channels;
int srclen, dstlen;
float *src, *srci;
float *dst, *dsti;
double ratio = 0.0;
double srcrate;
double dstrate = 0.0;
struct timeval tv0, tv1;
double deltat;
int numformats;
int pos, bufferpos, outcount;
int i, c;
if (argc != 5)
usage(argv[0]);
if (!strcmp(argv[1], "-by")) {
ratio = atof(argv[2]);
if (ratio <= 0.0) {
fprintf(stderr, "Ratio of %f is illegal\n", ratio);
usage(argv[0]);
}
}
else if (!strcmp(argv[1], "-to")) {
dstrate = atof(argv[2]);
if (dstrate < 10.0 || dstrate > 100000.0) {
fprintf(stderr, "Sample rate of %f is illegal\n", dstrate);
usage(argv[0]);
}
}
else
usage(argv[0]);
memset(&srcinfo, 0, sizeof(srcinfo));
memset(&dstinfo, 0, sizeof(dstinfo));
srcfile = sf_open(argv[3], SFM_READ, &srcinfo);
if (!srcfile) {
fprintf(stderr, "%s", sf_strerror(NULL));
exit(-1);
}
srcrate = srcinfo.samplerate;
if (dstrate == 0.0)
dstrate = srcrate * ratio;
else
ratio = dstrate / srcrate;
channels = srcinfo.channels;
/* figure out format of destination file */
extension = strstr(argv[4], ".");
if (extension) {
extension++;
sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT,
&numformats, sizeof(numformats));
for(i=0; i<numformats; i++) {
memset(&formatinfo, 0, sizeof(formatinfo));
formatinfo.format = i;
sf_command(NULL, SFC_GET_FORMAT_MAJOR,
&formatinfo, sizeof(formatinfo));
if (!strcmp(formatinfo.extension, extension)) {
printf("Using %s for output format.\n", formatinfo.name);
dstinfo.format = formatinfo.format |
(srcinfo.format & SF_FORMAT_SUBMASK);
break;
}
}
}
if (!dstinfo.format) {
if (extension)
printf("Warning: output format (%s) not recognized, "
"using same as input format.\n",
extension);
dstinfo.format = srcinfo.format;
}
dstinfo.samplerate = (int)(dstrate + 0.5);
dstinfo.channels = channels;
dstfile = sf_open(argv[4], SFM_WRITE, &dstinfo);
if (!dstfile) {
fprintf(stderr, "%s", sf_strerror(NULL));
exit(-1);
}
printf("Source: %s (%d frames, %.2f Hz)\n",
argv[3], (int)srcinfo.frames, srcrate);
printf("Destination: %s (%.2f Hz, ratio=%.5f)\n", argv[4],
dstrate, ratio);
srclen = 4096;
dstlen = (srclen * ratio + 1000);
srci = (float *)malloc(srclen * channels * sizeof(float));
dsti = (float *)malloc(dstlen * channels * sizeof(float));
src = (float *)malloc(srclen * sizeof(float));
dst = (float *)malloc(dstlen * sizeof(float));
handle = (void **)malloc(channels * sizeof(void *));
for(c=0; c<channels; c++)
handle[c] = resample_open(1, ratio, ratio);
gettimeofday(&tv0, NULL);
pos = 0;
bufferpos = 0;
outcount = 0;
while(pos < srcinfo.frames) {
int block = MIN(srclen-bufferpos, srcinfo.frames-pos);
int lastFlag = (pos+block == srcinfo.frames);
int inUsed, inUsed2=0, out=0, out2=0;
sf_readf_float(srcfile, &srci[bufferpos*channels], block);
block += bufferpos;
for(c=0; c<channels; c++) {
for(i=0; i<block; i++)
src[i] = srci[i*channels+c];
inUsed = 0;
out = resample_process(handle[c], ratio, src, block, lastFlag,
&inUsed, dst, dstlen);
if (c==0) {
inUsed2 = inUsed;
out2 = out;
}
else {
if (inUsed2 != inUsed || out2 != out) {
fprintf(stderr, "Fatal error: channels out of sync!\n");
exit(-1);
}
}
for(i=0; i<out; i++)
{
if(dst[i] <= -1)
dsti[i*channels+c] = -1;
else if(dst[i] >= 1)
dsti[i*channels+c] = 1;
else
dsti[i*channels+c] = dst[i];
}
}
sf_writef_float(dstfile, dsti, out);
bufferpos = block - inUsed;
for(i=0; i<bufferpos*channels; i++)
srci[i] = srci[i+(inUsed*channels)];
pos += inUsed;
outcount += out;
}
sf_close(srcfile);
sf_close(dstfile);
gettimeofday(&tv1, NULL);
deltat =
(tv1.tv_sec + tv1.tv_usec * 0.000001) -
(tv0.tv_sec + tv0.tv_usec * 0.000001);
printf("Elapsed time: %.3f seconds\n", deltat);
printf("%d frames written to output file\n", outcount);
free(src);
free(srci);
free(dst);
free(dsti);
exit(0);
}

View File

@@ -0,0 +1,182 @@
/**********************************************************************
testresample.c
Real-time library interface by Dominic Mazzoni
Based on resample-1.7:
http://www-ccrma.stanford.edu/~jos/resample/
License: LGPL - see the file LICENSE.txt for more information
**********************************************************************/
#include "../include/libresample.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MIN(A, B) (A) < (B)? (A) : (B)
void runtest(int srclen, double freq, double factor,
int srcblocksize, int dstblocksize)
{
int expectedlen = (int)(srclen * factor);
int dstlen = expectedlen + 1000;
float *src = (float *)malloc((srclen+100) * sizeof(float));
float *dst = (float *)malloc((dstlen+100) * sizeof(float));
void *handle;
double sum, sumsq, err, rmserr;
int i, out, o, srcused, errcount, rangecount;
int statlen, srcpos, lendiff;
int fwidth;
printf("-- srclen: %d sin freq: %.1f factor: %.3f srcblk: %d dstblk: %d\n",
srclen, freq, factor, srcblocksize, dstblocksize);
for(i=0; i<srclen; i++)
src[i] = sin(i/freq);
for(i=srclen; i<srclen+100; i++)
src[i] = -99.0;
for(i=0; i<dstlen+100; i++)
dst[i] = -99.0;
handle = resample_open(1, factor, factor);
fwidth = resample_get_filter_width(handle);
out = 0;
srcpos = 0;
for(;;) {
int srcBlock = MIN(srclen-srcpos, srcblocksize);
int lastFlag = (srcBlock == srclen-srcpos);
o = resample_process(handle, factor,
&src[srcpos], srcBlock,
lastFlag, &srcused,
&dst[out], MIN(dstlen-out, dstblocksize));
srcpos += srcused;
if (o >= 0)
out += o;
if (o < 0 || (o == 0 && srcpos == srclen))
break;
}
resample_close(handle);
if (o < 0) {
printf("Error: resample_process returned an error: %d\n", o);
}
if (out <= 0) {
printf("Error: resample_process returned %d samples\n", out);
free(src);
free(dst);
return;
}
lendiff = abs(out - expectedlen);
if (lendiff > (int)(2*factor + 1.0)) {
printf(" Expected ~%d, got %d samples out\n",
expectedlen, out);
}
sum = 0.0;
sumsq = 0.0;
errcount = 0.0;
/* Don't compute statistics on all output values; the last few
are guaranteed to be off because it's based on far less
interpolation. */
statlen = out - fwidth;
for(i=0; i<statlen; i++) {
double diff = sin((i/freq)/factor) - dst[i];
if (fabs(diff) > 0.05) {
if (errcount == 0)
printf(" First error at i=%d: expected %.3f, got %.3f\n",
i, sin((i/freq)/factor), dst[i]);
errcount++;
}
sum += fabs(diff);
sumsq += diff * diff;
}
rangecount = 0;
for(i=0; i<statlen; i++) {
if (dst[i] < -1.01 || dst[i] > 1.01) {
if (rangecount == 0)
printf(" Error at i=%d: value is %.3f\n", i, dst[i]);
rangecount++;
}
}
if (rangecount > 1)
printf(" At least %d samples were out of range\n", rangecount);
if (errcount > 0) {
i = out - 1;
printf(" i=%d: expected %.3f, got %.3f\n",
i, sin((i/freq)/factor), dst[i]);
printf(" At least %d samples had significant error.\n", errcount);
}
err = sum / statlen;
rmserr = sqrt(sumsq / statlen);
printf(" Out: %d samples Avg err: %f RMS err: %f\n", out, err, rmserr);
free(src);
free(dst);
}
int main(int argc, char **argv)
{
int i, srclen, dstlen, ifreq;
double factor;
printf("\n*** Vary source block size*** \n\n");
srclen = 10000;
ifreq = 100;
for(i=0; i<20; i++) {
factor = ((rand() % 16) + 1) / 4.0;
dstlen = (int)(srclen * factor + 10);
runtest(srclen, (double)ifreq, factor, 64, dstlen);
runtest(srclen, (double)ifreq, factor, 32, dstlen);
runtest(srclen, (double)ifreq, factor, 8, dstlen);
runtest(srclen, (double)ifreq, factor, 2, dstlen);
runtest(srclen, (double)ifreq, factor, srclen, dstlen);
}
printf("\n*** Vary dest block size ***\n\n");
srclen = 10000;
ifreq = 100;
for(i=0; i<20; i++) {
factor = ((rand() % 16) + 1) / 4.0;
runtest(srclen, (double)ifreq, factor, srclen, 32);
dstlen = (int)(srclen * factor + 10);
runtest(srclen, (double)ifreq, factor, srclen, dstlen);
}
printf("\n*** Resample factor 1.0, testing different srclen ***\n\n");
ifreq = 40;
for(i=0; i<100; i++) {
srclen = (rand() % 30000) + 10;
dstlen = (int)(srclen + 10);
runtest(srclen, (double)ifreq, 1.0, srclen, dstlen);
}
printf("\n*** Resample factor 1.0, testing different sin freq ***\n\n");
srclen = 10000;
for(i=0; i<100; i++) {
ifreq = ((int)rand() % 10000) + 1;
dstlen = (int)(srclen * 10);
runtest(srclen, (double)ifreq, 1.0, srclen, dstlen);
}
printf("\n*** Resample with different factors ***\n\n");
srclen = 10000;
ifreq = 100;
for(i=0; i<100; i++) {
factor = ((rand() % 64) + 1) / 4.0;
dstlen = (int)(srclen * factor + 10);
runtest(srclen, (double)ifreq, factor, srclen, dstlen);
}
return 0;
}