Example #1
0
void
JackDriver::post_process_port(ProcessContext& context, EnginePort* port)
{
	const SampleCount nframes    = context.nframes();
	jack_port_t*      jack_port  = (jack_port_t*)port->handle();
	PortImpl*         graph_port = port->graph_port();
	void*             buffer     = port->buffer();

	if (graph_port->is_input()) {
		return;
	}

	if (!buffer) {
		// First cycle for a new output, so pre_process wasn't called
		buffer = jack_port_get_buffer(jack_port, nframes);
		port->set_buffer(buffer);
	}

	graph_port->post_process(context);
	Buffer* const graph_buf = graph_port->buffer(0).get();
	if (graph_port->is_a(PortType::AUDIO)) {
		memcpy(buffer, graph_buf->samples(), nframes * sizeof(Sample));
	} else if (graph_port->buffer_type() == graph_port->bufs().uris().atom_Sequence) {
		jack_midi_clear_buffer(buffer);
		LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)graph_buf->atom();
		LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
			const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY(&ev->body);
			if (ev->body.type == graph_port->bufs().uris().midi_MidiEvent) {
				jack_midi_event_write(buffer, ev->time.frames, buf, ev->body.size);
			}
		}
	}
Example #2
0
void
JackDriver::pre_process_port(ProcessContext& context, EnginePort* port)
{
	const SampleCount nframes    = context.nframes();
	jack_port_t*      jack_port  = (jack_port_t*)port->handle();
	PortImpl*         graph_port = port->graph_port();
	void*             buffer     = jack_port_get_buffer(jack_port, nframes);

	port->set_buffer(buffer);

	if (!graph_port->is_input()) {
		graph_port->buffer(0)->clear();
		return;
	}

	if (graph_port->is_a(PortType::AUDIO)) {
		Buffer* graph_buf = graph_port->buffer(0).get();
		memcpy(graph_buf->samples(), buffer, nframes * sizeof(float));

	} else if (graph_port->buffer_type() == graph_port->bufs().uris().atom_Sequence) {
		Buffer* graph_buf = (Buffer*)graph_port->buffer(0).get();

		const jack_nframes_t event_count = jack_midi_get_event_count(buffer);

		graph_buf->prepare_write(context);

		// Copy events from Jack port buffer into graph port buffer
		for (jack_nframes_t i = 0; i < event_count; ++i) {
			jack_midi_event_t ev;
			jack_midi_event_get(&ev, buffer, i);

			if (!graph_buf->append_event(
				    ev.time, ev.size, _midi_event_type, ev.buffer)) {
				_engine.log().warn("Failed to write to MIDI buffer, events lost!\n");
			}
		}
	}
}
Example #3
0
void
DelayNode::run(ProcessContext& context)
{
	Buffer* const delay_buf = _delay_port->buffer(0).get();
	Buffer* const in_buf    = _in_port->buffer(0).get();
	Buffer* const out_buf   = _out_port->buffer(0).get();

	DelayNode* plugin_data = this;

	const float* const in            = in_buf->samples();
	float* const       out           = out_buf->samples();
	const float        delay_time    = delay_buf->samples()[0];
	const uint32_t     buffer_mask   = plugin_data->_buffer_mask;
	const SampleRate   sample_rate   = context.engine().driver()->sample_rate();
	float              delay_samples = plugin_data->_delay_samples;
	int64_t            write_phase   = plugin_data->_write_phase;
	const uint32_t     sample_count  = context.nframes();

	if (write_phase == 0) {
		_last_delay_time = delay_time;
		_delay_samples   = delay_samples = CALC_DELAY(delay_time);
	}

	if (delay_time == _last_delay_time) {
		const int64_t idelay_samples = (int64_t)delay_samples;
		const float   frac           = delay_samples - idelay_samples;

		for (uint32_t i = 0; i < sample_count; i++) {
			int64_t read_phase = write_phase - (int64_t)delay_samples;
			const float read = cube_interp(frac,
			                               buffer_at(read_phase - 1),
			                               buffer_at(read_phase),
			                               buffer_at(read_phase + 1),
			                               buffer_at(read_phase + 2));
			buffer_at(write_phase++) = in[i];
			out[i] = read;
		}
	} else {
		const float next_delay_samples  = CALC_DELAY(delay_time);
		const float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count;

		for (uint32_t i = 0; i < sample_count; i++) {
			delay_samples += delay_samples_slope;
			write_phase++;
			const int64_t read_phase     = write_phase - (int64_t)delay_samples;
			const int64_t idelay_samples = (int64_t)delay_samples;
			const float   frac           = delay_samples - idelay_samples;
			const float   read           = cube_interp(frac,
			                                           buffer_at(read_phase - 1),
			                                           buffer_at(read_phase),
			                                           buffer_at(read_phase + 1),
			                                           buffer_at(read_phase + 2));
			buffer_at(write_phase) = in[i];
			out[i] = read;
		}

		_last_delay_time = delay_time;
		_delay_samples   = delay_samples;
	}

	_write_phase = write_phase;
}
Example #4
0
void
DelayNode::process(ProcessContext& context)
{
	AudioBuffer* const delay_buf = (AudioBuffer*)_delay_port->buffer(0).get();
	AudioBuffer* const in_buf    = (AudioBuffer*)_in_port->buffer(0).get();
	AudioBuffer* const out_buf   = (AudioBuffer*)_out_port->buffer(0).get();

	NodeImpl::pre_process(context);

	DelayNode* plugin_data = this;

	const float* const in            = in_buf->data();
	float* const       out           = out_buf->data();
	const float        delay_time    = delay_buf->data()[0];
	const uint32_t     buffer_mask   = plugin_data->_buffer_mask;
	const unsigned int sample_rate   = plugin_data->_srate;
	float              delay_samples = plugin_data->_delay_samples;
	long               write_phase   = plugin_data->_write_phase;
	const uint32_t     sample_count  = context.nframes();

	if (write_phase == 0) {
		_last_delay_time = delay_time;
		_delay_samples   = delay_samples = CALC_DELAY(delay_time);
	}

	if (delay_time == _last_delay_time) {
		const long  idelay_samples = (long)delay_samples;
		const float frac           = delay_samples - idelay_samples;

		for (uint32_t i = 0; i < sample_count; i++) {
			long read_phase = write_phase - (long)delay_samples;
			const float read = cube_interp(frac,
					buffer_at(read_phase - 1),
					buffer_at(read_phase),
					buffer_at(read_phase + 1),
					buffer_at(read_phase + 2));
			buffer_at(write_phase++) = in[i];
			out[i] = read;
		}
	} else {
		const float next_delay_samples  = CALC_DELAY(delay_time);
		const float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count;

		for (uint32_t i = 0; i < sample_count; i++) {
			delay_samples += delay_samples_slope;
			write_phase++;
			const long  read_phase     = write_phase - (long)delay_samples;
			const long  idelay_samples = (long)delay_samples;
			const float frac           = delay_samples - idelay_samples;
			const float read           = cube_interp(frac,
					buffer_at(read_phase - 1),
					buffer_at(read_phase),
					buffer_at(read_phase + 1),
					buffer_at(read_phase + 2));
			buffer_at(write_phase) = in[i];
			out[i] = read;
		}

		_last_delay_time = delay_time;
		_delay_samples   = delay_samples;
	}

	_write_phase = write_phase;

	NodeImpl::post_process(context);
}