Example #1
0
void waveform_float_wavetable_sine_mix(float_waveform_t *waveform, float_oscillator_t *osc, float *sample_buffer, int sample_count)
{
	fixed_t frequency_ratio = DOUBLE_TO_FIXED(osc->frequency / waveform->frequency);
	fixed_t phase_step = fixed_mul(frequency_ratio, waveform->phase_step);

	float amplitude_step = (osc->level - osc->last_level) / sample_count;
	float amplitude_scale = osc->last_level;

	while (sample_count > 0)
	{
		int sample_index = fixed_mul(osc->phase_fixed, waveform->sample_count);
		float sample = waveform->samples[sample_index];
		sample *= amplitude_scale;
		sample += *sample_buffer;
		*sample_buffer++ = sample;
		*sample_buffer++ = sample;
		osc->phase_fixed += phase_step;
		if (osc->phase_fixed >= FIXED_ONE)
		{
			osc->phase_fixed -= FIXED_ONE;
		}
		amplitude_scale += amplitude_step;
		sample_count--;
	}

}
void test_fixed_multiply(void)
{
  /* Negative */
  a = fixed_make(-2023.621F);
  b = fixed_make(10.0F);
  result = fixed_mul(a, b);
  TEST_ASSERT_EQUAL_FLOAT(fixed_make(-20236.21F), result);

  /* Positive */
  a = fixed_make(2023.621F);
  b = fixed_make(10.0F);
  result = fixed_mul(a, b);
  TEST_ASSERT_EQUAL_FLOAT(fixed_make(20236.21F), result);
}
Example #3
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 #4
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;
}
Example #5
0
/* Called to copy samples to the decode fifo when we are doing
 * a transition - crossfade or fade in. This method applies gain
 * to both the new signal and the one that's already in the fifo.
 */
