Пример #1
0
/* Let user load a function table with samples from a sound file.  The file
   can be 16-bit integer or 32-bit floating point in either byte order, and
   in any of the header formats recognized by sndlib.  The makegen syntax
   used in Minc is:

      frames_read = makegen(slot, 1, size, filename, inskip [, inchan, dump])

   <size> is the duration (in seconds) of the sound file segment, or if it's
   negative, the number of sample frames to read.  If <size> is zero, the
   whole file is slurpped in.  (Beware with large files -- there is no
   check on memory consumption here!)

   <filename> is a double-quoted pathname (as in rtinput).

   <inskip> is the time (in seconds) to skip before reading, or if it's 
   negative, the number of sample frames to skip before reading.

   If <inchan> is missing, reads all channels from the file; otherwise,
   reads just the channel specified by <inchan> (with zero as first chan).

   If <dump> is 1, then dumps the gen table to a header-less sound file,
   called "dumpaudio.raw," in the current directory.  The file is 32-bit
   float, using the host byte order, <inchan> chans, and the sampling
   rate in the source file's header.

   As usual, if the slot number is positive, the table will be rescaled
   to fit in the range [-1,1]; if it's negative, it will not be rescaled.

   Returns to Minc the number of sample frames read.

   JGG, 07 Feb 2001
*/
double
gen1(struct gen *gen, char *sfname)
{
   int      i, fd, header_type, data_format, data_location, inchan;
   int      gen_chans, gen_frames, gen_samps, file_chans, file_frames;
   int      start_frame, bytes_per_samp, byteswap, is_float, dump;
   int      buf_start_frame, end_frame, frames_read, buf_frames;
   long     file_samps;
   off_t    seek_to;
   float    request_dur, filedur, inskip;
   double   srate, *block, *blockp;
   char     *buf;

   request_dur = gen->pvals[0];
   inskip = gen->pvals[2];
   if (gen->nargs > 3)
      inchan = (int) gen->pvals[3];
   else
      inchan = -1;   /* read all chans */
   dump = gen->nargs > 4? (int) gen->pvals[4] : 0;

   fd = open_sound_file("gen1", sfname, &header_type, &data_format,
                        &data_location, &srate, &file_chans, &file_samps);
   if (fd == -1)
      return die("gen1", "Can't open input file: \"%s\"!", sfname);

   if (srate != SR()) {
      rtcmix_warn("gen1", "The input file sampling rate is %g, but "
                      "the output rate is currently %g.", srate, SR());
   }

   file_frames = file_samps / file_chans;

   if (inchan == -1)
      gen_chans = file_chans;
   else
      gen_chans = 1;

   if (file_chans == 1)
      inchan = -1;                       /* more efficient copy below */

   if (inchan >= file_chans)
      return die("gen1", "You asked for channel %d of a %d-channel file. (\"%s\")",
                                                   inchan, file_chans, sfname);

   if (request_dur < 0.0)
      gen_frames = (int) -request_dur;
   else if (request_dur > 0.0)
      gen_frames = (int) (request_dur * srate);
   else
      gen_frames = file_frames;

   if (inskip < 0.0)
      start_frame = (int) -inskip;
   else
      start_frame = (int) (inskip * srate); 

   if (start_frame + gen_frames > file_frames)
      gen_frames = file_frames - start_frame;

   gen_samps = gen_frames * gen_chans;
 
   block = (double *) malloc((size_t) (gen_samps * sizeof(double)));
   if (block == NULL)
      return die("gen1", "Not enough memory for function table %d.", gen->slot);

   buf = (char *) malloc((size_t) BUFSIZE);
	if (buf == NULL) {
		free(block);
      return die("gen1", "Not enough memory for temporary buffer.");
	}

   bytes_per_samp = mus_data_format_to_bytes_per_sample(data_format);

   seek_to = data_location + (start_frame * file_chans * bytes_per_samp);
   if (lseek(fd, seek_to, SEEK_SET) == -1) {
	   free(block);
	   free(buf);
		return die("gen1", "lseek() failed");
   }

#if MUS_LITTLE_ENDIAN
   byteswap = IS_BIG_ENDIAN_FORMAT(data_format);
#else
   byteswap = IS_LITTLE_ENDIAN_FORMAT(data_format);
#endif
   is_float = IS_FLOAT_FORMAT(data_format);

   buf_frames = (BUFSIZE / bytes_per_samp) / file_chans;

   end_frame = start_frame + gen_frames;

   blockp = block;
   frames_read = 0;
   buf_start_frame = start_frame;
   for ( ; buf_start_frame < end_frame; buf_start_frame += frames_read) {
      int  samps_read;
      long bytes_read;

      if (buf_start_frame + buf_frames > end_frame) {      /* last buffer */
         int samps = (end_frame - buf_start_frame) * file_chans;
         bytes_read = read(fd, buf, samps * bytes_per_samp);
      }
      else
         bytes_read = read(fd, buf, BUFSIZE);
      if (bytes_read == -1) {
		  free(block);
		  free(buf);
		  return die("gen1", "read() failed");
      }
      if (bytes_read == 0)          /* EOF, somehow */
         break;

      samps_read = bytes_read / bytes_per_samp;
      frames_read = samps_read / file_chans;

      if (is_float) {
         float *bufp = (float *) buf;

         if (inchan == -1) {                 /* store all chans */
            if (byteswap) {
               for (i = 0; i < samps_read; i++) {
                  byte_reverse4(bufp);       /* modify *bufp in place */
                  *blockp++ = (double) *bufp++;
               }
            }
            else {
               for (i = 0; i < samps_read; i++)
                  *blockp++ = (double) *bufp++;
            }
         }
         else {                              /* store only inchan */
            bufp += inchan;
            if (byteswap) {
               for (i = 0; i < samps_read; i += file_chans) {
                  byte_reverse4(bufp);       /* modify *bufp in place */
                  *blockp++ = (double) *bufp;
                  bufp += file_chans;
               }
            }
            else {
               for (i = 0; i < samps_read; i += file_chans) {
                  *blockp++ = (double) *bufp;
                  bufp += file_chans;
               }
            }
         }
      }
      else {                                 /* is shortint file */
         short *bufp = (short *) buf;

         if (inchan == -1) {                 /* store all chans */
            if (byteswap) {
               for (i = 0; i < samps_read; i++, bufp++) {
                  short samp = reverse_int2(bufp);
                  *blockp++ = (double) samp;
               }
            }
            else {
               for (i = 0; i < samps_read; i++)
                  *blockp++ = (double) *bufp++;
            }
         }
         else {                              /* store only inchan */
            bufp += inchan;
            if (byteswap) {
               for (i = 0; i < samps_read; i += file_chans) {
                  short samp = reverse_int2(bufp);
                  *blockp++ = (double) samp;
                  bufp += file_chans;
               }
            }
            else {
               for (i = 0; i < samps_read; i += file_chans) {
                  *blockp++ = (double) *bufp;
                  bufp += file_chans;
               }
            }
         }
      }
   }

   free(buf);
   sndlib_close(fd, 0, 0, 0, 0);

   gen->array = block;
   gen->size = gen_samps;

   fnscl(gen);

   if (dump)
      dump_gen_to_raw_file(block, gen_samps);

   return (double) gen_frames;
}
Пример #2
0
/* compute_residual
 * ================
 * Computes the difference between the synthesis and the original sound. 
 * the <win-samps> array contains the sample numbers in the input file corresponding to each frame
 * audio: pointer to analyzed data
 * fil_len: length of data in samples
 * output_file: output file path
 * sound: pointer to ATS_SOUND
 * win_samps: pointer to array of analysis windows center times
 * file_sampling_rate: sampling rate of analysis file
 */
