Пример #1
0
void
AtomWriter::delta(const Raul::URI&            uri,
                  const Resource::Properties& remove,
                  const Resource::Properties& add)
{
	LV2_Atom_Forge_Frame msg;
	forge_request(&msg, _uris.patch_Patch);
	lv2_atom_forge_key(&_forge, _uris.patch_subject);
	forge_uri(uri);

	lv2_atom_forge_key(&_forge, _uris.patch_remove);
	LV2_Atom_Forge_Frame remove_obj;
	lv2_atom_forge_object(&_forge, &remove_obj, 0, 0);
	forge_properties(remove);
	lv2_atom_forge_pop(&_forge, &remove_obj);

	lv2_atom_forge_key(&_forge, _uris.patch_add);
	LV2_Atom_Forge_Frame add_obj;
	lv2_atom_forge_object(&_forge, &add_obj, 0, 0);
	forge_properties(add);
	lv2_atom_forge_pop(&_forge, &add_obj);

	lv2_atom_forge_pop(&_forge, &msg);
	finish_msg();
}
Пример #2
0
/**
   ==== Utility Function: `tx_rawaudio` ====

   This function forges a message for sending a vector of raw data.  The object
   is a http://lv2plug.in/ns/ext/atom#Blank[Blank] with a few properties, like:
   [source,n3]
   --------
   []
   	a sco:RawAudio ;
   	sco:channelID 0 ;
   	sco:audioData [ 0.0, 0.0, ... ] .
   --------

   where the value of the `sco:audioData` property, `[ 0.0, 0.0, ... ]`, is a
   http://lv2plug.in/ns/ext/atom#Vector[Vector] of
   http://lv2plug.in/ns/ext/atom#Float[Float].
*/
static void
tx_rawaudio(LV2_Atom_Forge* forge,
            ScoLV2URIs*     uris,
            const int32_t   channel,
            const size_t    n_samples,
            const float*    data)
{
	LV2_Atom_Forge_Frame frame;

	// Forge container object of type 'RawAudio'
	lv2_atom_forge_frame_time(forge, 0);
	lv2_atom_forge_object(forge, &frame, 0, uris->RawAudio);

	// Add integer 'channelID' property
	lv2_atom_forge_key(forge, uris->channelID);
	lv2_atom_forge_int(forge, channel);

	// Add vector of floats 'audioData' property
	lv2_atom_forge_key(forge, uris->audioData);
	lv2_atom_forge_vector(
		forge, sizeof(float), uris->atom_Float, n_samples, data);

	// Close off object
	lv2_atom_forge_pop(forge, &frame);
}
Пример #3
0
void
AtomWriter::forge_request(LV2_Atom_Forge_Frame* frame, LV2_URID type)
{
	lv2_atom_forge_object(&_forge, frame, 0, type);

	if (_id) {
		lv2_atom_forge_key(&_forge, _uris.patch_sequenceNumber);
		lv2_atom_forge_int(&_forge, _id);
	}
}
Пример #4
0
static LV2_Atom_Forge_Ref
_trans_event(prog_t *prog,  LV2_Atom_Forge *forge, int rolling, jack_position_t *pos)
{
	LV2_Atom_Forge_Frame frame;

	LV2_Atom_Forge_Ref ref = lv2_atom_forge_frame_time(forge, 0);
	if(ref)
		ref = lv2_atom_forge_object(forge, &frame, 0, prog->time_position);
	{
		if(ref)
			ref = lv2_atom_forge_key(forge, prog->time_frame);
		if(ref)
			ref = lv2_atom_forge_long(forge, pos->frame);

		if(ref)
			ref = lv2_atom_forge_key(forge, prog->time_speed);
		if(ref)
			ref = lv2_atom_forge_float(forge, rolling ? 1.0 : 0.0);

		if(pos->valid & JackPositionBBT)
		{
			float bar_beat = pos->beat - 1 + (pos->tick / pos->ticks_per_beat);
			float bar = pos->bar - 1;

			if(ref)
				ref = lv2_atom_forge_key(forge, prog->time_barBeat);
			if(ref)
				ref = lv2_atom_forge_float(forge, bar_beat);

			if(ref)
				ref = lv2_atom_forge_key(forge, prog->time_bar);
			if(ref)
				ref = lv2_atom_forge_long(forge, bar);

			if(ref)
				ref = lv2_atom_forge_key(forge, prog->time_beatUnit);
			if(ref)
				ref = lv2_atom_forge_int(forge, pos->beat_type);

			if(ref)
				ref = lv2_atom_forge_key(forge, prog->time_beatsPerBar);
			if(ref)
				ref = lv2_atom_forge_float(forge, pos->beats_per_bar);

			if(ref)
				ref = lv2_atom_forge_key(forge, prog->time_beatsPerMinute);
			if(ref)
				ref = lv2_atom_forge_float(forge, pos->beats_per_minute);
		}
	}
	if(ref)
		lv2_atom_forge_pop(forge, &frame);

	return ref;
}
Пример #5
0
void
AtomWriter::forge_arc(const Raul::Path& tail, const Raul::Path& head)
{
	LV2_Atom_Forge_Frame arc;
	lv2_atom_forge_object(&_forge, &arc, 0, _uris.ingen_Arc);
	lv2_atom_forge_key(&_forge, _uris.ingen_tail);
	forge_uri(Node::path_to_uri(tail));
	lv2_atom_forge_key(&_forge, _uris.ingen_head);
	forge_uri(Node::path_to_uri(head));
	lv2_atom_forge_pop(&_forge, &arc);
}
Пример #6
0
/** generate a file path message,
 * send current state to GUI
 */
