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); } } }
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"); } } } }
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; }
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); }