예제 #1
0
int OverlayAudio::process_buffer(int64_t size, 
	Samples **buffer,
	int64_t start_position,
	int sample_rate)
{
	load_configuration();


	int output_track = 0;
	if(config.output_track == OverlayAudioConfig::BOTTOM)
		output_track = get_total_buffers() - 1;

// Direct copy the output track
	read_samples(buffer[output_track],
		output_track,
		sample_rate,
		start_position,
		size);

// Add remaining tracks
	Samples *output_buffer = buffer[output_track];
	double *output_samples = output_buffer->get_data();
	for(int i = 0; i < get_total_buffers(); i++)
	{
		if(i != output_track)
		{
			Samples *input_buffer = buffer[i];
			read_samples(buffer[i],
				i,
				sample_rate,
				start_position,
				size);
			double *input_samples = input_buffer->get_data();
			
			switch(config.mode)
			{
				case OverlayAudioConfig::ADD:
					for(int j = 0; j < size; j++)
					{
						output_samples[j] += input_samples[j];
					}
					break;
					
					
				case OverlayAudioConfig::MULTIPLY:
					for(int j = 0; j < size; j++)
					{
						output_samples[j] *= input_samples[j];
					}
					break;
			}
		}
	}

	return 0;
}
예제 #2
0
int TimeFrontMain::process_buffer(VFrame **frame,
		int64_t start_position,
		double frame_rate)