static void inform_ui (MidiMap* self)
{
	if (!self->cfg_file_path) { return; }
	const MidiMapURIs* uris = &self->uris;

	lv2_atom_forge_frame_time (&self->forge, 0);
	LV2_Atom_Forge_Frame frame;
	lv2_atom_forge_object (&self->forge, &frame, 1, uris->patch_Set);
	lv2_atom_forge_property_head (&self->forge, uris->patch_property, 0);
	lv2_atom_forge_urid (&self->forge, uris->mem_cfgfile);
	lv2_atom_forge_property_head (&self->forge, uris->patch_value, 0);
	lv2_atom_forge_path (&self->forge, self->cfg_file_path, strlen (self->cfg_file_path));

	lv2_atom_forge_pop (&self->forge, &frame);
}
Пример #7
0
void
AtomWriter::put(const Raul::URI&            uri,
                const Resource::Properties& properties,
                Resource::Graph             ctx)
{
	LV2_Atom_Forge_Frame msg;
	forge_request(&msg, _uris.patch_Put);
	lv2_atom_forge_key(&_forge, _uris.patch_subject);
	forge_uri(uri);
	lv2_atom_forge_key(&_forge, _uris.patch_body);

	LV2_Atom_Forge_Frame body;
	lv2_atom_forge_object(&_forge, &body, 0, 0);
	forge_properties(properties);
	lv2_atom_forge_pop(&_forge, &body);

	lv2_atom_forge_pop(&_forge, &msg);
	finish_msg();
}
Пример #8
0
void
AtomWriter::disconnect_all(const Raul::Path& graph,
                           const Raul::Path& path)
{
	LV2_Atom_Forge_Frame msg;
	forge_request(&msg, _uris.patch_Delete);

	lv2_atom_forge_key(&_forge, _uris.patch_subject);
	forge_uri(Node::path_to_uri(graph));

	lv2_atom_forge_key(&_forge, _uris.patch_body);
	LV2_Atom_Forge_Frame arc;
	lv2_atom_forge_object(&_forge, &arc, 0, _uris.ingen_Arc);
	lv2_atom_forge_key(&_forge, _uris.ingen_incidentTo);
	forge_uri(Node::path_to_uri(path));
	lv2_atom_forge_pop(&_forge, &arc);

	lv2_atom_forge_pop(&_forge, &msg);
	finish_msg();
}
Пример #9
0
 /** Forge a blank object
     @param frame
     @param id
     @param otype
  */
 inline ForgeRef
 write_blank (ForgeFrame& frame, uint32_t id, uint32_t otype)
 {
     return lv2_atom_forge_object (this, &frame, id, otype);
 }
