mirror of https://github.com/asterisk/asterisk
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							214 lines
						
					
					
						
							5.4 KiB
						
					
					
				
			
		
		
	
	
							214 lines
						
					
					
						
							5.4 KiB
						
					
					
				| /**********************************************************************
 | |
| 
 | |
|   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);
 | |
| }
 |