~hp/orbit.lv2

edd9aad27dfbe98f33412d1bbe7ea49a166f2015 — Hanspeter Portner 3 months ago ebfd944
Add missing curly braces around if/else statements
M meson_options.txt => meson_options.txt +1 -1
@@ 9,4 9,4 @@ option('lv2libdir',
	type : 'string',
	value : 'lib/lv2')

option('version', type : 'string', value : '0.1.679')
option('version', type : 'string', value : '0.1.705')

M src/orbit_beatbox.c => src/orbit_beatbox.c +32 -0
@@ 79,13 79,21 @@ _note(plughandle_t *handle, uint8_t frames, uint8_t cmd, uint8_t channel, uint8_
	LV2_Atom_Forge_Ref ref = handle->ref;

	if(ref)
	{
		ref = lv2_atom_forge_frame_time(&handle->forge, frames);
	}
	if(ref)
	{
		ref = lv2_atom_forge_atom(&handle->forge, 3, handle->urid.midi_event);
	}
	if(ref)
	{
		ref = lv2_atom_forge_raw(&handle->forge, midi, 3);
	}
	if(ref)
	{
		lv2_atom_forge_pad(&handle->forge, 3);
	}

	handle->ref = ref;
}


@@ 269,7 277,9 @@ _cb(timely_t *timely, int64_t frames, LV2_URID type, void *data)
				handle->beat_count = TIMELY_FRAMES_PER_SECOND(&handle->timely) * 60
					/ TIMELY_BEATS_PER_MINUTE(&handle->timely) / 2;
				if(handle->ref)
				{
					props_set(&handle->props, &handle->forge, frames, handle->urid.beat_led, &handle->ref);
				}
			}
		}
	}


@@ 293,7 303,9 @@ _cb(timely_t *timely, int64_t frames, LV2_URID type, void *data)
				handle->bar_count = TIMELY_FRAMES_PER_SECOND(&handle->timely) * 60
					/ TIMELY_BEATS_PER_MINUTE(&handle->timely) / 2;
				if(handle->ref)
				{
					props_set(&handle->props, &handle->forge, frames, handle->urid.bar_led, &handle->ref);
				}
			}
		}
	}


@@ 305,15 317,21 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
{
	plughandle_t *handle = calloc(1, sizeof(plughandle_t));
	if(!handle)
	{
		return NULL;
	}
	mlock(handle, sizeof(plughandle_t));

	for(unsigned i=0; features[i]; i++)
	{
		if(!strcmp(features[i]->URI, LV2_URID__map))
		{
			handle->map = features[i]->data;
		}
		else if(!strcmp(features[i]->URI, LV2_LOG__log))
		{
			handle->log= features[i]->data;
		}
	}

	if(!handle->map)


@@ 325,7 343,9 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
	}

	if(handle->log)
	{
		lv2_log_logger_init(&handle->logger, handle->map, handle->log);
	}

	handle->urid.midi_event = handle->map->map(handle->map->handle, LV2_MIDI__MidiEvent);



@@ 389,7 409,9 @@ run(LV2_Handle instance, uint32_t nsamples)
	{
		const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
		if(!timely_advance(&handle->timely, obj, last_t, ev->time.frames))
		{
			props_advance(&handle->props, &handle->forge, ev->time.frames, obj, &handle->ref);
		}

		last_t = ev->time.frames;
	}


@@ 403,7 425,9 @@ run(LV2_Handle instance, uint32_t nsamples)
		{
			handle->state.bar_led = 0;
			if(handle->ref)
			{
				props_set(&handle->props, &handle->forge, nsamples-1, handle->urid.bar_led, &handle->ref);
			}
		}
	}



