Example #1
0
int main(int ac, char** av)
{
#if 1
    {
        fixed_t fu = float_to_fixed(1.2);
        fixed_t bar = float_to_fixed(2.4);
        fixed_t baz = fixed_add(fu, bar);

        printf("%f + ", fixed_to_float(fu));
        printf("%f = ", fixed_to_float(bar));
        printf("%f\n", fixed_to_float(baz));
    }

    {
        fixed_t fu = float_to_fixed(1.5);
        fixed_t bar = int_to_fixed(2);
        fixed_t baz = fixed_mul(fu, bar);

        printf("%f * ", fixed_to_float(fu));
        printf("%f = ", fixed_to_float(bar));
        printf("%f\n", fixed_to_float(baz));
    }

    {
        fixed_t fu = int_to_fixed(1);
        fixed_t bar = int_to_fixed(2);
        fixed_t baz = fixed_div(fu, bar);

        printf("%f / ", fixed_to_float(fu));
        printf("%f = ", fixed_to_float(bar));
        printf("%f\n", fixed_to_float(baz));
    }

    {
        fixed_t fu = int_to_fixed(-1);
        fixed_t bar = int_to_fixed(2);
        fixed_t baz = fixed_div(fu, bar);

        printf("%f / ", fixed_to_float(fu));
        printf("%f = ", fixed_to_float(bar));
        printf("%f\n", fixed_to_float(baz));
    }
#endif

#if 0
    {
        fixed_t alpha = float_to_fixed(0.0);
        fixed_t step = float_to_fixed(0.01);
        for (; alpha < FIXED_TWO_PI; alpha = fixed_add(alpha, step))
        {
            printf("%f ", fixed_to_float(alpha));
            printf("%f\n", fabsf(sinf(fixed_to_float(alpha)) - fixed_to_float(fixed_sin(alpha))));
        }

    }
#endif

    return 0;
}
void test_fixed_divide(void)
{
  /* Negative */
  a = fixed_make(-2023.621F);
  b = fixed_make(10.0F);
  result = fixed_div(a, b);
  TEST_ASSERT_EQUAL_FLOAT(fixed_make(-202.3621F), result);

  /* Positive */
  a = fixed_make(2023.621F);
  b = fixed_make(10.0F);
  result = fixed_div(a, b);
  TEST_ASSERT_EQUAL_FLOAT(fixed_make(202.3621F), result);
}
Example #3
0
void temp_handler(void) {
    temp_samples[sample++] = make_fixed(raw_temp);

    if (sample == N_SAMPLES) {
        fixed_t t = make_fixed(0);
        for (uint8_t i = 0; i < N_SAMPLES; i++) {
            t = fixed_add(t, temp_samples[i]);
        }

        temp = fixed_round(fixed_div(fixed_div(t, N_SAMPLES), 4));
        set_number(0, temp, relay_on);
        sample = 0;
    }
}
Example #4
0
File: mat.c Project: tuttlem/freak
void mat44_perspective(mat44 *m, fixed fov, fixed aspect, fixed near_z, fixed far_z) {

  fixed _fov = fixed_div(fixed_mul(FIXED_PI, fov), int_to_fixed(180));
  fixed _f = fixed_div(FIXED_ONE, fixed_tan(fixed_mul(_fov, double_to_fixed(0.5))));

  fixed nf = fixed_div((far_z + near_z), (near_z - far_z));
  fixed nfr = fixed_div(fixed_mul(fixed_mul(int_to_fixed(2), far_z), near_z), (near_z - far_z));
  
  mat44_set(m,
            fixed_div(_f, aspect), 0 , 0           , 0  ,
            0                    , _f, 0           , 0  ,
            0                    , 0 , nf          , nfr,
            0                    , 0 , FIXED_NEGONE, 0);
  
}
Example #5
0
void  Scan_Samples(void){
	fixed ybox[7];	// array box car derivative
	s16 bin;						// index into peak height array
	fixed dt, tau, *yp0, *yp1, y, y_i;
	fixed threshold;				// trigger level for leading edge
	fixed deriv;
	fixed alpha, beta, gamma, peak;
	s16 i;
	configurations *cp = &configuration;


	ADC_Stop();
	tail = head = Get_Scan_Pos(); // get current absolute position in adc  buffer
	/*
	if(cp->sig_filter){
		// Set up Butterworth low pass filter
		dt = FIXED_HALF;			// sample time 0.5 uS
		tau = fixed_from_int(cp->sig_filter);  // filter time in uS
		alpha = fixed_div(dt, tau + dt);
	}
	*/
	ADC_Start();
	while(TRUE){
		if(tail == head){
			head = Get_Scan_Pos();
			// recalculate filter elements in case changed
			/*
			if(cp->sig_filter){
				// Set up Butterworth low pass filter in case of changes
				dt = FIXED_HALF;			// sample time 0.5 uS
				tau = fixed_from_int(cp->sig_filter);  // filter time in uS
				alpha = fixed_div(dt, tau + dt);
			}
			*/
		}
		if(tail == head)
			continue;
		// track live time
		if(samp_cntr++ >= SAMP_PER_MS){
			live_time++;
			samp_cntr = 0;
		}
		// get new value, adjust for zero and inversion at same time
		y = fixed_from_int(zero - scan_buffer[tail++]);
		if(tail >= SCAN_BUFFER_SZ){
			tail = 0;
		}
		// filter signal if needed
		/*
		if(cp->sig_filter){
			// Butterworth low pass filter
			y = *yp0 + fixed_mul(alpha, (y - *yp0));
		}
		*/
		// shift the boxcar window and find derivative
		yp0 =&ybox[0];
		yp1 = &ybox[1];
		for(i = 6; i > 0; i--){	// last box slot gets new y value
			*yp0++ = *yp1++;
		}
		*yp0 = y;		// place latest sample in end of boxcar
		// compute the derivative
		deriv = 0;
		yp0 =&ybox[0];
		deriv -= *yp0++;
		deriv -= *yp0++;
		alpha = *yp0;
		deriv -= *yp0++;
		beta = *yp0++;
		gamma = *yp0;
		deriv += *yp0++;
		deriv += *yp0++;
		deriv += *yp0++;
		// process depending on state
		switch(scan_state){
			case RESTART:
				scan_state = LEADING;
				//cp->scope_valid = FALSE;
				break;
			case LEADING:
				if(cp->sig_type == PULSE_POS && deriv > cp->sig_dvdt_lim){
					scan_state = PEAK;
					break;
				}
				if(cp->sig_type == PULSE_NEG && deriv < cp->sig_dvdt_lim){
					scan_state = PEAK;
					break;
				}
				// if no pulse then check the zero
				avg_zero = (avg_zero * 20 + y)/21;
				break;
			case PEAK:
				// reverse derivative indicates peak
				if(cp->sig_type == PULSE_POS && deriv < 0){
					scan_state = TAIL;
				}
				if(cp->sig_type == PULSE_NEG && deriv > 0){
					scan_state = TAIL;
				}
				if(scan_state == TAIL){
					// handle gaussian approximation if enabled
					if(cp->sig_gaussian){
						// p = ((a - g)/(a -2b + g))/2 = position of peak
						peak = (fixed_div((alpha - gamma),(alpha - (2 * beta) + gamma))) / 2;
						// y(p) = b - ((a - g) * p)/4  = peak value
						peak = beta - (fixed_mul((alpha - gamma), peak) / 4);
					} else {
						peak = (alpha + beta + gamma) / 3;
					}
					if(cp->sig_type == PULSE_NEG){
						peak = -peak;
					}
					// peak now always positive
					if( peak > cp->sig_lo_lim && peak < cp->sig_hi_lim){
						bin = fixed_to_int(peak);
						pulse_height[bin]++;  // increment count in spectrum array
						cur_cnt++;
						// handle rate meter beeping
						if(cp->rate_beep && !alarm_on){
							Beep(BEEP_500Hz, 10);
						}
					}
				}
				break;
			case TAIL:
				// find where curve turns back to baseline
				if(cp->sig_type == PULSE_POS && deriv >= 0){
					scan_state = LEADING;
				}
				if(cp->sig_type == PULSE_NEG && deriv <= 0){
					scan_state = LEADING;
				}
				break;
		}	// switch(scan_state)
	}	// while ring buffer not empty
}
Example #6
0
void
image_downsize_gd_fixed_point(image *im)
{
  int x, y;
  fixed_t sy1, sy2, sx1, sx2;
  int dstX = 0, dstY = 0, srcX = 0, srcY = 0;
  fixed_t width_scale, height_scale;
  
  int dstW = im->target_width;
  int dstH = im->target_height;
  int srcW = im->width;
  int srcH = im->height;
  
  if (im->height_padding) {
    dstY = im->height_padding;
    dstH = im->height_inner;
  }
  
  if (im->width_padding) {
    dstX = im->width_padding;
    dstW = im->width_inner;
  }
  
  width_scale = fixed_div(int_to_fixed(srcW), int_to_fixed(dstW));
  height_scale = fixed_div(int_to_fixed(srcH), int_to_fixed(dstH));
  
  for (y = dstY; (y < dstY + dstH); y++) {
    sy1 = fixed_mul(int_to_fixed(y - dstY), height_scale);
    sy2 = fixed_mul(int_to_fixed((y + 1) - dstY), height_scale);
    
    for (x = dstX; (x < dstX + dstW); x++) {
      fixed_t sx, sy;
  	  fixed_t spixels = 0;
  	  fixed_t red = 0, green = 0, blue = 0, alpha = 0;
  	  
  	  if (!im->has_alpha)
        alpha = FIXED_255;
  	  
      sx1 = fixed_mul(int_to_fixed(x - dstX), width_scale);
      sx2 = fixed_mul(int_to_fixed((x + 1) - dstX), width_scale);  	  
  	  sy = sy1;
  	  
  	  /*
      DEBUG_TRACE("sx1 %f, sx2 %f, sy1 %f, sy2 %f\n",
        fixed_to_float(sx1), fixed_to_float(sx2), fixed_to_float(sy1), fixed_to_float(sy2));
      */
  	  
  	  do {
        fixed_t yportion;
        
        //DEBUG_TRACE("  yportion(sy %f, sy1 %f, sy2 %f) = ", fixed_to_float(sy), fixed_to_float(sy1), fixed_to_float(sy2));
        
        if (fixed_floor(sy) == fixed_floor(sy1)) {
          yportion = FIXED_1 - (sy - fixed_floor(sy));
    		  if (yportion > sy2 - sy1) {
            yportion = sy2 - sy1;
    		  }
    		  sy = fixed_floor(sy);
    		}
    		else if (sy == fixed_floor(sy2)) {
          yportion = sy2 - fixed_floor(sy2);
        }
        else {
          yportion = FIXED_1;
        }
        
        //DEBUG_TRACE("%f\n", fixed_to_float(yportion));
        
        sx = sx1;
        
        do {
          fixed_t xportion;
    		  fixed_t pcontribution;
    		  pix p;
    		  
    		  //DEBUG_TRACE("  xportion(sx %f, sx1 %f, sx2 %f) = ", fixed_to_float(sx), fixed_to_float(sx1), fixed_to_float(sx2));
  		  
    		  if (fixed_floor(sx) == fixed_floor(sx1)) {
    	      xportion = FIXED_1 - (sx - fixed_floor(sx));
    	      if (xportion > sx2 - sx1)	{
              xportion = sx2 - sx1;
    			  }
    		    sx = fixed_floor(sx);
    		  }
    		  else if (sx == fixed_floor(sx2)) {
            xportion = sx2 - fixed_floor(sx2);
          }
    		  else {
    		    xportion = FIXED_1;
    		  }
    		  
    		  //DEBUG_TRACE("%f\n", fixed_to_float(xportion));
  		  
    		  pcontribution = fixed_mul(xportion, yportion);
  		  
    		  p = get_pix(im, fixed_to_int(sx + srcX), fixed_to_int(sy + srcY));
    		  
    		  /*
    		  DEBUG_TRACE("  merging with pix %d, %d: src %x (%d %d %d %d), pcontribution %f\n",
            fixed_to_int(sx + srcX), fixed_to_int(sy + srcY),
            p, COL_RED(p), COL_GREEN(p), COL_BLUE(p), COL_ALPHA(p), fixed_to_float(pcontribution));
          */
  		    
          red   += fixed_mul(int_to_fixed(COL_RED(p)), pcontribution);
          green += fixed_mul(int_to_fixed(COL_GREEN(p)), pcontribution);
    		  blue  += fixed_mul(int_to_fixed(COL_BLUE(p)), pcontribution);
    		  
    		  if (im->has_alpha)
    		    alpha += fixed_mul(int_to_fixed(COL_ALPHA(p)), pcontribution);
    		  
    		  spixels += pcontribution;
    		  sx += FIXED_1;
    		} while (sx < sx2);
    		
        sy += FIXED_1;
      } while (sy < sy2);
      
  	  // If rgba get too large for the fixed-point representation, fallback to the floating point routine
		  // This should only happen with very large images
		  if (red < 0 || green < 0 || blue < 0 || alpha < 0) {
        warn("fixed-point overflow: %d %d %d %d\n", red, green, blue, alpha);
        return image_downsize_gd(im);
      }
      
      if (spixels != 0) {
        /*
        DEBUG_TRACE("  rgba (%f %f %f %f) spixels %f\n",
          fixed_to_float(red), fixed_to_float(green), fixed_to_float(blue), fixed_to_float(alpha), fixed_to_float(spixels));
        */
        
        spixels = fixed_div(FIXED_1, spixels);
        
        red   = fixed_mul(red, spixels);
        green = fixed_mul(green, spixels);
        blue  = fixed_mul(blue, spixels);
        
        if (im->has_alpha)
          alpha = fixed_mul(alpha, spixels);
	    }
	    
	    /* Clamping to allow for rounding errors above */
      if (red > FIXED_255)   red = FIXED_255;
      if (green > FIXED_255) green = FIXED_255;
      if (blue > FIXED_255)  blue = FIXED_255;
      if (im->has_alpha && alpha > FIXED_255) alpha = FIXED_255;
      
      /*
      DEBUG_TRACE("  -> %d, %d %x (%d %d %d %d)\n",
        x, y, COL_FULL(fixed_to_int(red), fixed_to_int(green), fixed_to_int(blue), fixed_to_int(alpha)),
        fixed_to_int(red), fixed_to_int(green), fixed_to_int(blue), fixed_to_int(alpha));
      */
      
      if (im->orientation != ORIENTATION_NORMAL) {
        int ox, oy; // new destination pixel coordinates after rotating
        
        image_get_rotated_coords(im, x, y, &ox, &oy);
        
        if (im->orientation >= 5) {
          // 90 and 270 rotations, width/height are swapped so we have to use alternate put_pix method
          put_pix_rotated(
            im, ox, oy, im->target_height,
            COL_FULL(fixed_to_int(red), fixed_to_int(green), fixed_to_int(blue), fixed_to_int(alpha))
          );
        }
        else {
          put_pix(
            im, ox, oy,
            COL_FULL(fixed_to_int(red), fixed_to_int(green), fixed_to_int(blue), fixed_to_int(alpha))
          );
        }
      }
      else {
        put_pix(
          im, x, y,
          COL_FULL(fixed_to_int(red), fixed_to_int(green), fixed_to_int(blue), fixed_to_int(alpha))
        );
      }
	  }
	}
}
Example #7
0
File: wave.c Project: theFork/uMIDI
void set_frequency(struct wave * const wave, fixed_t frequency)
{
    wave->settings.frequency = frequency;
    const fixed_t max_frequency = fixed_from_int(F_TASK_FAST/(2*WAVE_STEPS));
    wave->state.speed_prescaler = fixed_to_int(fixed_div(max_frequency, wave->settings.frequency));
}
Example #8
0
void decode_output_samples(sample_t *buffer, u32_t nsamples, int sample_rate) {
	size_t bytes_out;

	/* Some decoders can pass no samples at the start of the track. Stop
	 * early, otherwise we may send the track start event at the wrong
	 * time.
	 */
	if (nsamples == 0) {
		return;
	}

	// XXXX full port from ip3k

	decode_audio_lock();

	if (decode_first_buffer) {
		LOG_DEBUG(log_audio_decode, "first buffer sample_rate=%d", sample_rate);

		upload_open();

		crossfade_started = FALSE;
		decode_audio->track_start_point = decode_audio->fifo.wptr;
		
		if (decode_transition_type & TRANSITION_CROSSFADE) {
			size_t crossfadeBytes;
			fft_fixed interval;

			if (decode_transition_type & TRANSITION_IMMEDIATE) {
				size_t wanted = SAMPLES_TO_BYTES(decode_transition_period * decode_audio->track_sample_rate);
				size_t used = fifo_bytes_used(&decode_audio->fifo);

				if (used > wanted) {
					size_t skip = used - wanted;
					if (skip > decode_audio->fifo.wptr) decode_audio->fifo.wptr += decode_audio->fifo.size;
					decode_audio->fifo.wptr -= skip;
				}
			}

			/* We are being asked to do a crossfade. Find out
			 * if it is possible.
			 */
			interval = determine_transition_interval(sample_rate, decode_transition_period, &crossfadeBytes);

			if (interval) {
				LOG_DEBUG(log_audio_decode, "Starting CROSSFADE over %d seconds, requiring %d bytes", fixed_to_s32(interval), (unsigned int)crossfadeBytes);

				/* Buffer position to stop crossfade */
				crossfade_ptr = decode_audio->fifo.wptr;

				/* Buffer position to start crossfade */
				if (crossfadeBytes > decode_audio->fifo.wptr) decode_audio->fifo.wptr += decode_audio->fifo.size;
				decode_audio->fifo.wptr -= crossfadeBytes;

				/* Gain steps */
				transition_gain_step = fixed_div(FIXED_ONE, fixed_mul(interval, s32_to_fixed(TRANSITION_STEPS_PER_SECOND)));
				transition_gain = 0;
				transition_sample_step = sample_rate / TRANSITION_STEPS_PER_SECOND;
				transition_samples_in_step = 0;

				crossfade_started = TRUE;
				decode_audio->track_start_point = decode_audio->fifo.wptr;
			}
			/* 
			 * else there aren't enough leftover samples from the
			 * previous track, so abort the transition.
			 */
		}
		else if (decode_transition_type & TRANSITION_FADE_IN) {
			/* The transition is a fade in. */

			LOG_DEBUG(log_audio_decode, "Starting FADE_IN over %d seconds", decode_transition_period);

			/* Gain steps */
			transition_gain_step = fixed_div(FIXED_ONE, s32_to_fixed(decode_transition_period * TRANSITION_STEPS_PER_SECOND));
			transition_gain = 0;
			transition_sample_step = sample_rate / TRANSITION_STEPS_PER_SECOND;
			transition_samples_in_step = 0;
		}

		decode_audio->track_copyright = streambuf_is_copyright();
		decode_audio->track_sample_rate = sample_rate;

		decode_audio->check_start_point = TRUE;
		decode_first_buffer = FALSE;
	}

	if (upload_samples(buffer, nsamples)) {
		decode_audio_unlock();
		return;
	}
	
	/* If output_channels is set, copy left samples to right, or vice versa */
	if (output_channels) {
		unsigned int i;
		if (output_channels & OUTPUT_CHANNEL_LEFT) {
			for (i = 0; i < nsamples * 2; i += 2) {
				buffer[i+1] = buffer[i];
			}
		}
		else {
			for (i = 0; i < nsamples * 2; i += 2) {
				buffer[i] = buffer[i+1];
			}
		}
	}

	decode_apply_track_gain(buffer, nsamples);

	bytes_out = SAMPLES_TO_BYTES(nsamples);

	while (bytes_out) {
		size_t wrap, bytes_write, bytes_remaining;

		/* The size of the output write is limied by the
		 * space untill our fifo wraps.
		 */
		wrap = fifo_bytes_until_wptr_wrap(&decode_audio->fifo);

		/* When crossfading limit the output write to the
		 * end of the transition.
		 */
		if (crossfade_started) {
			bytes_remaining = decode_transition_bytes_remaining(crossfade_ptr);
			if (bytes_remaining < wrap) {
				wrap = bytes_remaining;
			}
		}

		bytes_write = bytes_out;
		if (bytes_write > wrap) {
			bytes_write = wrap;
		}

		if (transition_gain_step) {
			decode_transition_copy_bytes(buffer, bytes_write);

			if ((crossfade_started && decode_audio->fifo.wptr == crossfade_ptr)
			    || transition_gain >= FIXED_ONE) {
				LOG_DEBUG(log_audio_decode, "Completed transition");

				transition_gain_step = 0;
				crossfade_started = FALSE;
			}
		}
		else {
			memcpy(decode_fifo_buf + decode_audio->fifo.wptr, buffer, bytes_write);
			fifo_wptr_incby(&decode_audio->fifo, bytes_write);
		}

		buffer += (bytes_write / sizeof(sample_t));
		bytes_out -= bytes_write;
	}

	decode_audio_unlock();
}