Пример #10
0
/** ==== Run Method ==== */
static void
run(LV2_Handle handle, uint32_t n_samples)
{
	EgScope* self = (EgScope*)handle;

	/* Ensure notify port buffer is large enough to hold all audio-samples and
	   configuration settings.  A minimum size was requested in the .ttl file,
	   but check here just to be sure.

	   TODO: Explain these magic numbers.
	*/
	const size_t   size  = (sizeof(float) * n_samples + 64) * self->n_channels;
	const uint32_t space = self->notify->atom.size;
	if (space < size + 128) {
		/* Insufficient space, report error and do nothing.  Note that a
		   real-time production plugin mustn't call log functions in run(), but
		   this can be useful for debugging and example purposes.
		*/
		lv2_log_error(&self->logger, "Buffer size is insufficient\n");
		return;
	}

	// Prepare forge buffer and initialize atom-sequence
	lv2_atom_forge_set_buffer(&self->forge, (uint8_t*)self->notify, space);
	lv2_atom_forge_sequence_head(&self->forge, &self->frame, 0);

	/* Send settings to UI

	   The plugin can continue to run while the UI is closed and re-opened.
	   The state and settings of the UI are kept here and transmitted to the UI
	   every time it asks for them or if the user initializes a 'load preset'.
	*/
	if (self->send_settings_to_ui && self->ui_active) {
		self->send_settings_to_ui = false;
		// Forge container object of type 'ui_state'
		LV2_Atom_Forge_Frame frame;
		lv2_atom_forge_frame_time(&self->forge, 0);
		lv2_atom_forge_object(&self->forge, &frame, 0, self->uris.ui_State);

		// Add UI state as properties
		lv2_atom_forge_key(&self->forge, self->uris.ui_spp);
		lv2_atom_forge_int(&self->forge, self->ui_spp);
		lv2_atom_forge_key(&self->forge, self->uris.ui_amp);
		lv2_atom_forge_float(&self->forge, self->ui_amp);
		lv2_atom_forge_key(&self->forge, self->uris.param_sampleRate);
		lv2_atom_forge_float(&self->forge, self->rate);
		lv2_atom_forge_pop(&self->forge, &frame);
	}

	// Process incoming events from GUI
	if (self->control) {
		const LV2_Atom_Event* ev = lv2_atom_sequence_begin(
			&(self->control)->body);
		// For each incoming message...
		while (!lv2_atom_sequence_is_end(
			       &self->control->body, self->control->atom.size, ev)) {
			// If the event is an atom:Blank object
			if (ev->body.type == self->uris.atom_Blank) {
				const LV2_Atom_Object* obj = (const LV2_Atom_Object*)&ev->body;
				if (obj->body.otype == self->uris.ui_On) {
					// If the object is a ui-on, the UI was activated
					self->ui_active           = true;
					self->send_settings_to_ui = true;
				} else if (obj->body.otype == self->uris.ui_Off) {
					// If the object is a ui-off, the UI was closed
					self->ui_active = false;
				} else if (obj->body.otype == self->uris.ui_State) {
					// If the object is a ui-state, it's the current UI settings
					const LV2_Atom* spp = NULL;
					const LV2_Atom* amp = NULL;
					lv2_atom_object_get(obj, self->uris.ui_spp, &spp,
					                    self->uris.ui_amp, &amp,
					                    0);
					if (spp) {
						self->ui_spp = ((const LV2_Atom_Int*)spp)->body;
					}
					if (amp) {
						self->ui_amp = ((const LV2_Atom_Float*)amp)->body;
					}
				}
			}
			ev = lv2_atom_sequence_next(ev);
		}
	}

	// Process audio data
	for (uint32_t c = 0; c < self->n_channels; ++c) {
		if (self->ui_active) {
			// If UI is active, send raw audio data to UI
			tx_rawaudio(&self->forge, &self->uris, c, n_samples, self->input[c]);
		}
		// If not processing audio in-place, forward audio
		if (self->input[c] != self->output[c]) {
			memcpy(self->output[c], self->input[c], sizeof(float) * n_samples);
		}
	}

	// Close off sequence
	lv2_atom_forge_pop(&self->forge, &self->frame);
}