Enable higher quality resampling, as it doesn't have a noticeable performance
[asterisk-bristuff.git] / main / libresample / tests / resample-sndfile.c
blobe780228c17d26d249840e2edc247fa050b8e1e7e
1 /**********************************************************************
3 resample-sndfile.c
5 Written by Dominic Mazzoni
7 Based on resample-1.7:
8 http://www-ccrma.stanford.edu/~jos/resample/
10 License: LGPL - see the file LICENSE.txt for more information
12 **********************************************************************/
14 #include "../include/libresample.h"
16 #include <sndfile.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <math.h>
23 #include <sys/time.h>
25 #define MIN(A, B) (A) < (B)? (A) : (B)
27 void usage(char *progname)
29 fprintf(stderr, "Usage: %s -by <ratio> <input> <output>\n", progname);
30 fprintf(stderr, " %s -to <rate> <input> <output>\n", progname);
31 fprintf(stderr, "\n");
32 exit(-1);
35 int main(int argc, char **argv)
37 SNDFILE *srcfile, *dstfile;
38 SF_INFO srcinfo, dstinfo;
39 SF_FORMAT_INFO formatinfo;
40 char *extension;
41 void **handle;
42 int channels;
43 int srclen, dstlen;
44 float *src, *srci;
45 float *dst, *dsti;
46 double ratio = 0.0;
47 double srcrate;
48 double dstrate = 0.0;
49 struct timeval tv0, tv1;
50 double deltat;
51 int numformats;
52 int pos, bufferpos, outcount;
53 int i, c;
55 if (argc != 5)
56 usage(argv[0]);
58 if (!strcmp(argv[1], "-by")) {
59 ratio = atof(argv[2]);
60 if (ratio <= 0.0) {
61 fprintf(stderr, "Ratio of %f is illegal\n", ratio);
62 usage(argv[0]);
65 else if (!strcmp(argv[1], "-to")) {
66 dstrate = atof(argv[2]);
67 if (dstrate < 10.0 || dstrate > 100000.0) {
68 fprintf(stderr, "Sample rate of %f is illegal\n", dstrate);
69 usage(argv[0]);
72 else
73 usage(argv[0]);
75 memset(&srcinfo, 0, sizeof(srcinfo));
76 memset(&dstinfo, 0, sizeof(dstinfo));
77 srcfile = sf_open(argv[3], SFM_READ, &srcinfo);
78 if (!srcfile) {
79 fprintf(stderr, "%s", sf_strerror(NULL));
80 exit(-1);
83 srcrate = srcinfo.samplerate;
84 if (dstrate == 0.0)
85 dstrate = srcrate * ratio;
86 else
87 ratio = dstrate / srcrate;
89 channels = srcinfo.channels;
91 /* figure out format of destination file */
93 extension = strstr(argv[4], ".");
94 if (extension) {
95 extension++;
96 sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT,
97 &numformats, sizeof(numformats));
98 for(i=0; i<numformats; i++) {
99 memset(&formatinfo, 0, sizeof(formatinfo));
100 formatinfo.format = i;
101 sf_command(NULL, SFC_GET_FORMAT_MAJOR,
102 &formatinfo, sizeof(formatinfo));
103 if (!strcmp(formatinfo.extension, extension)) {
104 printf("Using %s for output format.\n", formatinfo.name);
105 dstinfo.format = formatinfo.format |
106 (srcinfo.format & SF_FORMAT_SUBMASK);
107 break;
112 if (!dstinfo.format) {
113 if (extension)
114 printf("Warning: output format (%s) not recognized, "
115 "using same as input format.\n",
116 extension);
117 dstinfo.format = srcinfo.format;
120 dstinfo.samplerate = (int)(dstrate + 0.5);
121 dstinfo.channels = channels;
123 dstfile = sf_open(argv[4], SFM_WRITE, &dstinfo);
124 if (!dstfile) {
125 fprintf(stderr, "%s", sf_strerror(NULL));
126 exit(-1);
129 printf("Source: %s (%d frames, %.2f Hz)\n",
130 argv[3], (int)srcinfo.frames, srcrate);
131 printf("Destination: %s (%.2f Hz, ratio=%.5f)\n", argv[4],
132 dstrate, ratio);
134 srclen = 4096;
135 dstlen = (srclen * ratio + 1000);
136 srci = (float *)malloc(srclen * channels * sizeof(float));
137 dsti = (float *)malloc(dstlen * channels * sizeof(float));
138 src = (float *)malloc(srclen * sizeof(float));
139 dst = (float *)malloc(dstlen * sizeof(float));
141 handle = (void **)malloc(channels * sizeof(void *));
142 for(c=0; c<channels; c++)
143 handle[c] = resample_open(1, ratio, ratio);
145 gettimeofday(&tv0, NULL);
147 pos = 0;
148 bufferpos = 0;
149 outcount = 0;
150 while(pos < srcinfo.frames) {
151 int block = MIN(srclen-bufferpos, srcinfo.frames-pos);
152 int lastFlag = (pos+block == srcinfo.frames);
153 int inUsed, inUsed2=0, out=0, out2=0;
155 sf_readf_float(srcfile, &srci[bufferpos*channels], block);
156 block += bufferpos;
158 for(c=0; c<channels; c++) {
159 for(i=0; i<block; i++)
160 src[i] = srci[i*channels+c];
162 inUsed = 0;
163 out = resample_process(handle[c], ratio, src, block, lastFlag,
164 &inUsed, dst, dstlen);
165 if (c==0) {
166 inUsed2 = inUsed;
167 out2 = out;
169 else {
170 if (inUsed2 != inUsed || out2 != out) {
171 fprintf(stderr, "Fatal error: channels out of sync!\n");
172 exit(-1);
176 for(i=0; i<out; i++)
178 if(dst[i] <= -1)
179 dsti[i*channels+c] = -1;
180 else if(dst[i] >= 1)
181 dsti[i*channels+c] = 1;
182 else
183 dsti[i*channels+c] = dst[i];
187 sf_writef_float(dstfile, dsti, out);
189 bufferpos = block - inUsed;
190 for(i=0; i<bufferpos*channels; i++)
191 srci[i] = srci[i+(inUsed*channels)];
192 pos += inUsed;
193 outcount += out;
196 sf_close(srcfile);
197 sf_close(dstfile);
199 gettimeofday(&tv1, NULL);
200 deltat =
201 (tv1.tv_sec + tv1.tv_usec * 0.000001) -
202 (tv0.tv_sec + tv0.tv_usec * 0.000001);
204 printf("Elapsed time: %.3f seconds\n", deltat);
205 printf("%d frames written to output file\n", outcount);
207 free(src);
208 free(srci);
209 free(dst);
210 free(dsti);
212 exit(0);