@@ 414,18 438,24 @@ run(LV2_Handle instance, uint32_t nsamples)
		{
			handle->state.beat_led = 0;
			if(handle->ref)
			{
				props_set(&handle->props, &handle->forge, nsamples-1, handle->urid.beat_led, &handle->ref);
			}
		}
	}

	if(handle->ref)
	{
		lv2_atom_forge_pop(&handle->forge, &frame);
	}
	else
	{
		lv2_atom_sequence_clear(handle->event_out);

		if(handle->log)
		{
			lv2_log_trace(&handle->logger, "forge buffer overflow\n");
		}
	}
}



@@ 467,7 497,9 @@ static const void*
extension_data(const char* uri)
{
	if(!strcmp(uri, LV2_STATE__interface))
	{
		return &state_iface;
	}

	return NULL;
}

M src/orbit_click.c => src/orbit_click.c +24 -0
@@ 95,9 95,13 @@ _bar_intercept(void *data, int64_t frames UNUSED, props_impl_t *impl UNUSED)
	{
		handle->bar.wave[i] = sin(i * 2.f * M_PI * handle->bar.freq / handle->rate) * amp;
		if(i < handle->attack_len)
		{
			handle->bar.wave[i] *= (float)i / handle->attack_len;
		}
		else // >= handle->attack_len
		{
			handle->bar.wave[i] *= (float)(handle->bar.wave_len - i) / handle->decay_len;
		}
	}
}



@@ 112,9 116,13 @@ _beat_intercept(void *data, int64_t frames UNUSED, props_impl_t *impl UNUSED)
	{
		handle->beat.wave[i] = sin(i * 2.f * M_PI * handle->beat.freq / handle->rate) * amp;
		if(i < handle->attack_len)
		{
			handle->beat.wave[i] *= (float)i / handle->attack_len;
		}
		else // >= attack_len
		{
			handle->beat.wave[i] *= (float)(handle->beat.wave_len - i) / handle->decay_len;
		}
	}
}



@@ 220,15 228,21 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
{
	plughandle_t *handle = calloc(1, sizeof(plughandle_t));
	if(!handle)
	{
		return NULL;
	}
	mlock(handle, sizeof(plughandle_t));

	for(unsigned i=0; features[i]; i++)
	{
		if(!strcmp(features[i]->URI, LV2_URID__map))
		{
			handle->map = features[i]->data;
		}
		else if(!strcmp(features[i]->URI, LV2_LOG__log))
		{
			handle->log= features[i]->data;
		}
	}

	if(!handle->map)


@@ 240,7 254,9 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
	}

	if(handle->log)
	{
		lv2_log_logger_init(&handle->logger, handle->map, handle->log);
	}

	timely_mask_t mask = TIMELY_MASK_BAR_BEAT_WHOLE
		| TIMELY_MASK_BAR_WHOLE


@@ 364,7 380,9 @@ run(LV2_Handle instance, uint32_t nsamples)

		const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
		if(!timely_advance(&handle->timely, obj, last_t, ev->time.frames))
		{
			props_advance(&handle->props, &handle->forge, ev->time.frames, obj, &handle->ref);
		}

		last_t = ev->time.frames;
	}


@@ 374,13 392,17 @@ run(LV2_Handle instance, uint32_t nsamples)
	timely_advance(&handle->timely, NULL, last_t, nsamples);

	if(handle->ref)
	{
		lv2_atom_forge_pop(&handle->forge, &frame);
	}
	else
	{
		lv2_atom_sequence_clear(handle->event_out);

		if(handle->log)
		{
			lv2_log_trace(&handle->logger, "forge buffer overflow\n");
		}
	}
}



@@ 426,7 448,9 @@ static const void*
extension_data(const char* uri)
{
	if(!strcmp(uri, LV2_STATE__interface))
	{
		return &state_iface;
	}

	return NULL;
}

