Exemple #1
0
void SimpleChorusModel::process_chorus(float leftInput, float rightInput,
				       float* leftOutput, float* rightOutput) {
  float ocsDiff;

  _ocsDistance = _depthAmp * sinus[(int)_index];
  
  ocsDiff = _ocsDistance - floorf(_ocsDistance);

  _past_position_left = MAXBUFFERLENGTH //to be sure that _past_position_left>0
    + _position - _leftMidDistance + (int)_ocsDistance;
  _past_position_right = MAXBUFFERLENGTH
    + _position - _rightMidDistance + (int)_ocsDistance;

  *leftOutput = _leftAmp *
    lin_interp(ocsDiff, _leftBuffer[_past_position_left%MAXBUFFERLENGTH],
	       _leftBuffer[(_past_position_left+1)%MAXBUFFERLENGTH]);
  *rightOutput = _rightAmp *
    lin_interp(ocsDiff, _rightBuffer[_past_position_right%MAXBUFFERLENGTH],
	       _rightBuffer[(_past_position_right+1)%MAXBUFFERLENGTH]);

  _leftBuffer[_position] = leftInput;
  _rightBuffer[_position] = rightInput;
  
  _position++;
  _position %= MAXBUFFERLENGTH;
  
  _index += _inct;
  _index = (_index<MAXSINUSRESOLUTION?_index:_index-MAXSINUSRESOLUTION);
}
Exemple #2
0
void SimpleChorusModel::setChorus() {
  //inct
  _inct = (float)MAXSINUSRESOLUTION/_sampleRate * _LFOFreq;
  //left & right amp
  _leftAmp = lin_interp(1.0 - _pan, 1.0 - PANAMP, 1.0 + PANAMP);
  _rightAmp = lin_interp(_pan, 1.0 - PANAMP, 1.0 + PANAMP);
  //left & right midDistance
  float leftmdm; //left mid distance in meter
  float rightmdm; //right mid distance in meter
  leftmdm = MIDSOURCEDISTANCE - EARSDISTANCE * (0.5 - _pan);
  rightmdm = MIDSOURCEDISTANCE + EARSDISTANCE * (0.5 - _pan);

  _leftMidDistance = (int)(_sampleRate * leftmdm / SOUNDSPEED);
  _rightMidDistance = (int)(_sampleRate * rightmdm / SOUNDSPEED);

  //depthAmp
  _depthAmp =
    _sampleRate * (MAXDEPTH * _depth) /SOUNDSPEED;
  //filter coef
  _filterCoef1 = 1 - COEFFILTER;
  _filterCoef2 = COEFFILTER;
}
/**
 * Calculate the magnitude of force due to air resistance (wind)
 */
