/* * recursively choose new u until intersection with x is found */ float find_u_intersect(float * x_u, float * y, float margin, control_point p[], float min, float max, float x, int trials) { if (trials != 0) { // find point between min and max float u_1 = (min + max)/2.0; // get x-value of Bezier curve for this point float x_1 = get_x_value(x_u, y, p, u_1); // compare with x, if within margin: return u_1 if (fabsf(x - x_1) < margin) { return u_1; } else { // get x-value of Bezier curve for left point float x_min = get_x_value(x_u, y, p, min); // check if we should continue with interval right or left of u_1 float diff_0 = x_min - x; float diff_1 = x_1 - x; if ( (diff_0 * diff_1) <= 0 ) { // interval left of u_1: run with u_1 as new max return find_u_intersect(x_u, y, margin, p, min, u_1, x, trials-1); } else { // interval right of u_1: run with u_1 as new min return find_u_intersect(x_u, y, margin, p, u_1, max, x, trials-1); } } } return -1.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); }