M src/orbit_looper.c => src/orbit_looper.c +8 -0
@@ 431,14 431,22 @@ _cb(timely_t *timely, int64_t frames, LV2_URID type, void *data)
						};

						if(handle->log)
						{
							lv2_log_trace(&handle->logger, "releasing hanging note %"PRIx8" %02"PRIx8, cha, note);
						}

						if(handle->ref)
						{
							handle->ref = lv2_atom_forge_frame_time(&handle->forge, frames);
						}
						if(handle->ref)
						{
							handle->ref = lv2_atom_forge_atom(&handle->forge, sizeof(msg), handle->urid.midi_event);
						}
						if(handle->ref)
						{
							handle->ref = lv2_atom_forge_write(&handle->forge, msg, sizeof(msg));
						}

						handle->active[cha][note] = false;
					}

M src/orbit_monitor.c => src/orbit_monitor.c +12 -0
@@ 127,15 127,21 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
{
	plughandle_t *handle = calloc(1, sizeof(plughandle_t));
	if(!handle)
	{
		return NULL;
	}
	mlock(handle, sizeof(plughandle_t));

	for(unsigned i=0; features[i]; i++)
	{
		if(!strcmp(features[i]->URI, LV2_URID__map))
		{
			handle->map = features[i]->data;
		}
		else if(!strcmp(features[i]->URI, LV2_LOG__log))
		{
			handle->log= features[i]->data;
		}
	}

	if(!handle->map)


@@ 147,7 153,9 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
	}

	if(handle->log)
	{
		lv2_log_logger_init(&handle->logger, handle->map, handle->log);
	}

	const timely_mask_t mask = 0;
	timely_init(&handle->timely, handle->map, rate, mask, _cb, handle);


@@ 259,7 267,9 @@ run(LV2_Handle instance, uint32_t nsamples)
		lv2_atom_sequence_clear(handle->event_out);

		if(handle->log)
		{
			lv2_log_trace(&handle->logger, "forge buffer overflow\n");
		}
	}
}



@@ 301,7 311,9 @@ static const void*
extension_data(const char* uri)
{
	if(!strcmp(uri, LV2_STATE__interface))
	{
		return &state_iface;
	}

	return NULL;
}

M src/orbit_pacemaker.c => src/orbit_pacemaker.c +52 -0
@@ 87,50 87,86 @@ _position_atomize(plughandle_t *handle, LV2_Atom_Forge *forge, int64_t frames,

	LV2_Atom_Forge_Ref ref = lv2_atom_forge_frame_time(forge, frames);
	if(ref)
	{
		ref = lv2_atom_forge_object(forge, &frame, 0, handle->urid.time_position);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, handle->urid.time_barBeat);
	}
	if(ref)
	{
		ref = lv2_atom_forge_float(forge, pos->bar_beat);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, handle->urid.time_bar);
	}
	if(ref)
	{
		ref = lv2_atom_forge_long(forge, pos->bar);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, handle->urid.time_beatUnit);
	}
	if(ref)
	{
		ref = lv2_atom_forge_int(forge, pos->beat_unit);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, handle->urid.time_beatsPerBar);
	}
	if(ref)
	{
		ref = lv2_atom_forge_float(forge, pos->beats_per_bar);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, handle->urid.time_beatsPerMinute);
	}
	if(ref)
	{
		ref = lv2_atom_forge_float(forge, pos->beats_per_minute);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, handle->urid.time_frame);
	}
	if(ref)
	{
		ref = lv2_atom_forge_long(forge, pos->frame);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, handle->urid.time_framesPerSecond);
	}
	if(ref)
	{
		ref = lv2_atom_forge_float(forge, pos->frames_per_second);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, handle->urid.time_speed);
	}
	if(ref)
	{
		ref = lv2_atom_forge_float(forge, pos->speed);
	}

	if(ref)
	{
		lv2_atom_forge_pop(forge, &frame);
	}

	return ref;
}


@@ 180,7 216,9 @@ _intercept(void *data, int64_t frames, props_impl_t *impl)
	}

	if(handle->ref)
	{
		handle->ref = _position_atomize(handle, &handle->forge, frames, pos);
	}

	// update frames_per_beat and frames_per_bar
	handle->frames_per_beat = 240.0 / (pos->beats_per_minute * pos->beat_unit) * pos->frames_per_second;


