Ejemplo n.º 1
0
 int ConstRateResample::Process(double  factor,
                                float  *inBuffer,
                                int     inBufferLen,
                                bool    lastFlag,
                                int    *inBufferUsed,
                                float  *outBuffer,
                                int     outBufferLen)
 {
    return resample_process(mHandle, factor, inBuffer, inBufferLen,
                            (int)lastFlag, inBufferUsed, outBuffer, outBufferLen);
 }
Ejemplo n.º 2
0
static int resample_frame(struct ast_trans_pvt *pvt,
	void *resampler, float resample_factor, struct ast_frame *f)
{
	int total_in_buf_used = 0;
	int total_out_buf_used = 0;
	int16_t *in_buf = (int16_t *) f->data;
	int16_t *out_buf = (int16_t *) pvt->outbuf + pvt->samples;
	float in_buf_f[f->samples];
	float out_buf_f[2048];
	int res = 0;
	int i;

	for (i = 0; i < f->samples; i++)
		in_buf_f[i] = in_buf[i] * (FLT_MAX / SHRT_MAX);

	while (total_in_buf_used < f->samples) {
		int in_buf_used, out_buf_used;

		out_buf_used = resample_process(resampler, resample_factor,
			&in_buf_f[total_in_buf_used], f->samples - total_in_buf_used,
			0, &in_buf_used,
			&out_buf_f[total_out_buf_used], ARRAY_LEN(out_buf_f) - total_out_buf_used);

		if (out_buf_used < 0)
			break;

		total_out_buf_used += out_buf_used;
		total_in_buf_used += in_buf_used;

		if (total_out_buf_used == ARRAY_LEN(out_buf_f)) {
			ast_log(LOG_ERROR, "Output buffer filled ... need to increase its size\n");
			res = -1;
			break;
		}
	}

	for (i = 0; i < total_out_buf_used; i++)
		out_buf[i] = out_buf_f[i] * (SHRT_MAX / FLT_MAX);	

	pvt->samples += total_out_buf_used;
	pvt->datalen += (total_out_buf_used * sizeof(int16_t));

	return res;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
FOOIDAPI int fp_feed_float(t_fooid * fid, float *data, int len)
{
    int pos;
    int c;
    float accum;
    int inpos;
    int res_out;
    int in_used;

    /*
        check input validity
    */
    if (len % fid->channels != 0) {
        return -1;
    }

    len = len / fid->channels;

	/*
	  cut the invalid data at start of music, only do once.
	*/
//	printf("[fp_feed_float] len = %d \n ", len);
	const float min_float = 1.0f / 32768.0f - EPSILON;
    if (!fid->soundfound) {
        pos = 0;
		//delete the zero part at the head of song's data.
        while (!fid->soundfound && pos < len) {
            for (c = 0; c < fid->channels; c++) {
                if (fabs(data[(pos * fid->channels) + c]) >= min_float ) {
                //if (fabs(data[(pos * fid->channels) + c]) >= (1.0f/32768.0f - EPSILON)) {
                    fid->soundfound = TRUE;
                }
            }
            if (!fid->soundfound) {
                pos++;			//the usable data start point store in poinger pos.
            }
        }
        /*
            end without sound?
        */
        if (pos >= len && !fid->soundfound) {
            return TRUE;
        }

        /*
            adjust start
        */
        len  = len - pos;
//
		printf(" [fp_feed_float] pos =%d, adjust len: %d\n",pos, len);
        data = data + (pos * fid->channels); //cut the data.
    }

    /*
        silly user feeding us more than we need?
    */
    if (fid->outpos >= SSIZE) {
        return FALSE;	//if 8000hz data (resample data) more than 100s, then return 0.
    }

	//printf("fp_feed_float] fid->outpos=%d\n", fid->outpos );
    /*
        now we have music data queued up
        process it at most IN_LEN at a time
    */
    do {
        /*
            read samples
        */
        for (pos = 0; pos < len && pos < IN_LEN; pos++) {
            /*
                downmix sample
            */
			// add 2 or more channels data, and avrage to a nono channel data
			// input to resample function.
            accum = 0;
            for (c = 0; c < fid->channels; c++) {
                accum += data[(pos * fid->channels) + c];
            }
            accum /= (float)fid->channels;

            fid->sbuffer[pos] = accum;
        }

        inpos = 0;
        /*
            feed to resampler
        */
        do {
			// return  out sample count.
            res_out = resample_process(fid->resample_h, fid->resample_ratio,
                                       &(fid->sbuffer[inpos]), min(IN_LEN - inpos, len), FALSE,
                                       &in_used,
                                       &(fid->samples[fid->outpos]), SSIZE - fid->outpos);
            //fid->outpos is a pointer at the t_fooid's samples array.
			//fid->outpos dislay the calculate data is enough?(8000*10)
			fid->outpos += res_out;  
            inpos       += in_used;
        } while (in_used < min(IN_LEN, len) && fid->outpos < SSIZE);
		

        /*
            are we done yet?
        */
        if (fid->outpos >= SSIZE) {
            return FALSE;
        }

        /*
            check if there's still input left
        */
        len  = len - in_used;
        data = data + (in_used * fid->channels);
    } while (len > 0);

    return TRUE;
}
Ejemplo n.º 5
0
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++)
            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);
}