static void decode_transition_copy_bytes(sample_t *buffer, size_t nbytes) {
	sample_t sample, *sptr;
	int nsamples, s;
	size_t bytes_read;
	fft_fixed in_gain, out_gain;

	ASSERT_AUDIO_LOCKED();

	while (nbytes) {
		bytes_read = SAMPLES_TO_BYTES(transition_sample_step - transition_samples_in_step);

		if (bytes_read > nbytes) {
			bytes_read = nbytes;
		}

		nsamples = BYTES_TO_SAMPLES(bytes_read);

		sptr = (sample_t *)(void *)(decode_fifo_buf + decode_audio->fifo.wptr);

		in_gain = transition_gain;
		out_gain = FIXED_ONE - in_gain;

		if (crossfade_started) {
			for (s=0; s<nsamples * 2; s++) {
				sample = fixed_mul(out_gain, *sptr);
				sample += fixed_mul(in_gain, *buffer++);
				*sptr++ = sample;
			}
		}
		else {
			for (s=0; s<nsamples * 2; s++) {
				*sptr++ = fixed_mul(in_gain, *buffer++);
			}
		}

		fifo_wptr_incby(&decode_audio->fifo, bytes_read);
		nbytes -= bytes_read;

		transition_samples_in_step += nsamples;
		while (transition_samples_in_step >= transition_sample_step) {
			transition_samples_in_step -= transition_sample_step;
			transition_gain += transition_gain_step;
		}
	}
}
Example #6
0
static inline sample_t volume_mul(sample_t sample, fft_fixed gain, sample_t clip_range[2]) {
	if (sample > clip_range[0]) {
		return SAMPLE_MAX;
	}
	if (sample < clip_range[1]) {
		return SAMPLE_MIN;
	}

	return fixed_mul(gain, sample);
}
Example #7
0
File: mat.c Project: tuttlem/freak
void mat44_euler_rot(mat44 *m, fixed yaw, fixed pitch, fixed roll) {
  fixed sb = fixed_sin(yaw), cb = fixed_cos(yaw),
    sa = fixed_sin(pitch), ca = fixed_cos(pitch),
    sc = fixed_sin(roll), cc = fixed_cos(roll);

  fixed
    a00 = fixed_mul(cc, cb),
    a01 = fixed_mul(-cb, sc),
    a02 = sb,
    a10 = fixed_mul3(sa, sb, cc) + fixed_mul(ca, sc),
    a11 = fixed_mul3(-sa, sb, sc) + fixed_mul(ca, cc),
    a12 = fixed_mul(-sa, cb),
    a20 = fixed_mul3(-ca, sb, cc) + fixed_mul(sa, sc),
    a21 = fixed_mul3(ca, sb, sc) + fixed_mul(sa, cc),
    a22 = fixed_mul(ca, cb);

  mat44_set(m,
            a00, a01, a02, 0,
            a10, a11, a12, 0,
            a20, a21, a22, 0,
            0  , 0  , 0  , FIXED_ONE);
}
Example #8
0
File: mat.c Project: tuttlem/freak
void mat44_axis_rot(mat44 *m, vec3 *axis, fixed angle) {
  fixed ca = fixed_cos(angle),
    sa = fixed_sin(angle);

  fixed nca = FIXED_ONE - ca;

  fixed
    a00 = ca + fixed_mul3(axis->x, axis->x, nca),
    a01 = fixed_mul3(axis->x, axis->y, nca) - fixed_mul(axis->z, sa),
    a02 = fixed_mul3(axis->x, axis->z, nca) + fixed_mul(axis->y, sa),
    a10 = fixed_mul3(axis->y, axis->x, nca) + fixed_mul(axis->z, sa),
    a11 = ca + fixed_mul3(axis->y, axis->y, nca),
    a12 = fixed_mul3(axis->y, axis->z, nca) - fixed_mul(axis->x, sa),
    a20 = fixed_mul3(axis->z, axis->x, nca) - fixed_mul(axis->y, sa),
    a21 = fixed_mul3(axis->z, axis->y, nca) + fixed_mul(axis->x, sa),
    a22 = ca + fixed_mul3(axis->z, axis->z, nca);
                                                    
  mat44_set(m,
            a00, a01, a02, 0,
            a10, a11, a12, 0,
            a20, a21, a22, 0,
            0  , 0  , 0  , FIXED_ONE);
  
}
Example #9
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 #10
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 #11
0
void draw_background_mode7(void) {


	int map_color;

	over_water=0;

	/* Draw Sky */
	/* Originally wanted to be fancy and have sun too, but no */
	color_equals(COLOR_MEDIUMBLUE);
	for(screen_y=0;screen_y<6;screen_y+=2) {
		hlin_double(ram[DRAW_PAGE], 0, 40, screen_y);
	}

	/* Draw hazy horizon */
	color_equals(COLOR_GREY);
	hlin_double(ram[DRAW_PAGE], 0, 40, 6);

//	fixed_to_double(&space_z,&double_space_z);
//	double_factor=double_space_z*double_BETA;

	fixed_mul(&space_z,&BETA,&factor,0);

	if (!displayed) {
		printf("SPACEZ/BETA/FACTOR %x %x * %x %x = %x %x\n",
			space_z.i,space_z.f,BETA.i,BETA.f,factor.i,factor.f);
	}

//	printf("spacez=%lf beta=%lf factor=%lf\n",
//		fixed_to_double(&space_z),
//		fixed_to_double(&BETA),
//		fixed_to_double(&factor));

	for (screen_y = 8; screen_y < LOWRES_H; screen_y+=2) {

		// then calculate the horizontal scale, or the distance between
		// space points on this horizontal line
//		double_horizontal_scale = double_space_z  / (screen_y + horizon);
//		double_to_fixed(double_horizontal_scale,&horizontal_scale);
		horizontal_scale.i=0;
		horizontal_scale.f=
			horizontal_lookup[space_z.i&0xf][(screen_y-8)/2];

		if (!displayed) {
			printf("HORIZ_SCALE %x %x\n",
			horizontal_scale.i,horizontal_scale.f);
		}

		// calculate the distance of the line we are drawing
		fixed_mul(&horizontal_scale,&scale,&distance,0);
		//fixed_to_double(&distance,&double_distance);

//		printf("Distance=%lf, horizontal-scale=%lf\n",
//			distance,horizontal_scale);


		if (!displayed) {
			printf("DISTANCE %x:%x\n",
			distance.i,distance.f);
		}

		// calculate the dx and dy of points in space when we step
		// through all points on this line
		dx.i=fixed_sin[(angle+8)&0xf].i;	// -sin()
		dx.f=fixed_sin[(angle+8)&0xf].f;	// -sin()
		fixed_mul(&dx,&horizontal_scale,&dx,0);

		if (!displayed) {
			printf("DX %x:%x\n",
			dx.i,dx.f);
		}


		dy.i=fixed_sin[(angle+4)&0xf].i;	// cos()
		dy.f=fixed_sin[(angle+4)&0xf].f;	// cos()
		fixed_mul(&dy,&horizontal_scale,&dy,0);

		if (!displayed) {
			printf("DY %x:%x\n",
			dy.i,dy.f);
		}

		// calculate the starting position
		//double_space_x =(double_distance+double_factor);
		fixed_add(&distance,&factor,&space_x);
//		double_to_fixed(double_space_x,&space_x);
		fixed_temp.i=fixed_sin[(angle+4)&0xf].i; // cos
		fixed_temp.f=fixed_sin[(angle+4)&0xf].f; // cos
		fixed_mul(&space_x,&fixed_temp,&space_x,0);
		fixed_add(&space_x,&cx,&space_x);
		fixed_temp.i=0xec;	// -20 (LOWRES_W/2)
		fixed_temp.f=0;
		fixed_mul(&fixed_temp,&dx,&fixed_temp,0);
		fixed_add(&space_x,&fixed_temp,&space_x);

		if (!displayed) {
			printf("SPACEX! %x:%x\n",
			space_x.i,space_x.f);
		}

		fixed_add(&distance,&factor,&space_y);
//		double_space_y =(double_distance+double_factor);
//		double_to_fixed(double_space_y,&space_y);
		fixed_temp.i=fixed_sin[angle&0xf].i;
		fixed_temp.f=fixed_sin[angle&0xf].f;
		fixed_mul(&space_y,&fixed_temp,&space_y,0);
		fixed_add(&space_y,&cy,&space_y);
		fixed_temp.i=0xec;	// -20 (LOWRES_W/2)
		fixed_temp.f=0;
		fixed_mul(&fixed_temp,&dy,&fixed_temp,0);
		fixed_add(&space_y,&fixed_temp,&space_y);

		if (!displayed) {
			printf("SPACEY! %x:%x\n",
			space_y.i,space_y.f);
		}

		// go through all points in this screen line
		for (screen_x = 0; screen_x < LOWRES_W-1; screen_x++) {
			// get a pixel from the tile and put it on the screen

			map_color=lookup_map(space_x.i,space_y.i);

			ram[COLOR]=map_color;
			ram[COLOR]|=map_color<<4;

			if ((screen_x==20) && (screen_y==38)) {
				if (map_color==COLOR_DARKBLUE) over_water=1;
			}

			hlin_double(ram[DRAW_PAGE], screen_x, screen_x+1,
				screen_y);

			// advance to the next position in space
			fixed_add(&space_x,&dx,&space_x);
			fixed_add(&space_y,&dy,&space_y);
		}
	}
	displayed=1;
}
Example #12
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();
}
Example #13
0
int main(int argc, char **argv) {

	int a_i,b_i,c_i;
	int a_f,b_f,c_f;
//	short x,y;
	int l,k,i,j;

	printf("Some tests\n");
#if 0
	x=-32768;
	y=3;

	a_i=x>>8;
	a_f=x&0xff;
	b_i=y>>8;
	b_f=y&0xff;

	printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y);
	k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0);
	if (k!=x*y) {
		printf("\t\tError! got %d (0x%x)\n",k,k);
		exit(1);
	}
	else {
		printf("\t\tProperly calculated %d\n",k);
	}

	a_i=0x0;
	a_f=0x7;

	b_i=0x0;
	b_f=0x9;

	x=7;
	y=9;

	printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y);
	k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0);
	if (k!=x*y) {
		printf("\t\tError! got %d (0x%x)\n",k,k);
		exit(1);
	}
	else {
		printf("\t\tProperly calculated %d (0x%x)\n",k,k);
	}

	a_i=0x0;
	a_f=0x2;

	b_i=0x0;
	b_f=0x3;

	x=2;
	y=3;

	printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y);
	k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0);
	if (k!=x*y) {
		printf("\t\tError! got %d (0x%x)\n",k,k);
		exit(1);
	}
	else {
		printf("\t\tProperly calculated %d (0x%x)\n",k,k);
	}

	a_i=0xff;
	a_f=0xff;

	b_i=0xff;
	b_f=0xff;

	x=0xffff;
	y=0xffff;

	printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y);
	k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0);
	if (k!=x*y) {
		printf("\t\tError! got %d (0x%x)\n",k,k);
		exit(1);
	}
	else {
		printf("\t\tProperly calculated %d (0x%x)\n",k,k);
	}

	a_i=0xff;
	a_f=0xff;

	b_i=0x00;
	b_f=0x01;

	x=0xffff;
	y=0x1;

	printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y);
	k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0);
	if (k!=x*y) {
		printf("\t\tError! got %d (0x%x)\n",k,k);
		exit(1);
	}
	else {
		printf("\t\tProperly calculated %d (0x%x)\n",k,k);
	}

	a_i=0x00;
	a_f=0xff;

	b_i=0x00;
	b_f=0x01;

	x=0xff;
	y=0x1;

	printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y);
	k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0);
	if (k!=x*y) {
		printf("\t\tError! got %d (0x%x)\n",k,k);
		exit(1);
	}
	else {
		printf("\t\tProperly calculated %d (0x%x)\n",k,k);
	}

	for(i=-32768;i<32768;i++) {
		for(j=-32768;j<32768;j++) {
			a_i=i>>8;
			a_f=i&0xff;
			b_i=j>>8;
			b_f=j&0xff;

			k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0);

			if (k!=i*j) {
				printf("WRONG! %x*%x = %x not %x\n",
					i,j,i*j,k);
				printf("       %d * %d = %d not %d\n",i,j,i*j,k);
				exit(1);
			}
		}
		if (i%256==0) printf("%x\n",i);
	}
#endif

	for(i=-32768;i<32768;i++) {
		for(j=-32768;j<32768;j++) {
			a_i=i>>8;
			a_f=i&0xff;
			b_i=j>>8;
			b_f=j&0xff;

			fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0);
			k=((i*j)>>8)&0xffff;
			l=(c_i<<8)|(c_f);

			if (k!=l) {
				printf("WRONG! %x*%x = %x, %x not %02x:%02x\n",
					i,j,i*j,k,c_i,c_f);
				printf("       %d * %d = %d not %d\n",i,j,l,k);
				exit(1);
			}
		}
		if (i%256==0) printf("%x\n",i);
	}


	return 0;
}