@@ 232,7 270,9 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
	int i;
	plughandle_t *handle = calloc(1, sizeof(plughandle_t));
	if(!handle)
	{
		return NULL;
	}
	mlock(handle, sizeof(plughandle_t));

	handle->pos.frames_per_second = rate;


@@ 240,9 280,13 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
	for(i=0; features[i]; i++)
	{
		if(!strcmp(features[i]->URI, LV2_URID__map))
		{
			handle->map = features[i]->data;
		}
		else if(!strcmp(features[i]->URI, LV2_LOG__log))
		{
			handle->log= features[i]->data;
		}
	}

	if(!handle->map)


@@ 254,7 298,9 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
	}

	if(handle->log)
	{
		lv2_log_logger_init(&handle->logger, handle->map, handle->log);
	}

	handle->urid.time_position = handle->map->map(handle->map->handle,
		LV2_TIME__Position);


@@ 375,13 421,17 @@ run(LV2_Handle instance, uint32_t nsamples)
	_advance(handle, last_t, nsamples);

	if(handle->ref)
	{
		lv2_atom_forge_pop(&handle->forge, &frame);
	}
	else
	{
		lv2_atom_sequence_clear(handle->event_out);

		if(handle->log)
		{
			lv2_log_trace(&handle->logger, "forge buffer overflow\n");
		}
	}
}



@@ 423,7 473,9 @@ static const void*
extension_data(const char* uri)
{
	if(!strcmp(uri, LV2_STATE__interface))
	{
		return &state_iface;
	}

	return NULL;
}

M src/orbit_quantum.c => src/orbit_quantum.c +28 -0
@@ 74,9 74,13 @@ _cb(timely_t *timely, int64_t frames, LV2_URID type, void *data)
				const LV2_Atom *atom = &ev->body;

				if(handle->ref)
				{
					handle->ref = lv2_atom_forge_frame_time(&handle->forge, frames);
				}
				if(handle->ref)
				{
					handle->ref = lv2_atom_forge_write(&handle->forge, atom, lv2_atom_total_size(atom));
				}

				varchunk_read_advance(handle->rb);
			}


@@ 92,14 96,20 @@ _cb(timely_t *timely, int64_t frames, LV2_URID type, void *data)
		while( (ev = varchunk_read_request(handle->rb, &size)) )
		{
			if(ev->time.beats > beats)
			{
				break; // event is for next beat
			}

			const LV2_Atom *atom = &ev->body;

			if(handle->ref)
			{
				handle->ref = lv2_atom_forge_frame_time(&handle->forge, frames);
			}
			if(handle->ref)
			{
				handle->ref = lv2_atom_forge_write(&handle->forge, atom, lv2_atom_total_size(atom));
			}

			varchunk_read_advance(handle->rb);
		}


@@ 112,15 122,21 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
{
	plughandle_t *handle = calloc(1, sizeof(plughandle_t));
	if(!handle)
	{
		return NULL;
	}
	mlock(handle, sizeof(plughandle_t));

	for(unsigned i=0; features[i]; i++)
	{
		if(!strcmp(features[i]->URI, LV2_URID__map))
		{
			handle->map = features[i]->data;
		}
		else if(!strcmp(features[i]->URI, LV2_LOG__log))
		{
			handle->log= features[i]->data;
		}
	}

	if(!handle->map)


@@ 131,7 147,9 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
	}

	if(handle->log)
	{
		lv2_log_logger_init(&handle->logger, handle->map, handle->log);
	}

	timely_mask_t mask = TIMELY_MASK_SPEED
		| TIMELY_MASK_BAR_BEAT_WHOLE;


@@ 226,9 244,13 @@ run(LV2_Handle instance, uint32_t nsamples)
			else // !rolling, aka through mode
			{
				if(handle->ref)
				{
					handle->ref = lv2_atom_forge_frame_time(&handle->forge, ev->time.frames);
				}
				if(handle->ref)
				{
					handle->ref = lv2_atom_forge_write(&handle->forge, &obj->atom, lv2_atom_total_size(&obj->atom));
				}
			}
		}



