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); }
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); }
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; }
/* 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; } } }
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); }
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); }
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); }
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 }
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)) ); } } } }
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; }
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(); }
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; }