static ppogl::Vec3d
calc_wind_force(const ppogl::Vec3d& player_vel)
{
    float re;         // Reynolds number
    float df_mag;     // magnitude of drag force
    float drag_coeff; // drag coefficient
    int table_size;   // size of drag coeff table

    static float last_time_called = -1;

    ppogl::Vec3d total_vel = -1*player_vel;
    
    if ( GameMgr::getInstance().getCurrentRace().windy ) {
		// adjust wind_scale with a random walk
		if ( last_time_called != GameMgr::getInstance().time ) {
			wind_scale = wind_scale + 
				(rand()/double(RAND_MAX)-0.50) * 0.15;
				wind_scale = MIN( 1.0, MAX( 0.0, wind_scale ) );
		}

		total_vel = total_vel+(wind_scale*wind_vel);
    }

    float wind_speed = total_vel.normalize();

    re = AIR_DENSITY * wind_speed * TUX_DIAMETER / AIR_VISCOSITY;

    table_size = sizeof(air_log_drag_coeff) / sizeof(air_log_drag_coeff[0]);

    drag_coeff = pow( 10.0, 
		      lin_interp( air_log_re, air_log_drag_coeff, 
				  log10(re), table_size ) );

    df_mag = 0.5 * drag_coeff * AIR_DENSITY * ( wind_speed * wind_speed )
	* ( M_PI * ( TUX_DIAMETER * TUX_DIAMETER ) * 0.25 );

    PP_ENSURE( df_mag > 0, "Negative wind force" );

    last_time_called = GameMgr::getInstance().time;

    return df_mag*total_vel;
}
int get_disp_crv(int N, double* alphas, double* betas, double* rhos, double* ds, double* phase_vels, double* freqs, int nfreqs, double C_min, double C_def_step, double C_accuracy, int NQUAD, int verbose)
{
	/* Evaluates the dispersion function for a material with N layers
	 * of P velocities alpha, S velocities beta, densities rho and thicknesses d.
	 * The 'continental model' in figure 10 of Schwab and Knopoff 1972 is implemented.
	 * Only the code in Figure 11 is used in addition to a quadratic root finding algorithm.
	 *
	 * alphas: array of size N with P velocities
	 * betas: array of size N with S velocities
	 * rhos: array of size N with densitities
	 * ds: array of size N-1 with layer thicknesses
	 * phase_vels: array of size 'nfreqs' to be populated with the solution dispersion curve
	 * freqs: array of size nfreqs with the frequencies in Hz
	 * nfreqs: number of frequencies
	 * C_min: minimum C to start searching at each frequency
	 * C_def_step: The increment added to C_min in the outer loop when still trying to find bracket. When too large, sometimes error 3 is obtained (robustness needs to be improved)
	 * C_accuracy: If the bracket size around the root becomes smaller than this, then accept we are close enough
	 * NQUAD: number of quadratic interpolation steps within the inner loop used to find the root in the bracket
	 * verbose: Flag used for toggling output
	 */
	double freq, omega;
	double *arr1, *arr2, *arr3;
	double *bot_scales, *top_scales, *mid_scales;
	double bot_val, top_val, mid_val;
	double bot_val_sc, mid_val_sc, top_val_sc;
	double bot_C, top_C, mid_C, next_mid_C;
	double relscale_mid, relscale_top;
	double B0, B1, B2; //quadratic form constants E, p95. Not using E to avoid confusion with exponent notation
	double D, quadroot1, quadroot2;
	double denom_0, denom_1, denom_2;
	double num_eps, C_step;
	int ifreq, iquad, MM;
	int restart_nr_this_freq;
	//allocate arrays
	arr1 =(double *) malloc((N-1)*sizeof(double));
	arr2 =(double *) malloc((N-1)*sizeof(double));
	arr3 =(double *) malloc((N-1)*sizeof(double));

	bot_scales = arr1;
	top_scales = arr2;
	mid_scales = arr3;

	num_eps = 1.0e-12;
	C_def_step = C_def_step + 1.0e-10; //page 133
	for(ifreq=0;ifreq<nfreqs;ifreq++) { //loop over frequencies
		freq  = freqs[ifreq];
		omega = 2*PI*freq;
		restart_nr_this_freq = 0;
		C_step = C_def_step;
		if(verbose) printf("Starting loop for frequency %e Hz\n\n", freq);

		//Find root for frequency.
		//Start with C_min
		bot_C   = C_min;
		bot_val = eval_rayleigh_disp_fun(N, alphas, betas, rhos, ds, bot_scales, omega, bot_C);

		//Loop over phase velocities
		top_C = bot_C; //intialize
		while(1){
			top_C   = bot_C + C_step;

			if (top_C > 0.999*betas[N-1]){//a attempted C larger than bottom Vs will result in Nan. Should never get above there
				top_C = 0.999*betas[N-1];
				if(bot_C == top_C){ //Apparently we also had this problem in the last iteration. Will not be able to advance
					if (restart_nr_this_freq == 4){
						printf("ERROR: Cannot find root below Vs of bottom layer\n");
						printf("Empirically, this seems to sometimes be resolvable by using smaller c_def_step\n");
						printf("The forward model is sometimes numerically poorly behaved in current implementation.\n");
						return(3);
					}
					else{ //try again for this frequency, use shorter step size
						restart_nr_this_freq = restart_nr_this_freq + 1; //increment and try again
						C_step  = C_step/5.0; //quite a lot of steps after 4 failed attempts. But less annoying than starting inversion over again

						printf("REDUCING STEP SIZE TO %e \n", C_step);
						bot_C   = C_min;
						bot_val = eval_rayleigh_disp_fun(N, alphas, betas, rhos, ds, bot_scales, omega, bot_C);
						top_C   = bot_C + C_step;
					}
				}
			}


			top_val = eval_rayleigh_disp_fun(N, alphas, betas, rhos, ds, top_scales, omega, top_C);

			if(verbose){
				printf("----------------------------------------------------\n");
				printf("Starting outer loop with bot_C %e and top_C %e\n", bot_C, top_C);
				printf("bot_val = %e and top_val = %e\n", bot_val, top_val);
				printf("----------------------------------------------------\n");
			}

			if (top_val == 0){ //if exactly on root. Hard to imagine...
				phase_vels[ifreq] = top_C;
				break;
			}

			//See if bot and top have different sign, then we know a root (zero) must be in between.
			if (bot_val*top_val < 0){
				//We found the bracket. Now do quadratic search
				mid_C   = 0.5*(top_C + bot_C); //Start with just halving the bracket
				mid_val = eval_rayleigh_disp_fun(N, alphas, betas, rhos, ds, mid_scales, omega, mid_C);

				//use bot, top and mid to find new C. Do NQUAD quadratic search steps
				for(iquad=0; iquad<NQUAD; iquad++){
					//take care of difference in scaling values
					//normalize scaling towards bot scales (arbitrary choice)
					//I'm currently scaling in every loop. Not most efficient.

					if(verbose){
						printf("Starting quadratic loop %i: \n", iquad);
						printf("bot_C = %e, mid_C = %e, top_C = %e\n",bot_C, mid_C, top_C);
						printf("bot_val = %e, mid_val = %e, top_val = %e\n\n",bot_val, mid_val, top_val);
					}

					if(sqrt(mid_val*mid_val) < num_eps){ //We are very close to 0. Sometimes rounding errors will cause crashes if we continue. Just accept this solution
						if(verbose) printf("Close enough to root. Stop searching.\n");
						break;
					}
					else if (top_C - bot_C < C_accuracy){ //if the bracket becomes small enough, we can also decide to stop
						if(verbose) printf("Desired accuracy is met. Stop searching.\n");
						break;
					}

					//init
					relscale_mid = 1;
					relscale_top = 1;
					for(MM=0; MM<N-1;MM++){
						relscale_mid = relscale_mid*mid_scales[MM]/bot_scales[MM];
						relscale_top = relscale_top*top_scales[MM]/bot_scales[MM];
					}

					bot_val_sc = bot_val;
					mid_val_sc = mid_val*relscale_mid;
					top_val_sc = top_val*relscale_top;

					//convenience
					denom_0 = (bot_C-mid_C)*(bot_C-top_C);
					denom_1 = (mid_C-bot_C)*(mid_C-top_C);
					denom_2 = (top_C-bot_C)*(top_C-mid_C);

					//the quadratic constants B0, B1, B2
					B0      =  ( bot_val_sc*mid_C*top_C/denom_0
							    +mid_val_sc*bot_C*top_C/denom_1
							    +top_val_sc*bot_C*mid_C/denom_2);

					B1      = -( bot_val_sc*(mid_C+top_C)/denom_0
							    +mid_val_sc*(bot_C+top_C)/denom_1
								+top_val_sc*(bot_C+mid_C)/denom_2);

					B2      = bot_val_sc/denom_0 + mid_val_sc/denom_1 + top_val_sc/denom_2;

					//Quadratic representation: F = B0 + B1*C + B2*C**2
					//Find root
					D = B1*B1-4e0*B2*B0; //determinant
					if(D<0){ //No roots, should not be possible with our brackets
						printf("ERROR: Determinant negative. Should not be possible.\n");
						return(1); //error
					}

					//Otherwise the roots are (-B1+-sqrt(D))/2B2
					quadroot1 = (-B1-sqrt(D))/(2*B2);
					quadroot2 = (-B1+sqrt(D))/(2*B2);

					//select the one within the bracket (should only be one)
					if(quadroot1 >= bot_C && quadroot1 <= top_C){       //we want root 1
						next_mid_C = quadroot1;
					}
					else if(quadroot2 >= bot_C && quadroot2 <= top_C) { //we want root 2
						next_mid_C = quadroot2;
					}
					else{

						//It appears we sometimes end up here when we are close to a solution
						//and some rounding errors bring us here
						//instead of throwing an error and exiting it may be pragmatic to look at
						//bot_val, mid_val and top_val together.
						//If bot_val and mid_val have different sign, then pick next_mid_C in between
						//bot_C and mid_C based on linear interpolation
						//Otherwise pick between mid_C and top_C

						if (bot_val*mid_val < 0){ //root should be in between
							next_mid_C = lin_interp(bot_C, mid_C, bot_val, mid_val);
						}
						else if (mid_val*top_val < 0){
							next_mid_C = lin_interp(mid_C, top_C, mid_val, top_val);
						}
						else{
							//We are not supposed to end up here. Just leaving it to catch any error in code
							printf("ERROR: Root condition statement gives unexpected result. Terminating.\n");
							return(2);
						}
					}

					//See how the next mid C compares with old mid C
					//This way we can see what our next bot and top val will be

					//first test if this side of mid_C should contain the 0.
					//quadratic interpolation sometimes gives unstable results when
					//two of the three points are very close together.
					//Do sanity check first

					if(next_mid_C == mid_C){ //if exactly the same, then mid_C must have been root
						break;
					}
					else if (next_mid_C < mid_C){
						if (bot_val*mid_val > 0){ //if same sign, then next_mid_C is in wrong bracket somehow. Should not have ended up here
							//do linear interpolation in upper bracket
							next_mid_C = lin_interp(mid_C, top_C, mid_val, top_val);
						}
					}
					else if (next_mid_C > mid_C){
						if (top_val*mid_val > 0){ //if same sign, then next_mid_C is in wrong bracket somehow. Should not have ended up here
							//do linear interpolation in lower bracket
							next_mid_C = lin_interp(bot_C, mid_C, bot_val, mid_val);
						}
					}


					else if(next_mid_C < mid_C){ //old mid C becomes top
						top_C      = mid_C;
						top_val    = mid_val;
						top_scales = mid_scales;
					}
					else if(next_mid_C > mid_C){ //old mid C becomes bot
						bot_C      = mid_C;
						bot_val    = mid_val;
						bot_scales = mid_scales;
					}

					//populate mid with the new mid
					mid_C = next_mid_C;

					if(iquad<NQUAD-1){//If another iteration will take place, calculate mid_val and mid_scales as well
						mid_val = eval_rayleigh_disp_fun(N, alphas, betas, rhos, ds, mid_scales, omega, mid_C);
					}

				}
				//Done searching for root, accept mid_C as being close enough.
				//mid_C is the last quadratic interpolation step
				phase_vels[ifreq] = mid_C;
				if(verbose){
					printf("For omega %e, phase velocity %e is selected \n", omega, phase_vels[ifreq]);
				}

				break; //Stop loop over C, we are done for this frequency
			}
			else{ //if same sign, increase with C_def_step again until we find a bracket. Prepare for next iteration
				bot_C      = top_C;
				bot_val    = top_val;
				bot_scales = top_scales;
			}


		}
	}


	//FREE ARRAYS
	free(arr1);
	free(arr2);
	free(arr3);

	return(0);
}
Exemple #5
0
Fluxrec *do_corr(Fluxrec *flux1, Fluxrec *flux2, int size, int *corsize,
		 int nbad)
{
  int no_error=1;         /* Flag set to 0 on error */
  int nx;                 /* Size of gridded arrays */
  float xmin,xmax;        /* Min and max day numbers */
  float dx;               /* Grid step-size between days */
  float test;             /* Tests size to see if it's a power of 2 */
  float *zpad1=NULL;      /* Zero padded light curve */
  float *zpad2=NULL;      /* Zero padded light curve */
  Fluxrec *grflux1=NULL;  /* Gridded version of flux1 */
  Fluxrec *grflux2=NULL;  /* Gridded version of flux2 */
  Fluxrec *correl=NULL;   /* Cross-correlation of flux1 and flux2 */

  /*
   * Note that the day part of the flux array will be sorted by 
   *  construction, so the min and max values will be easy to find.
   */

  xmin = flux1->day;
  xmax = (flux1+size-1)->day;

  /*
   * Check if size is a power of 2 because the number of points in the
   *  curve MUST be a power of two if the cross-correlation function
   *  is cross_corr_fft or cross_corr_nr.
   */

  test = log((float)size)/log(2.0);

  /*
   * If it is or if CORRFUNC == 3 , then set the values for nx and dx, 
   *  as simple functions of size, xmin, and xmax, and then zero
   *  pad the input data
   */

  if(test-(int)test == 0) {
    nx = size;
    dx = (xmax-xmin)/(nx-1);

    if(!(zpad1 = zero_pad(flux1,nx)))
      no_error = 0;
    if(!(zpad2 = zero_pad(flux2,nx)))
      no_error = 0;
  }    


  /*
   * If size is not a power of 2 and CORRFUNC != 3, interpolate the data onto 
   *  an appropriately spaced grid with a size that is a power of 2.
   */

  else {

    /*
     * Compute new values for nx and dx
     */

    nx = pow(2.0f,floor((log((double)size)/log(2.0)+0.5)));
    dx = (xmax-xmin)/(nx-1);
    printf("do_corr: Using grid of %d points for cross-correlation.\n",nx);
    if(!(grflux1 = lin_interp(flux1,size,nx,dx,nbad)))
      no_error = 0;
      
    if(no_error)
      if(!(grflux2 = lin_interp(flux2,size,nx,dx,nbad)))
	no_error = 0;
      
    /*
     * Zero-pad the gridded data
     */
      
    if(no_error)
      if(!(zpad1 = zero_pad(grflux1,nx)))
	no_error = 0;
      
    if(no_error)
      if(!(zpad2 = zero_pad(grflux2,nx)))
	no_error = 0;
  }

  /*
   * Do the cross-correlation, via one of three styles:
   *  1. FFT method (Numerical Recipes FFTs, then mulitply and transform back
   *  2. Numerical Recipes correl function
   *  3. Time domain method with no FFTs
   */

  if(no_error) {
    nx *= ZEROFAC;
    switch(CORRFUNC) {
    case 1:
      if(!(correl = cross_corr_fft(zpad1,zpad2,nx,dx)))
	no_error = 0;
      break;
    case 2:
      if(!(correl = cross_corr_nr(zpad1,zpad2,nx,dx)))
	no_error = 0;
      break;
    default:
      fprintf(stderr,"ERROR: do_corr.  Bad choice of correlation function\n");
      no_error = 0;
    }
  }

  /*
   * Clean up
   */

  zpad1 = del_array(zpad1);
  zpad2 = del_array(zpad2);
  grflux1 = del_fluxrec(grflux1);
  grflux2 = del_fluxrec(grflux2);

  if(no_error) {
    *corsize = nx;
    return correl;
  }
  else {
    *corsize = 0;
    return NULL;
    fprintf(stderr,"ERROR: do_corr\n");
  }
}