@@ 238,13 260,17 @@ run(LV2_Handle instance, uint32_t nsamples)
	timely_advance(timely, NULL, last_t, nsamples);

	if(handle->ref)
	{
		lv2_atom_forge_pop(&handle->forge, &frame);
	}
	else
	{
		lv2_atom_sequence_clear(handle->event_out);

		if(handle->log)
		{
			lv2_log_trace(&handle->logger, "forge buffer overflow\n");
		}
	}
}



@@ 287,7 313,9 @@ static const void*
extension_data(const char* uri)
{
	if(!strcmp(uri, LV2_STATE__interface))
	{
		return &state_iface;
	}

	return NULL;
}

M src/orbit_subspace.c => src/orbit_subspace.c +52 -0
@@ 71,50 71,86 @@ _position_atomize(plughandle_t *handle, LV2_Atom_Forge *forge, int64_t frames)
	LV2_Atom_Forge_Frame frame;
	LV2_Atom_Forge_Ref ref = lv2_atom_forge_frame_time(forge, frames);
	if(ref)
	{
		ref = lv2_atom_forge_object(forge, &frame, 0, timely->urid.time_position);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, TIMELY_URI_BAR_BEAT(timely));
	}
	if(ref)
	{
		ref = lv2_atom_forge_float(forge, bar_beat);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, TIMELY_URI_BAR(timely));
	}
	if(ref)
	{
		ref = lv2_atom_forge_long(forge, TIMELY_BAR(timely));
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, TIMELY_URI_BEAT_UNIT(timely));
	}
	if(ref)
	{
		ref = lv2_atom_forge_int(forge, beat_unit);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, TIMELY_URI_BEATS_PER_BAR(timely));
	}
	if(ref)
	{
		ref = lv2_atom_forge_float(forge, beats_per_bar);
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, TIMELY_URI_BEATS_PER_MINUTE(timely));
	}
	if(ref)
	{
		ref = lv2_atom_forge_float(forge, TIMELY_BEATS_PER_MINUTE(timely));
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, TIMELY_URI_FRAME(timely));
	}
	if(ref)
	{
		ref = lv2_atom_forge_long(forge, TIMELY_FRAME(timely));
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, TIMELY_URI_FRAMES_PER_SECOND(timely));
	}
	if(ref)
	{
		ref = lv2_atom_forge_float(forge, TIMELY_FRAMES_PER_SECOND(timely));
	}

	if(ref)
	{
		ref = lv2_atom_forge_key(forge, TIMELY_URI_SPEED(timely));
	}
	if(ref)
	{
		ref = lv2_atom_forge_float(forge, TIMELY_SPEED(timely));
	}

	if(ref)
	{
		lv2_atom_forge_pop(forge, &frame);
	}

	return ref;
}


@@ 125,7 161,9 @@ _intercept(void *data, int64_t frames, props_impl_t *impl UNUSED)
	plughandle_t *handle = data;

	if(handle->ref)
	{
		handle->ref = _position_atomize(handle, &handle->forge, frames);
	}
}

static const props_def_t defs [MAX_NPROPS] = {


@@ 156,15 194,21 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
{
	plughandle_t *handle = calloc(1, sizeof(plughandle_t));
	if(!handle)
	{
		return NULL;
	}
	mlock(handle, sizeof(plughandle_t));

	for(unsigned i=0; features[i]; i++)
	{
		if(!strcmp(features[i]->URI, LV2_URID__map))
		{
			handle->map = features[i]->data;
		}
		else if(!strcmp(features[i]->URI, LV2_LOG__log))
		{
			handle->log= features[i]->data;
		}
	}

	if(!handle->map)


@@ 176,7 220,9 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
	}

	if(handle->log)
	{
		lv2_log_logger_init(&handle->logger, handle->map, handle->log);
	}

	const timely_mask_t mask = 0;
	timely_init(&handle->timely, handle->map, rate, mask, _cb, handle);


@@ 245,13 291,17 @@ run(LV2_Handle instance, uint32_t nsamples)
	timely_advance(&handle->timely, NULL, last_t, nsamples);

	if(handle->ref)
	{
		lv2_atom_forge_pop(&handle->forge, &frame);
	}
	else
	{
		lv2_atom_sequence_clear(handle->event_out);

		if(handle->log)
		{
			lv2_log_trace(&handle->logger, "forge buffer overflow\n");
		}
	}
}