void compute_residual(ANARGS *anargs, int fil_len, char *output_file, ATS_SOUND *sound, int *win_samps)
{
  int i, frm, frm_1, frm_2, par, frames, partials, frm_samps, out_smp=0, ptout;
  double *in_buff, *synth_buff, mag, a1, a2, f1, f2, p1, p2, diff, synth;
  mus_sample_t **obuf;

  frames = sound->frames;
  partials = sound->partials;
  frm_samps = sound->frame_size;
  mag = TWOPI / (double)anargs->srate;
  /* this might fail if fil_len or frm_samps changes */
  if(anargs->residual == NULL) anargs->residual = (double *)calloc(fil_len + 2*frm_samps, sizeof(double));
  //      fprintf(stderr, "fil_len %d, frames %d, frm_samps %d\n", fil_len, frames, frm_samps);

  in_buff = (double *)malloc(frm_samps * sizeof(double));
  synth_buff = (double *)malloc(frm_samps * sizeof(double));
  /* open output file */
  if((ptout=mus_sound_open_output(output_file,anargs->srate,2,MUS_LSHORT,MUS_RIFF,"created by ATSA"))==-1) {
    fprintf(stderr, "\nERROR: can't open file %s for writing\n", output_file);  
    exit(1);
  } 
  /* allocate memory */
  obuf = (mus_sample_t **)malloc(2*sizeof(mus_sample_t *));
  obuf[0] = (mus_sample_t *)calloc(frm_samps, sizeof(mus_sample_t));
  obuf[1] = (mus_sample_t *)calloc(frm_samps, sizeof(mus_sample_t));
  /* compute residual frame by frame */
  for(frm=1; frm<frames; frm++) {
    /* clean buffers up */
    for(i=0; i<frm_samps; i++) in_buff[i] = synth_buff[i] = 0.0;
    frm_1 = frm - 1;
    frm_2 = frm;
    /* read frame from input */
    read_frame(anargs->audio, fil_len, win_samps[frm_1], win_samps[frm_2], in_buff);
    /* compute one synthesis frame */
    for(par=0; par<partials; par++) {
      a1 = sound->amp[par][frm_1];
      a2 = sound->amp[par][frm_2];
      /*  have to convert the frequency into radians per sample!!! */
      f1 = sound->frq[par][frm_1] * mag;
      f2 = sound->frq[par][frm_2] * mag;
      p1 = sound->pha[par][frm_1];
      p2 = sound->pha[par][frm_2];
      if( !( a1 <= 0.0 && a2 <= 0.0 ) ) {
	/* check amp 0 in frame 1 */
	if(a1 <= 0.0) {
	  f1 = f2;
	  p1 =  p2 - ( f2 * frm_samps );
      	  while(p1 > PI) p1 -= TWOPI;
      	  while(p1 < (PI * -1)) p1 += TWOPI;
      	}
	/* check amp 0 in frame 2 */
      	if(a2 <= 0.0) {
      	  f2 = f1;
      	  p2 = p1 + ( f1 * frm_samps );
      	  while(p2 > PI) p2 -= TWOPI;
      	  while(p2 < (PI * -1)) p2 += TWOPI;
      	}
	synth_buffer(a1, a2, f1, f2, p1, p2, synth_buff, frm_samps);
      }
    }
    /* write output: chan 0 residual, chan 1 synthesis */
    for(i=0; i<frm_samps; i++) {
      synth = synth_buff[i];
      diff = in_buff[i] - synth;
      obuf[0][i] = MUS_DOUBLE_TO_SAMPLE(diff);
      obuf[1][i] = MUS_DOUBLE_TO_SAMPLE(synth);
      anargs->residual[out_smp] = diff;
      out_smp++;
    }
    mus_sound_write(ptout, 0, frm_samps-1, 2, obuf);
  }
  free(in_buff);
  free(synth_buff);
  /* update header and close output file */
  mus_sound_close_output(ptout,2 * out_smp * mus_data_format_to_bytes_per_sample(MUS_LSHORT));
  free(obuf[0]);
  free(obuf[1]);
  free(obuf);
  //for(i=0; i<fil_len; i++) audio[i] = res[i];
  //free(res);
}
Пример #3
0
////////////////////////////////////////////////////////////////////
/////////THIS IS THE MAIN SYNTHESIS LOOP////////////////////////////
////////////////////////////////////////////////////////////////////
void do_synthesis()
{
  int i,x,z,j,maxlen, todo, curr, next, sflag=0;
  float dt=0., rfreq;
  float frame_samps, bw=.1;
  int   ptout;
  float maxamp=0.;
  int   bframe=0, eframe=0;
  int   nValue=0;
  char  stamp[16];
  int   written;
  int   format,header;
  mus_sample_t *obuf[1];
  float cxval, cyval, nxval, nyval, difx, dify;
  TIME_DATA *tdata;
  int nbp;
  float *dospt=NULL, *rospt=NULL;
  RANDI *rarray=NULL;
  float res_band_edges[ATSA_CRITICAL_BANDS+1]=ATSA_CRITICAL_BAND_EDGES;
  float res_band_centers[ATSA_CRITICAL_BANDS];
  char str[100];

  //ATTEMPT TO CATCH TWO POSSIBLE ERRORS........ 
  if(*ats_tittle==0) {
    Popup("ERROR: ATS file undefined,  select it first");
    return; 
  }
  if(*out_tittle==0) {
    Popup("ERROR: Output Soundfile undefined, select it first");  
    return; 
  }  
  if(sparams->amp==0. && sparams->ramp==0.) {
    Popup("ERROR: Deterministic and Residual output set to zero");  
    return; 
  }  


  //OPEN OUTPUT FILE
  set_output_type(&format, &header);

  if((ptout=mus_sound_open_output(out_tittle,(int)sparams->sr,1,format,header,"created by ATSH"))==-1) {
    Popup("ERROR: could not open Output Soundfile for writing");  
    return;
  }

  //do residual data transfer
  if (FILE_HAS_NOISE)
    for(i=0; i<(int)atshed->fra; ++i) band_energy_to_res(ats_sound, i);

  //NOW CHECK WHAT TO DO...
  if(sparams->amp > 0.) sflag |= SYNTH_DET;  //deterministic synthesis only
  if(sparams->ramp > 0.) sflag |= SYNTH_RES; //residual synthesis only

  tl_sr = (float)TABLE_LENGTH / sparams->sr; //needed for ioscilator...
  nbp   = get_nbp(timenv->curve);
  tdata = (TIME_DATA*)malloc(nbp * sizeof(TIME_DATA));
  

  //g_print(" \nNPOINTS= %d \n", nbp); 
  sparams->max_stretch=0.;  
  todo=0;

  //We first must calculate data of each breakpoint
  timenv->dur=fabs(timenv->dur); //correct if negative
  for(i=0; i < nbp - 1; ++i){
    //get the data from the time envelope and convert it to time
    cxval= timenv->dur * (get_x_value(timenv->curve,i)/100.);
    cyval= timenv->ymin + ((timenv->ymax - timenv->ymin) * (get_y_value(timenv->curve,i)/100.));
    nxval= timenv->dur * (get_x_value(timenv->curve,i+1)/100.);
    nyval= timenv->ymin + ((timenv->ymax - timenv->ymin) * (get_y_value(timenv->curve,i+1)/100.));
    
    //diff=0. is a special case we must take in account
    //here all we do is to set it to one millisecond (arbitrarly)
    difx= nxval - cxval;
    if(difx == 0.) difx=.001; 
    dify= nyval - cyval;
    if(dify == 0.) dify=.001; 

    //find out the max. stretching factor(needed to alocate the I/O buffer)
    if(fabs(difx) / fabs(dify) >= sparams->max_stretch) {
      sparams->max_stretch=fabs(difx) / fabs(dify);
    }
    
    //locate the frame for the beggining and end of segments
    if(i == 0){
      if(dify < 0.) bframe= locate_frame((int)atshed->fra-1,cyval, dify);
      else bframe= locate_frame(0,cyval, dify);
    }
    eframe= locate_frame(bframe, nyval, dify);
    //collect the data to be used
    tdata[i].from=bframe;
    tdata[i].to  =eframe;
    tdata[i].size= (int)(abs(eframe - bframe)) + 1;
    tdata[i].tfac=fabs(difx) / fabs(dify);
    todo+=tdata[i].size;
    
    //g_print("\n from frame=%d to frame=%d", bframe,eframe);

    bframe=eframe;
    ////////////////////////////////////////////////////////
    
  }
  

  //INITIALIZE PROGRESSBAR
  strcpy(str,"Writing File " );
  strcat(str, out_tittle);
  StartProgress(str, TRUE);

  //ALLOCATE AND CLEAN AUDIO BUFFERS
  maxlen= (int)ceil(maxtim * sparams->sr * sparams->max_stretch); 
  frbuf = (float *) malloc(maxlen * sizeof(float));
  for(z = 0; z < maxlen; ++z) frbuf[z]=0.;
  obuf[0] = (mus_sample_t *)calloc(maxlen, sizeof(mus_sample_t));

  switch(sflag) { //see which memory resources do we need and allocate them
  case SYNTH_DET: 
    dospt = (float *) malloc( (int)atshed->par * sizeof(float));
    for(z=0; z<(int)atshed->par; ++z) dospt[z]=0.;
    break;
    
  case SYNTH_RES: 
    rospt = (float *) malloc((int)ATSA_CRITICAL_BANDS * sizeof(float)); 
    rarray= (RANDI *) malloc((int)ATSA_CRITICAL_BANDS * sizeof(RANDI));
    for(z=0; z<(int)ATSA_CRITICAL_BANDS; ++z) {
      res_band_centers[z]= res_band_edges[z]+((res_band_edges[z+1]-res_band_edges[z])*0.5); 
      randi_setup(sparams->sr,res_band_edges[z+1]-res_band_edges[z],&rarray[z]);
      rospt[z]=0.;
    }
    break;

  case SYNTH_BOTH: 
    dospt = (float *) malloc( (int)atshed->par * sizeof(float));
    rarray= (RANDI *) malloc( (int)atshed->par * sizeof(RANDI));
    for(z=0; z<(int)atshed->par; ++z) {
      rfreq=(ats_sound->frq[z][tdata[0].from] < 500.? 50. : ats_sound->frq[z][tdata[0].from] * bw);
      randi_setup(sparams->sr,rfreq,&rarray[z]);
      dospt[z]=0.;
    }
    break;  

  }
  //NOW DO IT...
  written=0;
  stopper=FALSE;

  for(i = 0; i < nbp - 1; i++) { 

    curr=tdata[i].from;
 
    for(j=0; j < tdata[i].size;   j++) {

      next=(tdata[i].from < tdata[i].to ? curr+1 : curr-1 );	        
      if(next < 0 || next >= (int)atshed->fra) break;

      dt=fabs(ats_sound->time[0][next] - ats_sound->time[0][curr]);
      frame_samps=dt * sparams->sr * tdata[i].tfac ;      

      switch (sflag) {
      case SYNTH_DET: { //deterministic synthesis only
	for(x = 0; x < (int)atshed->par; x++) {                       
	  synth_deterministic_only(ats_sound->amp[x][curr], 
				   ats_sound->amp[x][next], 
				   ats_sound->frq[x][curr] * sparams->frec,
				   ats_sound->frq[x][next] * sparams->frec, 
				   frame_samps,x, dospt);     	  	         
	}
	break;
      }	
      case SYNTH_RES: { //residual synthesis only
	for(x = 0; x < (int)ATSA_CRITICAL_BANDS; x++) {
	  synth_residual_only(ENG_RMS(ats_sound->band_energy[x][curr], atshed->ws), 
			      ENG_RMS(ats_sound->band_energy[x][next],atshed->ws) ,
			      res_band_centers[x],frame_samps,x,rospt,&rarray[x]);  
	}
	break;
      }
      case SYNTH_BOTH: { //residual and deterministic synthesis  
	for(x = 0; x < (int)atshed->par; x++) {
	  rfreq=(ats_sound->frq[x][curr] < 500.? 50. : ats_sound->frq[x][curr]* bw);
	  synth_both(ats_sound->amp[x][curr], 
		     ats_sound->amp[x][next], 
		     ats_sound->frq[x][curr] * sparams->frec,
		     ats_sound->frq[x][next] * sparams->frec, 
		     frame_samps,x, dospt,
		     ENG_RMS(ats_sound->res[x][curr] * sparams->ramp, atshed->ws), 
		     ENG_RMS(ats_sound->res[x][next] * sparams->ramp, atshed->ws),
		     &rarray[x]);     	  	         
	}
	break;
	
      }
      }//end switch
      
      for(z=0; z< maxlen; ++z) {      //write and clean output buffer     
	if(z < (int)frame_samps) {      
	  
	  obuf[0][z] = MUS_FLOAT_TO_SAMPLE(frbuf[z]);	  
	  written++;
	  if (fabs(frbuf[z]) >= maxamp) {maxamp=fabs(frbuf[z]);}
	}
	frbuf[z]=0.;   
      }
      mus_sound_write(ptout, 0, frame_samps-1, 1, obuf);
      if(stopper==TRUE) goto finish;
      ++nValue;
      UpdateProgress(nValue,todo);
      curr=(tdata[i].from < tdata[i].to ? curr+1 :curr-1  );
    }
    
  } //CHANGE BREAKPOINT
  
 finish:

  free(frbuf);
  
  switch (sflag) {
  case SYNTH_DET:
    free(dospt);
    break;
  case SYNTH_RES: 
    free(rospt);
    free(rarray);
    break;
  case SYNTH_BOTH: 
    free(dospt);
    free(rarray);
    break;
  }
  
  mus_sound_close_output(ptout,written * mus_data_format_to_bytes_per_sample(format));

//   *info=0;
//   strcat(info, "DONE OK...!!! MAXAMP= ");
//   sprintf(stamp,"%6.4f ",maxamp);
//   strcat(info, stamp);
//   Popup(info);

  free(obuf[0]);
  free(tdata);
  EndProgress();

  strcpy(str, "DONE! MAXAMP= ");
  sprintf(stamp, "%6.4f", maxamp);
  strcat(str, stamp);
  Popup(str);

}