//int TimeFrontMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
{
	VFrame **outframes = frame;
	VFrame *(framelist[1024]);
	framelist[0] = new VFrame (
		outframes[0]->get_w(),
		outframes[0]->get_h(),
		outframes[0]->get_color_model());
	read_frame(framelist[0],
		0,
		start_position,
		frame_rate);
	this->input = framelist[0];
	this->output = outframes[0];
	need_reconfigure |= load_configuration();
	if (config.shape == TimeFrontConfig::OTHERTRACK)
	{
//		this->output = frame[1];
		if (get_total_buffers() != 2) 
		{
			// FIXME, maybe this should go to some other notification area?
			printf("ERROR: TimeFront plugin - If you are using another track for timefront, you have to have it under shared effects\n");
			return 0;
		}
		if (outframes[0]->get_w() != outframes[1]->get_w() || outframes[0]->get_h() != outframes[1]->get_h())
		{
			printf("Sizes of master track and timefront track do not match\n");
			return 0;
		}
	}

// Generate new gradient
	if(need_reconfigure)
	{
		need_reconfigure = 0;

		if(!gradient) gradient = new VFrame(
			outframes[0]->get_w(),
			outframes[0]->get_h(),
			BC_A8);

			
		if (config.shape != TimeFrontConfig::OTHERTRACK &&
		    config.shape != TimeFrontConfig::ALPHA)
		{
			if(!engine) engine = new TimeFrontServer(this,
				get_project_smp() + 1,
				get_project_smp() + 1);
			engine->process_packages();
		}
		
	}
	if (config.shape == TimeFrontConfig::ALPHA)
	{
		if(!gradient) gradient = new VFrame(
			outframes[0]->get_w(),
			outframes[0]->get_h(),
			BC_A8);
		VFrame *tfframe = framelist[0];
		switch (tfframe->get_color_model())
		{
			case BC_YUVA8888:
			case BC_RGBA8888:
				GRADIENTFROMCHANNEL(unsigned char, 4, 255, 3);


				break;
			case BC_RGBA_FLOAT:
				GRADIENTFROMCHANNEL(float, 4, 1.0f, 3);
				break;
			
			default:
				{
					printf("TimeFront plugin error: ALPHA used, but project color model does not have alpha\n");
					return 1;
					break;
				}
		}

	} else
	if (config.shape == TimeFrontConfig::OTHERTRACK)
예제 #3
0
int CompressorEffect::process_buffer(int64_t size, 
		Samples **buffer,
		int64_t start_position,
		int sample_rate)
{
	load_configuration();

// Calculate linear transfer from db 
	levels.remove_all();
	for(int i = 0; i < config.levels.total; i++)
	{
		levels.append();
		levels.values[i].x = DB::fromdb(config.levels.values[i].x);
		levels.values[i].y = DB::fromdb(config.levels.values[i].y);
	}
	min_x = DB::fromdb(config.min_db);
	min_y = DB::fromdb(config.min_db);
	max_x = 1.0;
	max_y = 1.0;


	int reaction_samples = (int)(config.reaction_len * sample_rate + 0.5);
	int decay_samples = (int)(config.decay_len * sample_rate + 0.5);
	int trigger = CLIP(config.trigger, 0, PluginAClient::total_in_buffers - 1);

	CLAMP(reaction_samples, -1000000, 1000000);
	CLAMP(decay_samples, reaction_samples, 1000000);
	CLAMP(decay_samples, 1, 1000000);
	if(labs(reaction_samples) < 1) reaction_samples = 1;
	if(labs(decay_samples) < 1) decay_samples = 1;

	int total_buffers = get_total_buffers();
	if(reaction_samples >= 0)
	{
		if(target_current_sample < 0) target_current_sample = reaction_samples;
		for(int i = 0; i < total_buffers; i++)
		{
			read_samples(buffer[i],
				i,
				sample_rate,
				start_position,
				size);
		}

		double current_slope = (next_target - previous_target) / 
			reaction_samples;
		double *trigger_buffer = buffer[trigger]->get_data();
		for(int i = 0; i < size; i++)
		{
// Get slope required to reach current sample from smoothed sample over reaction
// length.
			double sample;
			switch(config.input)
			{
				case CompressorConfig::MAX:
				{
					double max = 0;
					for(int j = 0; j < total_buffers; j++)
					{
						sample = fabs(buffer[j]->get_data()[i]);
						if(sample > max) max = sample;
					}
					sample = max;
					break;
				}

				case CompressorConfig::TRIGGER:
					sample = fabs(trigger_buffer[i]);
					break;
				
				case CompressorConfig::SUM:
				{
					double max = 0;
					for(int j = 0; j < total_buffers; j++)
					{
						sample = fabs(buffer[j]->get_data()[i]);
						max += sample;
					}
					sample = max;
					break;
				}
			}

			double new_slope = (sample - current_value) /
				reaction_samples;

// Slope greater than current slope
			if(new_slope >= current_slope && 
				(current_slope >= 0 ||
				new_slope >= 0))
			{
				next_target = sample;
				previous_target = current_value;
				target_current_sample = 0;
				target_samples = reaction_samples;
				current_slope = new_slope;
			}
			else
			if(sample > next_target && current_slope < 0)
			{
				next_target = sample;
				previous_target = current_value;
				target_current_sample = 0;
				target_samples = decay_samples;
				current_slope = (sample - current_value) / decay_samples;
			}
// Current smoothed sample came up without finding higher slope
			if(target_current_sample >= target_samples)
			{
				next_target = sample;
				previous_target = current_value;
				target_current_sample = 0;
				target_samples = decay_samples;
				current_slope = (sample - current_value) / decay_samples;
			}

// Update current value and store gain
			current_value = (next_target * target_current_sample + 
				previous_target * (target_samples - target_current_sample)) /
				target_samples;

			target_current_sample++;

			if(config.smoothing_only)
			{
				for(int j = 0; j < total_buffers; j++)
					buffer[j]->get_data()[i] = current_value;
			}
			else
			{
				double gain = calculate_gain(current_value);
				for(int j = 0; j < total_buffers; j++)
				{
					buffer[j]->get_data()[i] *= gain;
				}
			}
		}
	}
	else
	{
		if(target_current_sample < 0) target_current_sample = target_samples;
		int64_t preview_samples = -reaction_samples;

// Start of new buffer is outside the current buffer.  Start buffer over.
		if(start_position < input_start ||
			start_position >= input_start + input_size)
		{
			input_size = 0;
			input_start = start_position;
		}
		else
// Shift current buffer so the buffer starts on start_position
		if(start_position > input_start &&
			start_position < input_start + input_size)
		{
			if(input_buffer)
			{
				int len = input_start + input_size - start_position;
				for(int i = 0; i < total_buffers; i++)
				{
					memcpy(input_buffer[i]->get_data(),
						input_buffer[i]->get_data() + (start_position - input_start),
						len * sizeof(double));
				}
				input_size = len;
				input_start = start_position;
			}
		}

// Expand buffer to handle preview size
		if(size + preview_samples > input_allocated)
		{
			Samples **new_input_buffer = new Samples*[total_buffers];
			for(int i = 0; i < total_buffers; i++)
			{
				new_input_buffer[i] = new Samples(size + preview_samples);
				if(input_buffer)
				{
					memcpy(new_input_buffer[i]->get_data(), 
						input_buffer[i]->get_data(), 
						input_size * sizeof(double));
					delete input_buffer[i];
				}
			}
			if(input_buffer) delete [] input_buffer;

			input_allocated = size + preview_samples;
			input_buffer = new_input_buffer;
		}

// Append data to input buffer to construct readahead area.
#define MAX_FRAGMENT_SIZE 131072
		while(input_size < size + preview_samples)
		{
			int fragment_size = MAX_FRAGMENT_SIZE;
			if(fragment_size + input_size > size + preview_samples)
				fragment_size = size + preview_samples - input_size;
			for(int i = 0; i < total_buffers; i++)
			{
				input_buffer[i]->set_offset(input_size);
//printf("CompressorEffect::process_buffer %d %p %d\n", __LINE__, input_buffer[i], input_size);
				read_samples(input_buffer[i],
					i,
					sample_rate,
					input_start + input_size,
					fragment_size);
				input_buffer[i]->set_offset(0);
			}
			input_size += fragment_size;
		}


		double current_slope = (next_target - previous_target) /
			target_samples;
		double *trigger_buffer = input_buffer[trigger]->get_data();
		for(int i = 0; i < size; i++)
		{
// Get slope from current sample to every sample in preview_samples.
// Take highest one or first one after target_samples are up.

// For optimization, calculate the first slope we really need.
// Assume every slope up to the end of preview_samples has been calculated and
// found <= to current slope.
            int first_slope = preview_samples - 1;
// Need new slope immediately
			if(target_current_sample >= target_samples)
				first_slope = 1;
			for(int j = first_slope; 
				j < preview_samples; 
				j++)
			{
				double sample;
				switch(config.input)
				{
					case CompressorConfig::MAX:
					{
						double max = 0;
						for(int k = 0; k < total_buffers; k++)
						{
							sample = fabs(input_buffer[k]->get_data()[i + j]);
							if(sample > max) max = sample;
						}
						sample = max;
						break;
					}

					case CompressorConfig::TRIGGER:
						sample = fabs(trigger_buffer[i + j]);
						break;

					case CompressorConfig::SUM:
					{
						double max = 0;
						for(int k = 0; k < total_buffers; k++)
						{
							sample = fabs(input_buffer[k]->get_data()[i + j]);
							max += sample;
						}
						sample = max;
						break;
					}
				}






				double new_slope = (sample - current_value) /
					j;
// Got equal or higher slope
				if(new_slope >= current_slope && 
					(current_slope >= 0 ||
					new_slope >= 0))
				{
					target_current_sample = 0;
					target_samples = j;
					current_slope = new_slope;
					next_target = sample;
					previous_target = current_value;
				}
				else
				if(sample > next_target && current_slope < 0)
				{
					target_current_sample = 0;
					target_samples = decay_samples;
					current_slope = (sample - current_value) /
						decay_samples;
					next_target = sample;
					previous_target = current_value;
				}

// Hit end of current slope range without finding higher slope
				if(target_current_sample >= target_samples)
				{
					target_current_sample = 0;
					target_samples = decay_samples;
					current_slope = (sample - current_value) / decay_samples;
					next_target = sample;
					previous_target = current_value;
				}
			}

// Update current value and multiply gain
			current_value = (next_target * target_current_sample +
				previous_target * (target_samples - target_current_sample)) /
				target_samples;
//buffer[0][i] = current_value;
			target_current_sample++;

			if(config.smoothing_only)
			{
				for(int j = 0; j < total_buffers; j++)
				{
					buffer[j]->get_data()[i] = current_value;
				}
			}
			else
			{
				double gain = calculate_gain(current_value);
				for(int j = 0; j < total_buffers; j++)
				{
					buffer[j]->get_data()[i] = input_buffer[j]->get_data()[i] * gain;
				}
			}
		}



	}





	return 0;
}
예제 #4
0
int Vocoder::process_buffer(int64_t size, 
	Samples **buffer, 
	int64_t start_position,
	int sample_rate)
{
	need_reconfigure |= load_configuration();
	if(need_reconfigure) reconfigure();

// Process all except output channel
	int carrier_track = config.carrier_track;
	CLAMP(carrier_track, 0, PluginClient::get_total_buffers() - 1);
	int formant_track = 0;
	if(carrier_track == 0) formant_track = 1;
	CLAMP(formant_track, 0, PluginClient::get_total_buffers() - 1);


// Copy level controls to band levels
	for(int i = 0; i < current_bands; i++)
	{
		output_bands[i].level = 1.0;
	}

	
	for(int i = 0; i < get_total_buffers(); i++)
	{
		read_samples(buffer[i],
			i,
			get_samplerate(),
			start_position,
			size);
	}

	double *carrier_samples = buffer[carrier_track]->get_data();
	double *formant_samples = buffer[formant_track]->get_data();
	double *output = buffer[0]->get_data();
	double wetness = DB::fromdb(config.wetness);
	double level = DB::fromdb(config.level);
	for(int i = 0; i < size; i++)
	{
		do_bandpasses(carrier_bands, carrier_samples[i]);
		do_bandpasses(formant_bands, formant_samples[i]);
		
		output[i] *= wetness;
		double accum = 0;
		for(int j = 0; j < current_bands; j++)
		{
			output_bands[j].oldval = output_bands[j].oldval +
	    	  	(fabs (formant_bands[j].y) - 
		    		output_bands[j].oldval) * 
	    	 	output_bands[j].decay;
			double x = carrier_bands[j].y * output_bands[j].oldval;
			accum += x * output_bands[j].level;
		}

		accum *= level;

		output[i] += accum;
	}

	return 0;
}
예제 #5
0
int Overlay::process_buffer(VFrame **frame,
	int64_t start_position,
	double frame_rate)
{
	load_configuration();


printf("Overlay::process_buffer mode=%d\n", config.mode);
	if(!temp) temp = new VFrame(0,
		-1,
		frame[0]->get_w(),
		frame[0]->get_h(),
		frame[0]->get_color_model(),
		-1);

	if(!overlayer)
		overlayer = new OverlayFrame(get_project_smp() + 1);

	int step;
	VFrame *output;

	if(config.direction == OverlayConfig::BOTTOM_FIRST)
	{
		input_layer1 = get_total_buffers() - 1;
		input_layer2 = -1;
		step = -1;
	}
	else
	{
		input_layer1 = 0;
		input_layer2 = get_total_buffers();
		step = 1;
	}

	if(config.output_layer == OverlayConfig::TOP)
	{
		output_layer = 0;
	}
	else
	{
		output_layer = get_total_buffers() - 1;
	}



// Direct copy the first layer
	output = frame[output_layer];
	read_frame(output,
		input_layer1,
		start_position,
		frame_rate,
		get_use_opengl());

	if(get_total_buffers() == 1) return 0;



	current_layer = input_layer1;
	if(get_use_opengl())
		run_opengl();

	for(int i = input_layer1 + step; i != input_layer2; i += step)
	{
		read_frame(temp,
			i,
			start_position,
			frame_rate,
			get_use_opengl());

// Call the opengl handler once for each layer
		if(get_use_opengl())
		{
			current_layer = i;
			run_opengl();
		}
		else
		{
			overlayer->overlay(output,
				temp,
				0,
				0,
				output->get_w(),
				output->get_h(),
				0,
				0,
				output->get_w(),
				output->get_h(),
				1,
				config.mode,
				NEAREST_NEIGHBOR);
		}
	}


	return 0;
}