@@ 293,7 343,9 @@ static const void*
extension_data(const char* uri)
{
	if(!strcmp(uri, LV2_STATE__interface))
	{
		return &state_iface;
	}

	return NULL;
}

M src/orbit_timecapsule.c => src/orbit_timecapsule.c +77 -0
@@ 213,12 213,18 @@ _record_intercept(void *data, int64_t frames, props_impl_t *impl UNUSED)

	const double beats = handle->offset / TIMELY_FRAMES_PER_BEAT(&handle->timely);
	if(!isfinite(beats))
	{
		return;
	}

	if(handle->state.record)
	{
		_reposition_rec(handle, beats);
	}
	else
	{
		_reposition_play(handle, beats);
	}
}

static void


@@ 230,7 236,9 @@ _path_intercept(void *data, int64_t frames UNUSED, props_impl_t *impl UNUSED)
	const size_t tot_size = sizeof(job_t) + len;
	const double beats = handle->offset / TIMELY_FRAMES_PER_BEAT(&handle->timely);
	if(!isfinite(beats))
	{
		return;
	}

	job_t *job;
	if((job = varchunk_write_request(handle->to_worker, tot_size)))


@@ 298,29 306,41 @@ _play(plughandle_t *handle, int64_t to)
			case TC_JOB_WRITE:
			{
				if(handle->draining)
				{
					break; // ignore while draining
				}

				const int64_t beat_frames = job->beats * TIMELY_FRAMES_PER_BEAT(&handle->timely);

				if(beat_frames >= handle->offset)
				{
					goto skip; // event not part of this period
				}

				int64_t frames = beat_frames - rel;
				if(frames < 0)
				{
					frames = 0; //FIXME
				}

				//printf("%li %u\n", frames, job->atom->size);

				if(handle->ref)
				{
					handle->ref = lv2_atom_forge_frame_time(&handle->forge, frames);
				}
				if(handle->ref)
				{
					handle->ref = lv2_atom_forge_write(&handle->forge, job->atom, lv2_atom_total_size(job->atom));
				}
			} break;

			case TC_JOB_DRAIN:
			{
				if(handle->draining)
				{
					handle->draining = false;
				}
			} break;

			case TC_JOB_CHANGE_PATH:


@@ 341,7 361,9 @@ skip:
	}

	if(consumed)
	{
		_request_read(handle);
	}
}

static inline void


@@ 381,14 403,20 @@ _cb(timely_t *timely, int64_t frames UNUSED, LV2_URID type, void *data)
		const double beats = (double)TIMELY_BAR(timely) * TIMELY_BEATS_PER_BAR(timely)
			+ TIMELY_BAR_BEAT(timely);
		if(!isfinite(beats))
		{
			return;
		}

		handle->offset = beats * TIMELY_FRAMES_PER_BEAT(timely);

		if(handle->state.record)
		{
			_reposition_rec(handle, beats);
		}
		else
		{
			_reposition_play(handle, beats);
		}
	}
}



@@ 422,9 450,13 @@ _read_header(plughandle_t *handle, double *beats, uint32_t *size)
	itm.size = be32toh(itm.size);

	if(beats)
	{
		*beats = itm.beats.d;
	}
	if(size)
	{
		*size = itm.size;
	}

	return 0;
}


