Beispiel #1
0
/* Creates a new file and writes a header with the given characteristics.
   <type> is a sndlib constant for header type (e.g. MUS_AIFF).
   <format> is a sndlib constant for sound data format (e.g. snd_16_linear).
   (These constants are defined in sndlib.h.) Caller is responsible for
   checking that the header type and data format are compatible, and that
   the header type is one that sndlib can write (is WRITEABLE_HEADER_TYPE()).
   Writes no comment.

   NOTE: This will truncate an existing file with <sfname>, so check first!

   On success, returns a standard file descriptor, and leaves the file
   position pointer at the end of the header.
   On failure, returns -1. Caller can check errno then.
*/
int
sndlib_create(char *sfname, /* file name */
	      int type, /* file type, e.g. AIFF */
	      int format, /* data format, e.g., MU-LAW */
	      int srate, /* sampling rate in Hz */
	      int chans, /* 1 for mono, 2 for stereo */
	      char *comment)
{
   int  fd, loc;
   assert(sfname != NULL && strlen(sfname) <= FILENAME_MAX);
   mus_header_initialize(); // make sure relevant parts of sndlib are initialized
   //resample-1.8: sndlib_write_header(fd, 0, type, format, srate, chans, comment, &loc)
   //resample-1.8: mus_file_open_descriptors(fd, format, mus_header_data_format_to_bytes_per_sample(),loc);
   // int mus_file_open_descriptors(int tfd, const char *arg, int df, int ds, off_t dl, int dc, int dt);
   fd = mus_sound_open_output(sfname, srate, chans, format, type, "created by resample");
   return fd;
}
Beispiel #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);
}
Beispiel #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);

}