Beispiel #1
0
void pre_emphasis(fract32 data[], int arr_length)
{
	fract32 xBuffer[BUFFER_SIZE] = {0};
	// input buffer
	fract32 yBuffer[BUFFER_SIZE] = {0};
	// output buffer

	int current = 0;

	int index;

	for (index = 0; index < arr_length; index++) {
		fract32 temp_b0 = mult_fr1x32x32(shelving_coef.b0, data[index]);
		fract32 temp_b1 = mult_fr1x32x32(shelving_coef.b1, xBuffer[INDEX(current-1)]);
		fract32 temp_b2 = mult_fr1x32x32(shelving_coef.b2, xBuffer[INDEX(current-2)]);
		fract32 temp_a1 = mult_fr1x32x32(shelving_coef.a1, yBuffer[INDEX(current-1)]);
		fract32 temp_a2 = mult_fr1x32x32(shelving_coef.a2, yBuffer[INDEX(current-2)]);

		fract32 temp_b = add_fr1x32(add_fr1x32(temp_b0, temp_b1), temp_b2);
		fract32 temp_a = add_fr1x32(temp_a1, temp_a2);
		fract32 temp = sub_fr1x32(temp_b, temp_a);

		yBuffer[current] = shl_fr1x32(temp, 2);

		xBuffer[current] = data[index];		//input
		data[index] = yBuffer[current];		//output

		current++;
		current %= BUFFER_SIZE;
	}
}
Beispiel #2
0
// interpolated arbitrary mix of old buffer contents with new
void buffer_tap_mix(bufferTap *tap, fract32 val, fract32 preLevel) { 
  static s32 idxB;
  static fract32 a, b;  
  a = mult_fr1x32x32(val, sub_fr1x32(FR32_MAX, tap->idx.fr));
  b = mult_fr1x32x32(val, tap->idx.fr);
  idxB = tap->idx.i + 1;
  while(idxB > tap->loop) { idxB -= tap->loop; }
  // we can assume idxA is already wrapped
  tap->buf->data[tap->idx.i] = add_fr1x32(a, mult_fr1x32x32(tap->buf->data[tap->idx.i], preLevel));
  tap->buf->data[tap->idx.i] = add_fr1x32(b, mult_fr1x32x32(tap->buf->data[idxB], preLevel));
  tap->buf->data[idxB] = b;  
}
Beispiel #3
0
// calculate modulated and bandlimited waveshape
static inline void osc_calc_wm(osc* osc) {
  fract32 sm; // mod shape
  // fract32 sl; // shape limit given current freq


  // add modulation
  sm = add_fr1x32(osc->shape, mult_fr1x32x32(osc->wmIn, osc->wmAmt) );
  
  //- hacky magic formula for pseudo-bandlimiting:
  //- with maximal bandlimiting, want to limit shape to a function of unit freq
  //- max freq = min shape, min freq = max shape
  // :
  // map phase increment to [0,1] fract32

  /* sl = (fract32)(((u32)(osc->inc) - incRange) * shapeLimMul); */
  /* // invert [0,1] to [1,0] */
  /* sl = sub_fr1x32(FR32_MAX, sl); */
  
  /* // limit */
  /* if(sl < sm) { */
  /*   sm = dsp_lerp32(sm, sl, osc->bandLim); */
  /* } */

  // ok, time for serious bullshit!
  sm = sub_fr1x32(sm, 
		  mult_fr1x32x32( (fract32)(fix16_sub(osc->inc, incMin) * shapeLimMul),
				   osc->bandLim 
				  )
		  );
  if(sm < 0) { sm = 0; }
  osc->shapeMod = sm;
}
Beispiel #4
0
// get next filtered value
fract32 filter_ramp_tog_next(filter_ramp_tog* f) {
  // gcc intrinsics are saturating  
  f->y = add_fr1x32(f->y, f->sinc);
  if(f->y < 0) { f->y = 0; }   /// fixme: slow
  f->sync = (f->x == f->y);
  f->sinc = f->sync ? 0 : f->sinc;
  return f->y;

  
}
Beispiel #5
0
void module_process_frame(void) { 
  static fract32 tmpDel, tmpSvf;
  u8 i;

  tmpDel = 0;
  tmpSvf = 0;

  // mix inputs to delay lines
  mix_del_inputs();

  /// TEST

  for(i=0; i<NLINES; i++) {
    // process fade integrator
    //    lines[i].fadeWr = filter_ramp_tog_next(&(lpFadeWr[i]));
    lines[i].fadeRd = filter_ramp_tog_next(&(lpFadeRd[i]));

    // process delay line
    tmpDel = delayFadeN_next( &(lines[i]), in_del[i]);	    
    // process filters
    // check integrators for filter params
    if( !(svfCutSlew[i].sync) ) {
      filter_svf_set_coeff( &(svf[i]), filter_1p_lo_next(&(svfCutSlew[i])) );
    }
    if( !(svfRqSlew[i].sync) ) {
      filter_svf_set_rq( &(svf[i]), filter_1p_lo_next(&(svfRqSlew[i])) );
    }
    tmpSvf = filter_svf_next( &(svf[i]), tmpDel);  
    // mix
    tmpDel = mult_fr1x32x32( tmpDel, mix_fdry[i] );
    tmpDel = add_fr1x32(tmpDel, mult_fr1x32x32(tmpSvf, mix_fwet[i]) );

    out_del[i] = tmpDel;

  } // end lines loop 

  // mix outputs to DACs
  /// TEST
  /* out[0] = in[0]; */
  /* out[1] = in[1]; */
  /* out[2] = in[2]; */
  /* out[3] = in[3]; */
  out[0] = out[1] = out[2] = out[3] = 0x00000000;
  mix_outputs();

  /// do CV output
  if( cvSlew[cvChan].sync ) { ;; } else { 
    cvVal[cvChan] = filter_1p_lo_next(&(cvSlew[cvChan]));
    dac_update(cvChan, cvVal[cvChan]);
  }
 
  if(++cvChan == 4) {
    cvChan = 0;
  }
}
Beispiel #6
0
// interpolated read
fract32 buffer_tap_read(bufferTap *tap) {
  static s32 idxB;
  static fract32 a, b;
  idxB = tap->idx.i + 1;
  while(idxB >= tap->loop) { idxB -= tap->loop; }
  // we can assume idxA is already wrapped
  a = tap->buf->data[tap->idx.i];
  b = tap->buf->data[idxB];
  // apply interpolation from fractional index
  return add_fr1x32(a, mult_fr1x32x32(tap->idx.fr, sub_fr1x32(b, a)));
}
Beispiel #7
0
static fract32 filter_svf_calc_frame( filter_svf* f, fract32 in) { 
  //  fract32 out;
  f->low = add_fr1x32(f->low, 
		      mult_fr1x32x32(f->freq, f->band));

  f->high = sub_fr1x32(
		       sub_fr1x32(
				  in, 
				  shl_fr1x32(mult_fr1x32x32(f->rq, f->band), f->rqShift)
				  ),
		       f->low
		       );

  f->band = add_fr1x32(f->band, 
		       mult_fr1x32x32(f->freq, f->high) );

  //  f->notch = add_fr1x32(f->low, f->high);

  //  return out;
  return *(f->mode);
}
Beispiel #8
0
// add 32.32 value with overflow/underflow checking
void add_fix32(fix32* a, fix32* b) {
  // tmp fract
  fract32 tfr = a->fr;
  // tmp int
  s32 ti = a->i + b->i;
 
  /// FIXME: could be arch-specific inline ASM here for better speed
  /// (e.g. add fract32, check overflow flag ?)
  if(tfr >= 0) {
    if( sub_fr1x32(FRACT32_MAX,tfr) < b->fr) {
      // wrap by subtraction
      tfr = sub_fr1x32(
			 add_fr1x32(
				    sub_fr1x32(tfr, FR32_MAX),
				    b->fr),
			 FR32_MAX);
      ti += 1; // carry
    }
  } else {
    if(b->fr < sub_fr1x32(FRACT32_MAX,tfr)) {
      // wrap by addition
      tfr = add_fr1x32(
			 add_fr1x32(
				    add_fr1x32(tfr, FR32_MAX),
				    b->fr),
			 FR32_MAX);
      ti -= 1; // carry (negative)

    }
  }
  // yet another comparison and carry for negative fr
  if(tfr < 0) {
    a->fr = add_fr1x32(FR32_MAX, tfr);
    a->i = ti -1;
  } else {
    a->fr = tfr;
    a->i = ti;
  }
}
Beispiel #9
0
static inline void mix_adc (void) {
  /// can't handle the mix! use pointers for patch points right now
  int i, j;
  volatile fract32** pout = &(patch_adc_dac[0][0]);
  fract32* pin = in;
  for(i=0; i < 4; i++) {    
    for(j=0; j < 4; j++) {
      **pout = add_fr1x32(**pout, *pin);
      pout++;
    }
    pin++;
  }
}
Beispiel #10
0
// get next filtered value
fract32 filter_ramp_next(filter_ramp* f) {
  /// FIXME: conditionals suck
  if( !(f->sync) ) {
    f->y = add_fr1x32(f->x, f->sinc);  
    if( f->dec ) {
      if (f->y < f->x) {
	f->y = f->x;
      }
    } else {
      if (f->y > f->x) {
	f->y = f->x;
      }
    }
  }
  return f->y;
}
Beispiel #11
0
float calc_energy(fract32 data[], int arr_length)
{
	int shift = 9;
	// shift = log_2(arr_length)

	fract32 energy_fr = float_to_fr32(0.0);

	int index;
	for (index = 0; index < arr_length; index++) {
		fract32 temp = mult_fr1x32x32(data[index], data[index]);
		temp = shl_fr1x32(temp, -shift);
		// right shift in case of overflow
		energy_fr = add_fr1x32(energy_fr, temp);
	}

	float energy = fr32_to_float(energy_fr) * (1<<shift);

	return energy;
}
Beispiel #12
0
// read
fract32 buffer_tapN_read(bufferTapN *tap) {
  fract32 a, b;
  fix16 tmp;

#if 1
  if(tap->divCount == 0) {
    return tap->buf->data[tap->idx];
  } else { // interpolate during phase-division
    a = tap->buf->data[tap->idx];
    if( (tap->idx + 1) >= tap->loop) {
      b = tap->buf->data[0];
    } else {
      b = tap->buf->data[ tap->idx + 1 ];
    }
    tmp = FRACT_FIX16( sub_fr1x32(b, a) );
    tmp = fix16_mul(tmp, fix16_from_int(tap->divCount));
    return add_fr1x32(a, FIX16_FRACT_TRUNC(tmp));
  }
#else
    return tap->buf->data[tap->idx];
#endif
}
Beispiel #13
0
// frame calculation
static void calc_frame(void) {
#if 1
  u8 i;
  wavesVoice* v;

  for(i=0; i<WAVES_NVOICES; i++) {
    v = &(voice[i]);
    // oscillator class includes hz and mod integrators
    v->oscOut = shr_fr1x32( osc_next( &(v->osc) ), 2);
    // phase mod with fixed 1-frame delay
    osc_pm_in( &(v->osc), v->pmIn );
    // shape mod with fixed 1-frame delay
    osc_wm_in( &(v->osc), v->wmIn );
    // process filter integrators and set 
    filter_svf_set_coeff( &(v->svf), filter_1p_lo_next( &(v->cutSlew) ) );
    filter_svf_set_rq( &(v->svf), filter_1p_lo_next( &(v->rqSlew) ) );
    // process filter
    v->svfOut = filter_svf_next( &(v->svf), shr_fr1x32(v->oscOut, 1) );
    // process amp smoother
    v->amp  = filter_1p_lo_next( &(v->ampSlew) );
    // mix to output bus
    v->out = mult_fr1x32x32(v->amp,
			    add_fr1x32(mult_fr1x32x32( v->oscOut, v->fDry),
				       mult_fr1x32x32( v->svfOut, v->fWet)
				       )
			    );
  } // end voice loop

  /// FIXME: later, more voices, mod matrix, arbitrary mod delay.
  /// for now, simple direct mod feedback routing and 1-frame delay.
  voice[0].pmIn = voice[1].oscOut;
  //  voice[0].wmIn = voice[1].oscOut << 1;
  voice[1].pmIn = voice[0].oscOut;
  //  voice[1].wmIn = voice[0].oscOut << 1;
  
  // mix outputs using matrix
    mix_outputs();
  
  

#else
  /* //  fract32 out1, out0; */
 
  /* // osc output */
  /* oscOut1 = shr_fr1x32(osc_next( &(osc1) ), 2); */
  /* oscOut0 = shr_fr1x32(osc_next( &(osc0) ), 2); */

  /* // phase mod feedback with 1frame delay */
  /* osc_pm_in( &osc1, oscOut0 ); */
  /* osc_pm_in( &osc0, oscOut1 ); */
  /* // shape mod feedback with 1frame delay */
  /* osc_wm_in( &osc1, oscOut0 ); */
  /* osc_wm_in( &osc0, oscOut1 ); */

  /* /////////// */
  /* /////////// */
  /* // apply filters */

  /* if( !(svfCutSlew[i].sync) ) { */
  /*   filter_svf_set_coeff( &(svf[i]), filter_1p_lo_next(&(svfCutSlew[i])) ); */
  /* } */
  /* if( !(svfRqSlew[i].sync) ) { */
  /*   filter_svf_set_rq( &(svf[i]), filter_1p_lo_next(&(svfRqSlew[i])) ); */
  /* } */

  /* //  svfOut1 = shl_fr1x32(filter_svf_next( &(svf1), shr_fr1x32(oscOut1, 1)), 1); */
  /* //  svfOut2 = shl_fr1x32(filter_svf_next( &(svf2), shr_fr1x32(oscOut2, 1)), 1); */
  /* svfOut1 = filter_svf_next( &(svf1), shr_fr1x32(oscOut1, 1)); */
  /* svfOut0 = filter_svf_next( &(svf0), shr_fr1x32(oscOut0, 1)); */

  /* ///////// */
  /* ///////// */

  /* // amp smoothers */
  /* oscAmp1 = filter_1p_lo_next(amp1Lp); */
  /* oscAmp0 = filter_1p_lo_next(amp0Lp); */

  /* // apply osc amplitudes and sum  */
  /* oscOut1 = mult_fr1x32x32(oscAmp1, */
  /* 			add_fr1x32(mult_fr1x32x32( oscOut1, fdry1), */
  /* 				   mult_fr1x32x32( svfOut1, fwet1) */
  /* 				   )); */
  
  /* oscOut0 = mult_fr1x32x32(oscAmp0, */
  /* 			add_fr1x32(mult_fr1x32x32( oscOut0, fdry0), */
  /* 				   mult_fr1x32x32( svfOut0, fwet0) */
  /* 				   )); */

  /* //// */
  /* /// fixme: mono */
  /* frameVal = add_fr1x32( oscOut0, oscOut1); */

  /* // mix to output */
  /* //...todo */
  #endif
}
Beispiel #14
0
static void mix_outputs(void) {
  fract32 mul;
  //fract32 oscs;
  
  //-- out 0
  out[0] = 0;
  // osc
  mul = mix_osc_dac[0][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(voice[0].out, mul)); 
  mul = mix_osc_dac[1][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(voice[1].out, mul)); 
  // adc
  mul = mix_adc_dac[0][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(in[0], mul)); 
  mul = mix_adc_dac[1][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(in[1], mul)); 
  mul = mix_adc_dac[2][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(in[2], mul));
  mul = mix_adc_dac[3][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(in[3], mul));

  //-- out 1
  out[1] = 0;
  // osc
  mul = mix_osc_dac[0][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(voice[0].out, mul)); 
  mul = mix_osc_dac[1][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(voice[1].out, mul)); 
  // adc
  mul = mix_adc_dac[0][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(in[0], mul)); 
  mul = mix_adc_dac[1][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(in[1], mul)); 
  mul = mix_adc_dac[2][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(in[2], mul));
  mul = mix_adc_dac[3][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(in[3], mul));


  //////////////////
  /// TEST: skip outs 3+4, see where we run out of CPU...
  out[2] = out[0];
  out[3] = out[1];
  return;
  /////////////
  ////////////
  
  //-- out 2
  out[2] = 0;
  // osc
  mul = mix_osc_dac[0][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(voice[0].out, mul)); 
  mul = mix_osc_dac[1][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(voice[1].out, mul)); 
  // adc
  mul = mix_adc_dac[0][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(in[0], mul)); 
  mul = mix_adc_dac[1][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(in[1], mul)); 
  mul = mix_adc_dac[2][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(in[2], mul)); 
  mul = mix_adc_dac[3][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(in[3], mul)); 

  //-- out 3
  out[3] = 0;
  // osc
  mul = mix_osc_dac[0][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(voice[0].out, mul)); 
  mul = mix_osc_dac[1][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(voice[1].out, mul)); 
  // adc
  mul = mix_adc_dac[0][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(in[0], mul)); 
  mul = mix_adc_dac[1][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(in[1], mul)); 
  mul = mix_adc_dac[2][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(in[2], mul)); 
  mul = mix_adc_dac[3][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(in[3], mul));

}
Beispiel #15
0
// mix delay inputs
static void mix_del_inputs(void) {
  //  u8 i, j;
  //  fract32* pIn;
  fract32 mul;
  
  //--- del 0
  in_del[0] = 0;

  //adc->del
  mul = mix_adc_del[0][0];
  in_del[0] = add_fr1x32(in_del[0], mult_fr1x32x32(in[0], mul)); 
  mul = mix_adc_del[1][0];
  in_del[0] = add_fr1x32(in_del[0], mult_fr1x32x32(in[1], mul)); 
  mul = mix_adc_del[2][0];
  in_del[0] = add_fr1x32(in_del[0], mult_fr1x32x32(in[2], mul)); 
  mul = mix_adc_del[3][0];
  in_del[0] = add_fr1x32(in_del[0], mult_fr1x32x32(in[3], mul)); 

  // del->del
  mul = mix_del_del[0][0];
  in_del[0] = add_fr1x32(in_del[0], mult_fr1x32x32(out_del[0], mul)); 
  mul = mix_del_del[1][0];
  in_del[0] = add_fr1x32(in_del[0], mult_fr1x32x32(out_del[1], mul)); 

  //--- del 1
  in_del[1] = 0;
  // adc
  mul = mix_adc_del[0][1];
  in_del[1] = add_fr1x32(in_del[1], mult_fr1x32x32(in[0], mul)); 
  mul = mix_adc_del[1][1];
  in_del[1] = add_fr1x32(in_del[1], mult_fr1x32x32(in[1], mul)); 
  mul = mix_adc_del[2][1];
  in_del[1] = add_fr1x32(in_del[1], mult_fr1x32x32(in[2], mul)); 
  mul = mix_adc_del[3][1];
  in_del[1] = add_fr1x32(in_del[1], mult_fr1x32x32(in[3], mul)); 
  // del 
  mul = mix_del_del[0][1];
  in_del[1] = add_fr1x32(in_del[1], mult_fr1x32x32(out_del[0], mul)); 
  mul = mix_del_del[1][1];
  in_del[1] = add_fr1x32(in_del[1], mult_fr1x32x32(out_del[1], mul));
}
Beispiel #16
0
static void mix_outputs(void) {
  fract32 mul;
  
  //-- out 0
  out[0] = 0;
  // del
  mul = mix_del_dac[0][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(out_del[0], mul)); 
  mul = mix_del_dac[1][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(out_del[1], mul)); 
  // adc
  mul = mix_adc_dac[0][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(in[0], mul)); 
  mul = mix_adc_dac[1][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(in[1], mul)); 
  mul = mix_adc_dac[2][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(in[2], mul)); 
  mul = mix_adc_dac[3][0];
  out[0] = add_fr1x32(out[0], mult_fr1x32x32(in[3], mul)); 

  //-- out 1
  out[1] = 0;
  // del
  mul = mix_del_dac[0][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(out_del[0], mul)); 
  mul = mix_del_dac[1][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(out_del[1], mul)); 
  // adc
  mul = mix_adc_dac[0][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(in[0], mul)); 
  mul = mix_adc_dac[1][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(in[1], mul)); 
  mul = mix_adc_dac[2][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(in[2], mul)); 
  mul = mix_adc_dac[3][1];
  out[1] = add_fr1x32(out[1], mult_fr1x32x32(in[3], mul)); 

  //-- out 2
  out[2] = 0;
  // del
  mul = mix_del_dac[0][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(out_del[0], mul)); 
  mul = mix_del_dac[1][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(out_del[1], mul)); 
  // adc
  mul = mix_adc_dac[0][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(in[0], mul)); 
  mul = mix_adc_dac[1][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(in[1], mul)); 
  mul = mix_adc_dac[2][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(in[2], mul)); 
  mul = mix_adc_dac[3][2];
  out[2] = add_fr1x32(out[2], mult_fr1x32x32(in[3], mul)); 

  //-- out 3
  out[3] = 0;
  // del
  mul = mix_del_dac[0][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(out_del[0], mul)); 
  mul = mix_del_dac[1][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(out_del[1], mul)); 
  // adc
  mul = mix_adc_dac[0][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(in[0], mul)); 
  mul = mix_adc_dac[1][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(in[1], mul)); 
  mul = mix_adc_dac[2][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(in[2], mul)); 
  mul = mix_adc_dac[3][3];
  out[3] = add_fr1x32(out[3], mult_fr1x32x32(in[3], mul));

}
Beispiel #17
0
// interpolated addition of input to buffer contents
void buffer_tapN_add(bufferTapN *tap, fract32 val) { 
    tap->buf->data[tap->idx] = add_fr1x32(  tap->buf->data[tap->idx], val );
}
Beispiel #18
0
//  arbitrary mix of old buffer contents with new
void buffer_tapN_mix(bufferTapN *tap, fract32 val, fract32 preLevel) { 
  tap->buf->data[tap->idx] = 
    add_fr1x32(  mult_fr1x32x32(tap->buf->data[tap->idx], preLevel), val );
}
Beispiel #19
0
// get next value (with input)
extern fract32 filter_svf_next( filter_svf* f, fract32 in) {
  // process 2x and average
  fract32 out = shr_fr1x32(filter_svf_calc_frame(f, in), 1);
  out = add_fr1x32(out, shr_fr1x32(filter_svf_calc_frame(f, in), 1));
  return out;
}
Beispiel #20
0
// frame calculation
static void calc_frame(void) {
  int i;
  wavesVoice* v = voice;
  fract32* vout = voiceOut;

  for(i=0; i<WAVES_NVOICES; i++) {

    //    v = &(voice[i]);
    // oscillator class includes hz and mod integrators
    v->oscOut = shr_fr1x32( osc_next( &(v->osc) ), 2);

    // /set modulation - FIXME this is redundant...
    osc_pm_in( &(v->osc), v->pmIn );
    osc_wm_in( &(v->osc), v->wmIn );

    // set filter params
    slew32_calc(v->cutSlew);
    slew32_calc(v->rqSlew);
    filter_svf_set_coeff( &(v->svf), v->cutSlew.y );
    filter_svf_set_rq( &(v->svf), v->rqSlew.y );

    // process filter
    v->svfOut = filter_svf_next( &(v->svf), shr_fr1x32(v->oscOut, 1) );

    // process amp/mix smoothing
    slew32_calc(v->ampSlew);
    slew16_calc(v->drySlew);
    slew16_calc(v->wetSlew);

    // mix dry/filter and apply amp
    *vout = mult_fr1x32x32(
				 v->ampSlew.y,
				 add_fr1x32(
					    mult_fr1x32( 
							trunc_fr1x32(v->oscOut), 
							v->drySlew.y
							 ),
					    mult_fr1x32( 
							trunc_fr1x32(v->svfOut), 
							v->wetSlew.y
							 )
					    )
				 );

    
    // advance phase del indices
    v->pmDelWrIdx = (v->pmDelWrIdx + 1) & WAVES_PM_DEL_SAMPS_1;
    v->pmDelRdIdx = (v->pmDelRdIdx + 1) & WAVES_PM_DEL_SAMPS_1;
    // set pm input from delay
    v->pmIn = v->pmDelBuf[v->pmDelRdIdx];    
    // no tricky modulation routing here!
    v->wmIn = v->pmDelBuf[v->pmDelRdIdx];    
    // advance pointers
    vout++;
    v++;
  } // end voice loop

  // // simple cross-patch modulation
  // add delay, before filter
  voice[0].pmDelBuf[voice[0].pmDelWrIdx] = voice[1].oscOut;
  voice[1].pmDelBuf[voice[1].pmDelWrIdx] = voice[0].oscOut;
  /* voice[0].pmIn = voice[1].oscOut; */
  /* voice[1].pmIn = voice[0].oscOut; */

  // zero the outputs
  out[0] = out[1] = out[2] = out[3] = 0;
  
  // patch filtered oscs outputs
  mix_voice();
  
  // oatch adc
  mix_adc();
}
Beispiel #21
0
// frame calculation
static void calc_frame(void) {
    // ----- smoothers:
    // amp
    amp = filter_1p_fix16_next(ampLp);
    // time
    if(timeLp->sync) {
        ;;
    } else {
        time = filter_1p_fix16_next(timeLp);
        buffer_tap_sync(&tapRd, &tapWr, time);

#if ARCH_LINUX
        if(dbgFlag) {
            fprintf(dbgFile, "%d \t %f \r\n",
                    dbgCount,
                    fix16_to_float(time)
                   );
            dbgCount++;
        }

#endif


    }

    // rate
    //// NOTE: setting a different rate is pretty much pointless in this simple application.
    /// leaving it in just to test fractional interpolation methods.
    if(rateLp->sync) {
        ;;
    } else {
        rate = filter_1p_fix16_next(rateLp);
        buffer_tap_set_rate(&tapRd, rate);
        buffer_tap_set_rate(&tapWr, rate);
    }

    // get interpolated echo value

    echoVal = buffer_tap_read(&tapRd);

    /* // store interpolated input+fb value */
    //  buffer_tap_write(&tapWr, add_fr1x32(in0, mult_fr1x32x32(echoVal, fb ) ) );
    buffer_tap_write(&tapWr, add_fr1x32(in0 >> 1, mult_fr1x32x32(echoVal, fb ) ) );

    //FIXME: clip / saturate input buf here
    //// potentially, scale input by inverse feedback

/// test: no fb
    //buffer_tap_write(&tapWr, in0);

    /* // output */
    frameVal = add_fr1x32(
                   mult_fr1x32x32( echoVal, FIX16_FRACT_TRUNC(amp) ),
                   mult_fr1x32x32( in0,  FIX16_FRACT_TRUNC(dry) )
               );
    //// test: no dry
    //  frameVal = echoVal;
    /// FIXME: clip here

    buffer_tap_next(&tapRd);
    buffer_tap_next(&tapWr);
}