コード例 #1
0
void bufconvolve_process (t_bufconvolve *x, t_symbol *sym, long argc, t_atom *argv)
{
	t_atom temp_argv[4];
	double time_mul = 1.;
					  
	// Load and check arguments
	
	if (argc < 3)
	{
		object_error((t_object *) x, "not enough arguments to message %s", sym->s_name);
		return;
	}
	
	if (sym == gensym("deconvolve") && argc > 3)
	{
		time_mul = atom_getfloat(argv + 3);
		
		if (time_mul < 1.)
		{
			object_warn((t_object *) x, " time multiplier cannot be less than 1 (using 1)");
			time_mul = 1;
		}
	}
	
	temp_argv[0] = *argv++;
	temp_argv[1] = *argv++;
	temp_argv[2] = *argv++;
	atom_setfloat(temp_argv + 3, time_mul);
		
	defer(x, (method) bufconvolve_process_internal, sym, 4, temp_argv);
}
コード例 #2
0
ファイル: vb.goertzel~.c プロジェクト: v7b1/vb-objects
void myObj_setN(t_myObj *x, long input) {
	if(input < 16) {
		input = 16;
		object_warn((t_object*)x, "oh! smallest possible block size is 16 samps!");
	}
	x->newN = input;
}
コード例 #3
0
ファイル: fftinfo~.c プロジェクト: Cycling74/max5-sdk
void fftinfo_dsp(t_fftinfo *x, t_signal **sp, short *count)
{
	if (x->x_pfft) {
		outlet_int(x->x_out[3], (x->x_fullspect = (x->x_pfft->x_fullspect)?1:0));
		outlet_int(x->x_out[2], (x->x_ffthop = x->x_pfft->x_ffthop));
		outlet_int(x->x_out[1], (x->x_n = sp[0]->s_n));
		outlet_int(x->x_out[0], (x->x_fftsize = x->x_pfft->x_fftsize));
	}
	else if (fftinfo_warning) {
		object_warn((t_object *)x, "fftinfo~ only functions inside a pfft~",0);
		fftinfo_warning = 0;
	}
}
コード例 #4
0
ファイル: fftinfo~.c プロジェクト: Cycling74/max5-sdk
void fftinfo_bang(t_fftinfo *x)
{
	if (x->x_pfft) {
		// just output current values
		outlet_int(x->x_out[3], x->x_fullspect); // fullspect flag
		outlet_int(x->x_out[2], x->x_ffthop);
		outlet_int(x->x_out[1], x->x_n);
		outlet_int(x->x_out[0], x->x_fftsize);
	}
	else if (fftinfo_warning) {
		object_warn((t_object *)x, "fftinfo~ only functions inside a pfft~",0);
		fftinfo_warning = 0;
	}
}
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;
}
コード例 #6
0
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);
}
コード例 #7
0
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);
}
コード例 #8
0
void irextract_process (t_irextract *x, t_symbol *rec_buffer, t_atom_long num_channels, double sample_rate)
{
	FFT_SETUP_D fft_setup;
	
	FFT_SPLIT_COMPLEX_D spectrum_1;
	FFT_SPLIT_COMPLEX_D spectrum_2;
	FFT_SPLIT_COMPLEX_D spectrum_3;

	void *excitation_sig;
	double *out_mem;
	float *rec_mem;
	float *filter_in;
	
	t_symbol *filter = filter_retriever(x->deconvolve_filter_specifier);
	
	double filter_specifier[HIRT_MAX_SPECIFIER_ITEMS];
	double range_specifier[HIRT_MAX_SPECIFIER_ITEMS];
	
	double test_pow;
	double max_pow;
	double deconvolve_phase = phase_retriever(x->deconvolve_phase);
	
	long deconvolve_mode = x->deconvolve_mode;
	long bandlimit = x->measure_mode == SWEEP ? x->bandlimit : 0;
	
	AH_SIntPtr rec_length = buffer_length(rec_buffer);
	AH_SIntPtr gen_length = 0;
	AH_SIntPtr filter_length = buffer_length(filter);
	AH_SIntPtr out_length_samps;
	
	AH_UIntPtr fft_size; 
	AH_UIntPtr fft_size_log2;
	AH_UIntPtr i;
	
	if (buffer_check((t_object *)x, rec_buffer) || !rec_length)
		return;
	
	switch (x->measure_mode)
	{	
		case SWEEP:
			gen_length = ess_get_length(&x->sweep_params);
			break;
			
		case MLS:
			gen_length = mls_get_length(&x->max_length_params);
			break;
			
		case NOISE:
			gen_length = coloured_noise_get_length(&x->noise_params);
			break;
	}
	
	// Check and calculate lengths
	
	fft_size = calculate_fft_size(rec_length + gen_length, &fft_size_log2);
	
	if (rec_length % num_channels)
		object_warn ((t_object *) x, "buffer length is not a multiple of the number of channels - number may be wrong");
		
	if (((rec_length / num_channels) - gen_length) < 1)
	{
		object_error ((t_object *) x, "buffer is not long enough for generated signal");
		return;
	}
	
	out_length_samps = ((rec_length / num_channels) - gen_length);
	
	if (x->out_length)
	{
		if (out_length_samps < (x->out_length * sample_rate))
			object_warn ((t_object *) x, "buffer is not long enough for requested output length");
		else
			out_length_samps = (AH_SIntPtr) (x->out_length * sample_rate);
	}
	
	// Allocate Temporary Memory
	
	fft_setup = hisstools_create_setup_d(fft_size_log2);
		
	excitation_sig = malloc(((gen_length > filter_length) ? gen_length : filter_length) * sizeof(double));
	
	spectrum_1.realp = ALIGNED_MALLOC((sizeof(double) * fft_size * 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 = spectrum_3.realp + fft_size;
		
	rec_mem = (float *) malloc(rec_length * sizeof(float));
	
	filter_in = filter_length ? ALIGNED_MALLOC(sizeof(float *) * filter_length) : 0; 
	
	if (!fft_setup || !excitation_sig || !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);
		free(excitation_sig);
		ALIGNED_FREE(spectrum_1.realp);
		ALIGNED_FREE(filter_in);
	
		return;
	}
	
	x->fft_size = fft_size;
	x->sample_rate = sample_rate;
	x->out_length_samps = out_length_samps;
	x->gen_length = gen_length;
	
	// Allocate output memory and get record memory
	
	out_mem = grow_mem_swap(&x->out_mem, fft_size * sizeof(double), fft_size);
	
	if (!out_mem) 
	{
		object_error ((t_object *) x, "could not allocate memory for output storage");
		free(excitation_sig);
		hisstools_destroy_setup_d(fft_setup);
		return;
	}

	// Generate Signal
	
	switch (x->measure_mode)
	{
		case SWEEP:
			ess_gen(&x->sweep_params, excitation_sig, true);
			break;
			
		case MLS:
			mls_gen(&x->max_length_params, excitation_sig, true);
			break;
			
		case NOISE:
			coloured_noise_gen(&x->noise_params, excitation_sig, true);
			break;
	}
	
	// Transform excitation signal into complex spectrum 2
	
	time_to_halfspectrum_double(fft_setup, excitation_sig, gen_length, spectrum_2, fft_size);
			 
	if (bandlimit)
	{
		// Calculate standard filter for bandlimited deconvolution (sweep * inv sweep)
		
		ess_igen(&x->sweep_params, excitation_sig, true, true);
		time_to_halfspectrum_double(fft_setup, excitation_sig, gen_length, spectrum_3, fft_size);
		convolve(spectrum_3, spectrum_2, fft_size, SPECTRUM_REAL);
							
		// Calculate full power spectrum from half spectrum - convert filter to have the required phase
		
		power_full_spectrum_from_half_spectrum(spectrum_3, fft_size);		
		variable_phase_from_power_spectrum(fft_setup, spectrum_3, fft_size, deconvolve_phase, true);	
		
		// Convert back to real format
		
		spectrum_3.imagp[0] = spectrum_3.realp[fft_size >> 1];		
	}
	else 
	{
		// Find maximum power to scale 
		
		for (i = 1, max_pow = 0; i < (fft_size >> 1); i++)