@@ 502,7 534,9 @@ _write_to(plughandle_t *handle, double beats, const LV2_Atom *atom)
{
	//printf("_write\n");
	if(!handle->gzfile)
	{
		return -1;
	}

	memcpy(handle->buf, atom, lv2_atom_total_size(atom));



@@ 542,12 576,16 @@ _read_from(plughandle_t *handle)
{
	//printf("_read\n");
	if(!handle->gzfile)
	{
		return -1;
	}

	double beats;
	uint32_t tx_size;
	if(_read_header(handle, &beats, &tx_size) != 0)
	{
		return -1;
	}

	job_t *job;
	const uint32_t tot_size = sizeof(job_t) + tx_size;


@@ 595,19 633,29 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
{
	plughandle_t *handle = calloc(1, sizeof(plughandle_t));
	if(!handle)
	{
		return NULL;
	}
	mlock(handle, sizeof(plughandle_t));

	for(unsigned i=0; features[i]; i++)
	{
		if(!strcmp(features[i]->URI, LV2_URID__map))
		{
			handle->map = features[i]->data;
		}
		else if(!strcmp(features[i]->URI, LV2_URID__unmap))
		{
			handle->unmap = features[i]->data;
		}
		else if(!strcmp(features[i]->URI, LV2_WORKER__schedule))
		{
			handle->sched = features[i]->data;
		}
		else if(!strcmp(features[i]->URI, LV2_LOG__log))
		{
			handle->log= features[i]->data;
		}
	}

	if(!handle->map)


@@ 635,7 683,9 @@ instantiate(const LV2_Descriptor* descriptor, double rate,
	}

	if(handle->log)
	{
		lv2_log_logger_init(&handle->logger, handle->map, handle->log);
	}

	handle->netatom = netatom_new(handle->map, handle->unmap, true);
	if(!handle->netatom)


@@ 727,39 777,55 @@ run(LV2_Handle instance, uint32_t nsamples)
	LV2_ATOM_SEQUENCE_FOREACH(handle->event_in, ev)
	{
		if(handle->rolling)
		{
			handle->offset += ev->time.frames - last_t;
		}

		const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
		int handled = timely_advance(&handle->timely, obj, last_t, ev->time.frames);
		if(!handled)
		{
			handled = props_advance(&handle->props, &handle->forge, ev->time.frames, obj, &handle->ref);
		}

		if(handle->rolling)
		{
			if(!handled && handle->state.record)
			{
				_rec(handle, ev); // dont' record time position signals and patch messages
			}
		
			if(!handle->state.record && !handle->state.mute)
			{
				_play(handle, ev->time.frames);
			}
		}

		last_t = ev->time.frames;
	}

	if(handle->rolling)
	{
		handle->offset += nsamples - last_t;
	}
	timely_advance(&handle->timely, NULL, last_t, nsamples);
	if(handle->rolling && !handle->state.record && !handle->state.mute)
	{
		_play(handle, nsamples);
	}

	if(handle->ref)
	{
		lv2_atom_forge_pop(&handle->forge, &frame);
	}
	else
	{
		lv2_atom_sequence_clear(handle->event_out);

		if(handle->log)
		{
			lv2_log_trace(&handle->logger, "%s: forge buffer overflow\n", __func__);
		}
	}
}



@@ 771,13 837,19 @@ cleanup(LV2_Handle instance)
	_close_disk(handle);

	if(handle->to_dsp)
	{
		varchunk_free(handle->to_dsp);
	}

	if(handle->to_worker)
	{
		varchunk_free(handle->to_worker);
	}

	if(handle->netatom)
	{
		netatom_free(handle->netatom);
	}

	munlock(handle, sizeof(plughandle_t));
	free(handle);


@@ 910,9 982,14 @@ static const void *
extension_data(const char *uri)
{
	if(!strcmp(uri, LV2_STATE__interface))
	{
		return &state_iface;
	}
	else if(!strcmp(uri, LV2_WORKER__interface))
	{
		return &work_iface;
	}

	return NULL;
}