void bufreverse_process_internal(t_bufreverse *x, t_symbol *sym, short argc, t_atom *argv) { t_symbol *target = atom_getsym(argv++); t_symbol *source = atom_getsym(argv++); float *temp1; double *temp2; t_buffer_write_error error; AH_SIntPtr full_length = buffer_length(source); AH_SIntPtr i; double sample_rate = 0; t_atom_long read_chan = x->read_chan - 1; // Check source buffer if (buffer_check((t_object *) x, source, read_chan)) return; sample_rate = buffer_sample_rate(source); // Allocate Memory temp1 = (float *) ALIGNED_MALLOC(full_length * (sizeof(double) + sizeof(float))); temp2 = (double *) (temp1 + full_length); // Check momory allocation if (!temp1) { object_error((t_object *)x, "could not allocate temporary memory for processing"); free(temp1); return; } // Read from buffer buffer_read(source, read_chan, (float *) temp1, full_length); // Copy to double precision version for (i = 0; i < full_length; i++) temp2[i] = temp1[full_length - i - 1]; // Copy out to buffer error = buffer_write(target, temp2, full_length, x->write_chan - 1, x->resize, sample_rate, 1.); buffer_write_error((t_object *)x, target, error); // Free Resources ALIGNED_FREE(temp1); if (!error) outlet_bang(x->process_done); }
void irextract_mls (t_irextract *x, t_symbol *sym, long argc, t_atom *argv) { double sample_rate; double out_length = 0; t_atom_long num_channels = 1; t_atom_long order = 18; t_symbol *rec_buffer = 0; // Load parameters if (argc > 0) { rec_buffer = atom_getsym(argv++); sample_rate = buffer_sample_rate(rec_buffer); } if (argc > 1) order = atom_getlong(argv++); if (argc > 2) num_channels = atom_getlong(argv++); if (argc > 3) out_length = atom_getfloat(argv++); // Check parameters if (!rec_buffer) { object_error((t_object *)x, "no buffer given"); return; } order = (t_atom_long) irextract_param_check(x, "order", (double) order, 1, 24); num_channels = (t_atom_long) irextract_param_check(x, "number of channels", (double) num_channels, 1, HIRT_MAX_MEASURE_CHANS); x->out_length = irextract_param_check(x, "output length", out_length, 0., HUGE_VAL) / 1000.; // Process x->measure_mode = MLS; mls_params(&x->max_length_params, (long) order, db_to_a(x->amp)); irextract_process(x, rec_buffer, num_channels, sample_rate); }
short buffer_multiple_names(t_object *x, t_symbol **in_bufs, t_symbol **out_bufs, AH_SIntPtr *lengths, short argc, t_atom *argv, t_atom_long read_chan, t_atom_long write_chan, long in_place, short max_bufs, AH_SIntPtr *overall_len_ret, AH_SIntPtr *max_len_ret, double *sample_rate_ret) { AH_SIntPtr overall_length = 0; AH_SIntPtr max_length = 0; AH_SIntPtr new_length; short i; double sample_rate = 0.0; double new_sample_rate; if (!in_place) { if (argc % 2) { object_error((t_object *) x, "target buffer with no matching input buffer"); return 0; } argc /= 2; } if (argc > max_bufs) argc = max_bufs; if (!argc) { object_error(x, "no buffers specified"); return 0; } for (i = 0; i < argc; i++) { if (atom_gettype(argv + i) != A_SYM) { object_error(x, "name of buffer expected, but number given"); return 0; } if (buffer_check(x, atom_getsym(argv + i), write_chan)) return 0; if (in_place) { new_length = buffer_length (atom_getsym(argv + i)); new_sample_rate = buffer_sample_rate(atom_getsym(argv + i)); if (buffer_check(x, atom_getsym(argv + i), read_chan)) return 0; } else { new_length = buffer_length (atom_getsym(argv + i + argc)); new_sample_rate = buffer_sample_rate(atom_getsym(argv + i + argc)); if (buffer_check(x, atom_getsym(argv + i + argc), read_chan)) return 0; } if (new_length == 0) { object_error(x, "buffer %s has zero length ", atom_getsym(argv + i)->s_name); return 0; } // Store name and length out_bufs[i] = atom_getsym(argv + i); lengths[i] = new_length; if (in_place) in_bufs[i] = atom_getsym(argv + i); else in_bufs[i] = atom_getsym(argv + i + argc); if (new_length > max_length) max_length = new_length; overall_length += new_length; // Check sample rates if ((sample_rate != 0.0 && sample_rate != new_sample_rate) || new_sample_rate == 0.0) object_warn(x, "sample rates do not match for all source buffers"); else sample_rate = new_sample_rate; } *overall_len_ret = overall_length; *max_len_ret = max_length; *sample_rate_ret = sample_rate; return argc; }
void bufconvolve_process_internal (t_bufconvolve *x, t_symbol *sym, short argc, t_atom *argv) { FFT_SETUP_D fft_setup; FFT_SPLIT_COMPLEX_D spectrum_1; FFT_SPLIT_COMPLEX_D spectrum_2; FFT_SPLIT_COMPLEX_D spectrum_3; double *out_buf; float *in_temp; float *filter_in; AH_Boolean convolve_mode = sym == gensym("convolve") ? true : false; t_symbol *target = atom_getsym(argv++); t_symbol *source_1 = atom_getsym(argv++); t_symbol *source_2 = atom_getsym(argv++); t_symbol *filter = filter_retriever(x->deconvolve_filter_specifier); double filter_specifier[HIRT_MAX_SPECIFIER_ITEMS]; double range_specifier[HIRT_MAX_SPECIFIER_ITEMS]; double time_mul = atom_getfloat(argv++); double sample_rate = buffer_sample_rate(source_1); double deconvolve_phase = phase_retriever(x->deconvolve_phase); double deconvolve_delay; AH_SIntPtr source_length_1 = buffer_length(source_1); AH_SIntPtr source_length_2 = buffer_length(source_2); AH_SIntPtr filter_length = buffer_length(filter); AH_UIntPtr fft_size; AH_UIntPtr fft_size_log2; long deconvolve_mode = x->deconvolve_mode; t_buffer_write_error error; // Check input buffers if (buffer_check((t_object *) x, source_1) || buffer_check((t_object *) x, source_2)) return; // Check sample rates if (sample_rate != buffer_sample_rate(source_2)) object_warn((t_object *) x, "sample rates do not match"); // Check and calculate lengths if (convolve_mode == true) fft_size = (AH_UIntPtr) ((source_length_1 + source_length_2) * time_mul); else fft_size = (AH_UIntPtr) (source_length_1 < source_length_2 ? source_length_2 * time_mul : source_length_1 * time_mul); fft_size = calculate_fft_size(fft_size, &fft_size_log2); deconvolve_delay = delay_retriever(x->deconvolve_delay, fft_size, sample_rate); if (fft_size < 8) { object_error((t_object *) x, "input buffers are too short, or have no length"); return; } // Allocate Memory (use pointer aliasing where possible for efficiency) fft_setup = hisstools_create_setup_d(fft_size_log2); spectrum_1.realp = ALIGNED_MALLOC(sizeof(double) * fft_size * (convolve_mode == true ? 3 : 4)); spectrum_1.imagp = spectrum_1.realp + (fft_size >> 1); spectrum_2.realp = spectrum_1.imagp + (fft_size >> 1); spectrum_2.imagp = spectrum_2.realp + (fft_size >> 1); spectrum_3.realp = spectrum_2.imagp + (fft_size >> 1); spectrum_3.imagp = convolve_mode == true ? 0 : spectrum_3.realp + fft_size; filter_in = filter_length ? ALIGNED_MALLOC(sizeof(float *) * filter_length) : 0; out_buf = spectrum_2.realp; in_temp = (float *) spectrum_3.realp; // Check memory allocations if (!fft_setup || !spectrum_1.realp || (filter_length && !filter_in)) { object_error((t_object *) x, "could not allocate temporary memory for processing"); hisstools_destroy_setup_d(fft_setup); ALIGNED_FREE(spectrum_1.realp); ALIGNED_FREE(filter_in); return; } // Get inputs - convert to frequency domain buffer_read(source_1, x->read_chan - 1, in_temp, source_length_1); time_to_halfspectrum_float(fft_setup, in_temp, source_length_1, spectrum_1, fft_size); buffer_read(source_2, x->read_chan - 1, in_temp, source_length_2); time_to_halfspectrum_float(fft_setup, in_temp, source_length_2, spectrum_2, fft_size); // Do deconvolution or convolution if (convolve_mode == true) convolve(spectrum_1, spectrum_2, fft_size, SPECTRUM_REAL); else { // Fill deconvolution filter specifiers - load filter from buffer (if specified) - deconvolve fill_power_array_specifier(filter_specifier, x->deconvolve_filter_specifier, x->deconvolve_num_filter_specifiers); fill_power_array_specifier(range_specifier, x->deconvolve_range_specifier, x->deconvolve_num_range_specifiers); buffer_read(filter, 0, filter_in, fft_size); deconvolve(fft_setup, spectrum_1, spectrum_2, spectrum_3, filter_specifier, range_specifier, 0.0, filter_in, filter_length, fft_size, SPECTRUM_REAL, deconvolve_mode, deconvolve_phase, deconvolve_delay, sample_rate); } // Convert to time domain - copy out to buffer spectrum_to_time(fft_setup, out_buf, spectrum_1, fft_size, SPECTRUM_REAL); error = buffer_write(target, out_buf, (convolve_mode == true ? source_length_1 + source_length_2 - 1 : fft_size), x->write_chan - 1, x->resize, sample_rate, 1.); buffer_write_error((t_object *) x, target, error); // Free resources hisstools_destroy_setup_d(fft_setup); ALIGNED_FREE(spectrum_1.realp); ALIGNED_FREE(filter_in); if (!error) outlet_bang(x->process_done); }
void irphase_process_internal (t_irphase *x, t_symbol *sym, short argc, t_atom *argv) { FFT_SETUP_D fft_setup; FFT_SPLIT_COMPLEX_D spectrum_1; FFT_SPLIT_COMPLEX_D spectrum_2; FFT_SPLIT_COMPLEX_D spectrum_3; float *in; float *filter_in; double *out_buf; t_symbol *filter = filter_retriever(x->deconvolve_filter_specifier); t_symbol *target = atom_getsym(argv++); t_symbol *source = atom_getsym(argv++); double filter_specifier[HIRT_MAX_SPECIFIER_ITEMS]; double range_specifier[HIRT_MAX_SPECIFIER_ITEMS]; double phase = atom_getfloat(argv++); double time_mul = atom_getfloat(argv++); double sample_rate = buffer_sample_rate(source); double deconvolve_delay; double deconvolve_phase; t_phase_type mode = (t_phase_type) atom_getlong(argv++); AH_UIntPtr fft_size; AH_UIntPtr fft_size_log2; AH_UIntPtr i; t_buffer_write_error error; long deconvolve_mode; // Get input buffer lengths AH_SIntPtr source_length_1 = buffer_length(source); AH_SIntPtr filter_length = buffer_length(filter); AH_SIntPtr max_length = source_length_1; // Check input buffers if (buffer_check((t_object *) x, source)) return; // Calculate fft size time_mul = time_mul == 0. ? 1 : time_mul; if (time_mul < 1) { object_warn((t_object *) x, " time multiplier cannot be less than 1 (using 1)"); time_mul = 1; } fft_size = calculate_fft_size((long) (max_length * time_mul), &fft_size_log2); if (fft_size < 8) { object_error((t_object *) x, "buffers are too short, or have no length"); return; } deconvolve_mode = x->deconvolve_mode; deconvolve_phase = phase_retriever(x->deconvolve_phase); deconvolve_delay = delay_retriever(x->deconvolve_delay, fft_size, sample_rate); // Allocate momory fft_setup = hisstools_create_setup_d(fft_size_log2); spectrum_1.realp = ALIGNED_MALLOC(sizeof(double) * fft_size * (mode == MODE_ALLPASS ? 6 : 3)); spectrum_1.imagp = spectrum_1.realp + fft_size; spectrum_2.realp = spectrum_1.imagp + fft_size; spectrum_2.imagp = mode == MODE_ALLPASS ? spectrum_2.realp + fft_size : 0; spectrum_3.realp = mode == MODE_ALLPASS ? spectrum_2.imagp + fft_size : 0; spectrum_3.imagp = mode == MODE_ALLPASS ? spectrum_3.realp + fft_size : 0; filter_in = filter_length ? ALIGNED_MALLOC(sizeof(float *) * filter_length) : 0; out_buf = mode == MODE_ALLPASS ? spectrum_3.realp : spectrum_2.realp; in = (float *) out_buf; if (!spectrum_1.realp || !fft_setup || (filter_length && !filter_in)) { object_error((t_object *) x, "could not allocate temporary memory for processing"); hisstools_destroy_setup_d(fft_setup); ALIGNED_FREE(spectrum_1.realp); ALIGNED_FREE(filter_in); return; } // Get input - convert to frequency domain - get power spectrum - convert phase buffer_read(source, x->read_chan - 1, in, fft_size); time_to_spectrum_float(fft_setup, in, source_length_1, spectrum_1, fft_size); power_spectrum(spectrum_1, fft_size, SPECTRUM_FULL); variable_phase_from_power_spectrum(fft_setup, spectrum_1, fft_size, phase, false); if (mode == MODE_ALLPASS) { // Copy minimum phase spectrum to spectrum_2 for (i = 0; i < fft_size; i++) { spectrum_2.realp[i] = spectrum_1.realp[i]; spectrum_2.imagp[i] = spectrum_1.imagp[i]; } // Get input again time_to_spectrum_float(fft_setup, in, source_length_1, spectrum_1, fft_size); // Fill deconvolution filter specifiers - read filter from buffer (if specified) - deconvolve input by minimum phase spectrum fill_power_array_specifier(filter_specifier, x->deconvolve_filter_specifier, x->deconvolve_num_filter_specifiers); fill_power_array_specifier(range_specifier, x->deconvolve_range_specifier, x->deconvolve_num_range_specifiers); buffer_read(filter, 0, filter_in, fft_size); deconvolve(fft_setup, spectrum_1, spectrum_2, spectrum_3, filter_specifier, range_specifier, 0, filter_in, filter_length, fft_size, SPECTRUM_FULL, deconvolve_mode, deconvolve_phase, deconvolve_delay, sample_rate); } // Convert to time domain - copy out to buffer spectrum_to_time(fft_setup, out_buf, spectrum_1, fft_size, SPECTRUM_FULL); error = buffer_write(target, out_buf, fft_size, x->write_chan - 1, x->resize, sample_rate, 1); buffer_write_error((t_object *) x, target, error); // Free memory hisstools_destroy_setup_d(fft_setup); ALIGNED_FREE(spectrum_1.realp); ALIGNED_FREE(filter_in); if (!error) outlet_bang(x->process_done); }
void ircropfade_process_internal(t_ircropfade *x, t_symbol *sym, short argc, t_atom *argv) { // Load arguments t_symbol *target = atom_getsym(argv++); t_symbol *source = atom_getsym(argv++); t_atom_long crop1 = atom_getlong(argv++); t_atom_long crop2 = atom_getlong(argv++); double fade_start = atom_getfloat(argv++); double in_length = atom_getfloat(argv++); double fade_end = atom_getfloat(argv++); double out_length = atom_getfloat(argv++); // Set fade variables double fade_in_lo = fade_start - 1; double fade_in_hi = in_length > 0 ? fade_start + in_length : fade_start; double fade_out_lo = fade_end; double fade_out_hi = out_length > 0 ? fade_end - out_length : fade_end - 1; double fade_in_recip = 1. / (fade_in_hi - fade_in_lo); double fade_out_recip = 1. / (fade_out_hi - fade_out_lo); float *temp1; double *temp2; t_buffer_write_error error; AH_SIntPtr full_length = buffer_length(source); AH_SIntPtr final_length; AH_SIntPtr i; t_atom_long read_chan = x->read_chan - 1; double sample_rate = 0; // Check source buffer if (buffer_check((t_object *) x, source, read_chan)) return; sample_rate = buffer_sample_rate(source); crop1 = crop1 < 0 ? 0 : crop1; crop2 = crop2 < 0 ? 0 : crop2; crop1 = crop1 > full_length - 1 ? full_length - 1: crop1; crop2 = crop2 > full_length ? full_length : crop2; if (crop1 >= crop2) return; final_length = crop2 - crop1; // Allocate Memory temp1 = (float *) ALIGNED_MALLOC(full_length * sizeof(float) + final_length * sizeof(double)); temp2 = (double *) (temp1 + full_length); // Check momory allocation if (!temp1) { object_error((t_object *)x, "could not allocate temporary memory for processing"); free(temp1); return; } // Read from buffer buffer_read(source, read_chan, (float *) temp1, full_length); // Copy with crops / fades to double precision version for (i = 0; i < final_length; i++) { double in_val = temp1[i + crop1]; double fade_in = calculate_fade((double) (i + crop1), fade_in_lo, fade_in_recip); double fade_out = calculate_fade((double) (i + crop1), fade_out_lo, fade_out_recip); temp2[i] = in_val * fade_in * fade_out; } // Copy out to buffer error = buffer_write(target, temp2, final_length, x->write_chan - 1, x->resize, sample_rate, 1.); buffer_write_error((t_object *)x, target, error); // Free Resources ALIGNED_FREE(temp1); if (!error) outlet_bang(x->process_done); }
void irextract_noise (t_irextract *x, t_symbol *sym, long argc, t_atom *argv) { double length = 10000; double fade_in = 10; double fade_out = 10; double amp_comp = 1.; double out_length = 0; double max_pink, max_brown; double sample_rate; t_atom_long num_channels = 1; t_symbol *rec_buffer = 0; t_noise_mode noise_mode = NOISE_MODE_WHITE; if (sym == gensym("brown")) noise_mode = NOISE_MODE_BROWN; if (sym == gensym("pink")) noise_mode = NOISE_MODE_PINK; // Load parameters if (argc > 0) { rec_buffer = atom_getsym(argv++); sample_rate = buffer_sample_rate(rec_buffer); } if (argc > 1) length = atom_getfloat(argv++); if (argc > 2) fade_in = atom_getfloat(argv++); if (argc > 3) fade_out = atom_getfloat(argv++); if (argc > 4) num_channels = atom_getlong(argv++); if (argc > 5) out_length = atom_getfloat(argv++); // Check parameters if (!rec_buffer) { object_error((t_object *)x, "no buffer given"); return; } length = irextract_param_check(x, "length", length, 0., HUGE_VAL); fade_in = irextract_param_check(x, "fade in time", fade_in, 0., length / 2); fade_out = irextract_param_check(x, "fade out time", fade_out, 0., length / 2); num_channels = (t_atom_long) irextract_param_check(x, "number of channels", (double) num_channels, 1, HIRT_MAX_MEASURE_CHANS); x->out_length = irextract_param_check(x, "output length", out_length, 0., HUGE_VAL) / 1000.; // Process x->measure_mode = NOISE; coloured_noise_params(&x->noise_params, noise_mode, fade_in / 1000., fade_out / 1000., length / 1000., sample_rate, db_to_a(x->amp) / amp_comp); if (noise_mode != NOISE_MODE_WHITE) { coloured_noise_measure(&x->noise_params, (int) (length * sample_rate * 1000.), &max_pink, &max_brown); coloured_noise_reset(&x->noise_params); } if (noise_mode == NOISE_MODE_BROWN) amp_comp = max_brown; if (noise_mode == NOISE_MODE_PINK) amp_comp = max_pink; irextract_process(x, rec_buffer, num_channels, sample_rate); }
void irextract_sweep (t_irextract *x, t_symbol *sym, long argc, t_atom *argv) { double f1 = 20; double f2 = 22050; double length = 30000; double fade_in = 50; double fade_out = 10; double out_length = 0; double sample_rate; double amp_curve[33]; t_atom_long num_channels = 1; t_symbol *rec_buffer = 0; // Load parameters if (argc > 0) { rec_buffer = atom_getsym(argv++); sample_rate = buffer_sample_rate(rec_buffer); f2 = sample_rate / 2.; } if (argc > 1) f1 = atom_getfloat(argv++); if (argc > 2) f2 = atom_getfloat(argv++); if (argc > 3) length = atom_getfloat(argv++); if (argc > 4) fade_in = atom_getfloat(argv++); if (argc > 5) fade_out = atom_getfloat(argv++); if (argc > 6) num_channels = atom_getlong(argv++); if (argc > 7) out_length = atom_getfloat(argv++); // Check parameters if (!rec_buffer) { object_error((t_object *)x, "no buffer given"); return; } f1 = irextract_param_check(x, "low frequency", f1, 0.0001, sample_rate / 2); f2 = irextract_param_check(x, "high frequency", f2, f2, sample_rate / 2); length = irextract_param_check(x, "length", length, 0., HUGE_VAL); fade_in = irextract_param_check(x, "fade in time", fade_in, 0., length / 2); fade_out = irextract_param_check(x, "fade out time", fade_out, 0., length / 2); num_channels = (t_atom_long) irextract_param_check(x, "number of channels", (double) num_channels, 1, HIRT_MAX_MEASURE_CHANS); x->out_length = irextract_param_check(x, "output length", out_length, 0., HUGE_VAL) / 1000.; // Check length of sweep and memory allocation fill_amp_curve_specifier(amp_curve, x->amp_curve_specifier, x->amp_curve_num_specifiers); if (ess_params(&x->sweep_params, f1, f2, fade_in / 1000., fade_out / 1000., length / 1000., sample_rate, db_to_a(x->amp), amp_curve)) { // Process x->measure_mode = SWEEP; irextract_process(x, rec_buffer, num_channels, sample_rate); } else object_error((t_object *) x, "zero length sweep - requested length value is too small"); }