int lsx_term_threads(lsx_thread_state_t *state) { if (state->use_threads && stop_workers(state) < 0) return -1; lsx_free(state->pth); memset(state, 0, sizeof(lsx_thread_state_t)); return 0; }
static void init_dft_filter(rate_shared_t * p, unsigned which, int num_taps, sox_sample_t const h[], double Fp, double Fc, double Fn, double att, int multiplier, double phase, sox_bool allow_aliasing) { dft_filter_t * f = &p->half_band[which]; int dft_length, i; if (f->num_taps) return; if (h) { // for half_fir_coefs_low dft_length = lsx_set_dft_length(num_taps); f->coefs = lsx_aligned_calloc(dft_length, sizeof(*f->coefs)); for (i = 0; i < num_taps; ++i) f->coefs[(i + dft_length - num_taps + 1) & (dft_length - 1)] = h[abs(num_taps / 2 - i)] / dft_length * 2 * multiplier; f->post_peak = num_taps / 2; } else { double * h2 = lsx_design_lpf(Fp, Fc, Fn, allow_aliasing, att, &num_taps, 0, -1.); if (phase != 50) lsx_fir_to_phase(&h2, &num_taps, &f->post_peak, phase); else f->post_peak = num_taps / 2; dft_length = lsx_set_dft_length(num_taps); f->coefs = lsx_aligned_calloc(dft_length, sizeof(*f->coefs)); for (i = 0; i < num_taps; ++i) f->coefs[(i + dft_length - num_taps + 1) & (dft_length - 1)] = h2[i] / dft_length * 2 * multiplier; lsx_free(h2); } assert(num_taps & 1); f->num_taps = num_taps; f->dft_length = dft_length; f->tmp_buf = lsx_aligned_malloc(dft_length*sizeof(FFTComplex)/2); ff_rdft_x(dft_length, 1, f->coefs, f->tmp_buf); }
static void event_close(event_t ev) { pthread_mutex_destroy(&ev->mutex); pthread_cond_destroy(&ev->cond); lsx_free(ev); }
static void rate_init(rate_t * p, rate_shared_t * shared, double factor, quality_t quality, int interp_order, double phase, double bandwidth, sox_bool allow_aliasing, sox_bool old_behaviour) { int i, tuple, mult, divisor = 1, two_or_three = 2; sox_bool two_factors = sox_false; const int max_divisor = 2048; /* Keep coef table size ~< 500kb */ double epsilon; assert(factor > 0); p->factor = factor; if (quality < High || quality > Very) quality = High; p->upsample = (sox_bool)(factor < 1); for (i = (int)(factor), p->level = 0; i >>= 1; ++p->level); /* log base 2 */ factor /= 1 << (p->level + !p->upsample); epsilon = fabs((uint32_t)(factor * MULT32 + .5) / (factor * MULT32) - 1); for (i = 2; i <= max_divisor && divisor == 1; ++i) { double try_d = factor * i; int try_i = (int)(try_d + .5); if (fabs(try_i / try_d - 1) <= epsilon) { /* N.B. beware of long doubles */ if (try_i == i) { factor = 1, divisor = 2; if (p->upsample) p->upsample = sox_false; else ++p->level; } else factor = try_i, divisor = i; } } if (!old_behaviour && factor == 3 && divisor == 4 && p->level == 1) two_or_three = 3; p->stages = (stage_t *)lsx_calloc((size_t)p->level + 4, sizeof(*p->stages)) + 1; for (i = -1; i <= p->level + 1; ++i) p->stages[i].shared = shared; last_stage.step.all = (int64_t)(factor * MULT32 + .5); last_stage.out_in_ratio = MULT32 * divisor / last_stage.step.all; if (divisor != 1) assert(!last_stage.step.parts.fraction); else assert(!last_stage.step.parts.integer); tuple = 1 + p->upsample; if (!old_behaviour && p->upsample) { if (factor == 2 && divisor == 3) two_factors = sox_true, tuple = divisor; else if (factor == 1) { if (divisor < 6) two_factors = sox_true, tuple = divisor; else for (i = 2; !two_factors && i < 20; ++i) if (!(divisor % i)) two_factors = sox_true, tuple = i; } } mult = tuple; p->input_stage_num = -p->upsample; p->output_stage_num = p->level; if (two_or_three != 3 && last_stage.out_in_ratio != 2 && !two_factors) { poly_fir_t const * f; poly_fir1_t const * f1; int n = 2 * p->upsample + (quality - High); //if (interp_order < 0) interp_order = quality > High; interp_order = divisor == 1? 1 + interp_order : 0; last_stage.divisor = divisor; p->output_stage_num += 2; f = &poly_firs[n]; f1 = &f->interp[interp_order]; if (!last_stage.shared->poly_fir_coefs) { int num_taps = f->num_coefs, phases = divisor == 1? (1 << f1->phase_bits) : divisor; raw_coef_t * coefs = lsx_design_lpf( f->pass, f->stop, 1., sox_false, f->att, &num_taps, phases, -1.); assert(num_taps == f->num_coefs * phases - 1); last_stage.shared->poly_fir_coefs = prepare_coefs(coefs, f->num_coefs, phases, interp_order, mult, quality - High); lsx_free(coefs); } last_stage.fn = f1->fn; last_stage.pre_post = f->num_coefs - 1; last_stage.pre = 0; last_stage.preload = last_stage.pre_post >> 1; mult = 1; }