Ejemplo n.º 1
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);
}
Ejemplo n.º 2
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);
	}
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
void
AtomWriter::response(int32_t id, Status status, const std::string& subject)
{
	if (!id) {
		return;
	}

	LV2_Atom_Forge_Frame msg;
	forge_request(&msg, _uris.patch_Response);
	lv2_atom_forge_key(&_forge, _uris.patch_request);
	lv2_atom_forge_int(&_forge, id);
	if (!subject.empty() && Raul::URI::is_valid(subject)) {
		lv2_atom_forge_key(&_forge, _uris.patch_subject);
		lv2_atom_forge_uri(&_forge, subject.c_str(), subject.length());
	}
	lv2_atom_forge_key(&_forge, _uris.patch_body);
	lv2_atom_forge_int(&_forge, static_cast<int>(status));
	lv2_atom_forge_pop(&_forge, &msg);
	finish_msg();
}
Ejemplo n.º 5
0
/** forge atom-vector of raw data */
static void tx_rawaudio(LV2_Atom_Forge *forge, ScoLV2URIs *uris,
    const int32_t channel, const size_t n_samples, void *data)
{
  LV2_Atom_Forge_Frame frame;
  /* forge container object of type 'rawaudio' */
  lv2_atom_forge_frame_time(forge, 0);
  x_forge_object(forge, &frame, 1, uris->rawaudio);

  /* add integer attribute 'channelid' */
  lv2_atom_forge_property_head(forge, uris->channelid, 0);
  lv2_atom_forge_int(forge, channel);

  /* add vector of floats raw 'audiodata' */
  lv2_atom_forge_property_head(forge, uris->audiodata, 0);
  lv2_atom_forge_vector(forge, sizeof(float), uris->atom_Float, n_samples, data);

  /* close off atom-object */
  lv2_atom_forge_pop(forge, &frame);
}
Ejemplo n.º 6
0
/**
   Write the patch get message
*/
static LV2_Atom *write_patch_get(LV2_Atom_Forge *forge, Fluid_URIs *uris)
{
    LV2_Atom_Forge_Frame get_frame;
    LV2_Atom_Forge_Frame body_frame;

    LV2_Atom_Forge_Ref ref = lv2_atom_forge_blank(forge, &get_frame, 1,
                                                  uris->patch_get);

    lv2_atom_forge_property_head(forge, uris->patch_body, 0);
    lv2_atom_forge_blank(forge, &body_frame, 2, 0);

    lv2_atom_forge_property_head(forge, uris->patch_subject, 0);
    lv2_atom_forge_int(forge, uris->fluid_preset);

    lv2_atom_forge_pop(forge, &body_frame);
    lv2_atom_forge_pop(forge, &get_frame);

    return lv2_atom_forge_deref(forge, ref);
}
Ejemplo n.º 7
0
Archivo: lv2.c Proyecto: aelse/setBfree
static void pgm_cb(int num, int pc, const char *name, void *arg) {
  B3S* b3s = (B3S*)arg;
  char tmp[256];
  int pco = pc - b3s->inst->progs->MIDIControllerPgmOffset;
#ifdef DEBUGPRINT
      fprintf(stderr, "PGM CB %d %d %s\n",num, pc, name);
#endif
  LV2_Atom_Forge_Frame frame;
  lv2_atom_forge_frame_time(&b3s->forge, 0);
  x_forge_object(&b3s->forge, &frame, 1, b3s->uris.sb3_midipgm);

  lv2_atom_forge_property_head(&b3s->forge, b3s->uris.sb3_cckey, 0);
  lv2_atom_forge_int(&b3s->forge, pco);
  lv2_atom_forge_property_head(&b3s->forge, b3s->uris.sb3_ccval, 0);
  lv2_atom_forge_string(&b3s->forge, name, strlen(name));

  formatProgram(&b3s->inst->progs->programmes[pc], tmp, 256);
  lv2_atom_forge_property_head(&b3s->forge, b3s->uris.sb3_ccdsc, 0);
  lv2_atom_forge_string(&b3s->forge, tmp, strlen(tmp));

  lv2_atom_forge_pop(&b3s->forge, &frame);
}
Ejemplo n.º 8
0
static void
run(LV2_Handle handle, uint32_t n_samples)
{
  SiSco* self = (SiSco*)handle;
  const uint32_t size = (sizeof(float) * n_samples + 80) * self->n_channels;
  const uint32_t capacity = self->notify->atom.size;
  bool capacity_ok = true;

  /* check if atom-port buffer is large enough to hold
   * all audio-samples and configuration settings */
  if (capacity < size + 216 + self->n_channels * 16) {
    capacity_ok = false;
    if (!self->printed_capacity_warning) {
      fprintf(stderr, "SiSco.lv2 error: LV2 comm-buffersize is insufficient %d/%d bytes.\n",
	  capacity, size + 216 + self->n_channels * 16);
      self->printed_capacity_warning = true;
    }
  }

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

  /* Send settings to UI */
  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);
    x_forge_object(&self->forge, &frame, 1, self->uris.ui_state);
    /* forge attributes for 'ui_state' */
    lv2_atom_forge_property_head(&self->forge, self->uris.samplerate, 0);
    lv2_atom_forge_float(&self->forge, capacity_ok ? self->rate : 0);

    lv2_atom_forge_property_head(&self->forge, self->uris.ui_state_grid, 0);
    lv2_atom_forge_int(&self->forge, self->ui_grid);

    lv2_atom_forge_property_head(&self->forge, self->uris.ui_state_trig, 0);
    lv2_atom_forge_vector(&self->forge, sizeof(float), self->uris.atom_Float,
	sizeof(struct triggerstate) / sizeof(float), &self->triggerstate);

    lv2_atom_forge_property_head(&self->forge, self->uris.ui_state_curs, 0);
    lv2_atom_forge_vector(&self->forge, sizeof(int32_t), self->uris.atom_Int,
	sizeof(struct cursorstate) / sizeof(int32_t), &self->cursorstate);

    lv2_atom_forge_property_head(&self->forge, self->uris.ui_state_chn, 0);
    lv2_atom_forge_vector(&self->forge, sizeof(float), self->uris.atom_Float,
	self->n_channels * sizeof(struct channelstate) / sizeof(float), self->channelstate);

    lv2_atom_forge_property_head(&self->forge, self->uris.ui_state_misc, 0);
    lv2_atom_forge_int(&self->forge, self->ui_misc);

    /* close-off frame */
    lv2_atom_forge_pop(&self->forge, &frame);
  }

  /* Process incoming events from GUI */
  if (self->control) {
    LV2_Atom_Event* ev = lv2_atom_sequence_begin(&(self->control)->body);
    /* for each message from UI... */
    while(!lv2_atom_sequence_is_end(&(self->control)->body, (self->control)->atom.size, ev)) {
      /* .. only look at atom-events.. */
      if (ev->body.type == self->uris.atom_Blank || ev->body.type == self->uris.atom_Object) {
	const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
	/* interpret atom-objects: */
	if (obj->body.otype == self->uris.ui_on) {
	  /* UI was activated */
	  self->ui_active = true;
	  self->send_settings_to_ui = true;
	} else if (obj->body.otype == self->uris.ui_off) {
	  /* UI was closed */
	  self->ui_active = false;
	} else if (obj->body.otype == self->uris.ui_state) {
	  /* UI sends current settings */
	  const LV2_Atom* grid = NULL;
	  const LV2_Atom* trig = NULL;
	  const LV2_Atom* curs = NULL;
	  const LV2_Atom* misc = NULL;
	  const LV2_Atom* chn = NULL;
	  lv2_atom_object_get(obj,
	      self->uris.ui_state_grid, &grid,
	      self->uris.ui_state_trig, &trig,
	      self->uris.ui_state_curs, &curs,
	      self->uris.ui_state_misc, &misc,
	      self->uris.ui_state_chn, &chn,
	      0);
	  if (grid && grid->type == self->uris.atom_Int) {
	    self->ui_grid = ((LV2_Atom_Int*)grid)->body;
	  }
	  if (misc && misc->type == self->uris.atom_Int) {
	    self->ui_misc = ((LV2_Atom_Int*)misc)->body;
	  }
	  if (trig && trig->type == self->uris.atom_Vector) {
	    LV2_Atom_Vector *vof = (LV2_Atom_Vector*)LV2_ATOM_BODY(trig);
	    if (vof->atom.type == self->uris.atom_Float) {
	      struct triggerstate *ts = (struct triggerstate *) LV2_ATOM_BODY(&vof->atom);
	      memcpy(&self->triggerstate, ts, sizeof(struct triggerstate));
	    }
	  }
	  if (curs && curs->type == self->uris.atom_Vector) {
	    LV2_Atom_Vector *vof = (LV2_Atom_Vector*)LV2_ATOM_BODY(curs);
	    if (vof->atom.type == self->uris.atom_Int) {
	      struct cursorstate *cs = (struct cursorstate *) LV2_ATOM_BODY(&vof->atom);
	      memcpy(&self->cursorstate, cs, sizeof(struct cursorstate));
	    }
	  }
	  if (chn && chn->type == self->uris.atom_Vector) {
	    LV2_Atom_Vector *vof = (LV2_Atom_Vector*)LV2_ATOM_BODY(chn);
	    if (vof->atom.type == self->uris.atom_Float) {
	      struct channelstate *cs = (struct channelstate *) LV2_ATOM_BODY(&vof->atom);
	      memcpy(self->channelstate, cs, self->n_channels * sizeof(struct channelstate));
	    }
	  }
	}
      }
      ev = lv2_atom_sequence_next(ev);
    }
  }

  /* process audio data */
  for (uint32_t c = 0; c < self->n_channels; ++c) {
    if (self->ui_active && capacity_ok) {
      /* 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 in-place, forward audio */
    if (self->input[c] != self->output[c]) {
      memcpy(self->output[c], self->input[c], sizeof(float) * n_samples);
    }
  }

  /* close off atom-sequence */
  lv2_atom_forge_pop(&self->forge, &self->frame);
}
Ejemplo n.º 9
0
 /** Forge an integeger value
     @param val The value to write
  */
 inline ForgeRef
 write_int (const int val)
 {
     return lv2_atom_forge_int (this, val);
 }
Ejemplo n.º 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);
}
Ejemplo n.º 11
0
static void
bim_run(LV2_Handle instance, uint32_t n_samples)
{
	LV2meter* self = (LV2meter*)instance;

	const uint32_t capacity = self->notify->atom.size;
	assert(capacity > 920);
	lv2_atom_forge_set_buffer(&self->forge, (uint8_t*)self->notify, capacity);
	lv2_atom_forge_sequence_head(&self->forge, &self->frame, 0);

	if (self->send_state_to_ui && self->ui_active) {
		self->send_state_to_ui = false;
		forge_kvcontrolmessage(&self->forge, &self->uris, self->uris.mtr_control, CTL_SAMPLERATE, self->rate);
	}

	/* Process incoming events from GUI */
	if (self->control) {
		LV2_Atom_Event* ev = lv2_atom_sequence_begin(&(self->control)->body);
		while(!lv2_atom_sequence_is_end(&(self->control)->body, (self->control)->atom.size, ev)) {
			if (ev->body.type == self->uris.atom_Blank || ev->body.type == self->uris.atom_Object) {
				const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
				if (obj->body.otype == self->uris.mtr_meters_on) {
					self->ui_active = true;
					self->send_state_to_ui = true;
				}
				else if (obj->body.otype == self->uris.mtr_meters_off) {
					self->ui_active = false;
				}
				else if (obj->body.otype == self->uris.mtr_meters_cfg) {
					int k; float v;
					get_cc_key_value(&self->uris, obj, &k, &v);
					switch (k) {
						case CTL_START:
							self->ebu_integrating = true;
							break;
						case CTL_PAUSE:
							self->ebu_integrating = false;
							break;
						case CTL_RESET:
							bim_reset(self);
							self->send_state_to_ui = true;
							break;
						case CTL_AVERAGE:
							self->bim_average = true;
							break;
						case CTL_WINDOWED:
							self->bim_average = false;
							break;
						default:
							break;
					}
				}
			}
			ev = lv2_atom_sequence_next(ev);
		}
	}
#if 0
	static uint32_t max_post = 0;
	if (self->notify->atom.size > max_post) {
		max_post = self->notify->atom.size;
		printf("new post parse: %d\n", max_post);
	}
#endif


	/* process */

	if (self->ebu_integrating && self->integration_time < 2147483647) {
		/* currently 'self->histS' is int32,
		 * the max peak that can be recorded is 2^31,
		 * for now we simply limit data-acquisition to at
		 * most 2^31 points.
		 */
		if (self->integration_time > 2147483647 - n_samples) {
			self->integration_time = 2147483647;
		} else {
			for (uint32_t s = 0; s < n_samples; ++s) {
				float_stats(self, self->input[0] + s);
			}
			self->integration_time += n_samples;
		}
	}

	const int fps_limit = n_samples * ceil(self->rate / (5.f * n_samples)); // ~ 5fps
	self->radar_resync += n_samples;

	if (self->radar_resync >= fps_limit || self->send_state_to_ui) {
		self->radar_resync = self->radar_resync % fps_limit;

		if (self->ui_active && (self->ebu_integrating || self->send_state_to_ui)) {
			LV2_Atom_Forge_Frame frame;
			lv2_atom_forge_frame_time(&self->forge, 0);
			x_forge_object(&self->forge, &frame, 1, self->uris.bim_stats);

			lv2_atom_forge_property_head(&self->forge, self->uris.ebu_integr_time, 0);
			lv2_atom_forge_long(&self->forge, self->integration_time);

			lv2_atom_forge_property_head(&self->forge, self->uris.bim_zero, 0);
			lv2_atom_forge_int(&self->forge, self->bim_zero);
			lv2_atom_forge_property_head(&self->forge, self->uris.bim_pos, 0);
			lv2_atom_forge_int(&self->forge, self->bim_pos);

			lv2_atom_forge_property_head(&self->forge, self->uris.bim_max, 0);
			lv2_atom_forge_double(&self->forge, self->bim_max);
			lv2_atom_forge_property_head(&self->forge, self->uris.bim_min, 0);
			lv2_atom_forge_double(&self->forge, self->bim_min);
			lv2_atom_forge_property_head(&self->forge, self->uris.bim_nan, 0);
			lv2_atom_forge_int(&self->forge, self->bim_nan);
			lv2_atom_forge_property_head(&self->forge, self->uris.bim_inf, 0);
			lv2_atom_forge_int(&self->forge, self->bim_inf);
			lv2_atom_forge_property_head(&self->forge, self->uris.bim_den, 0);
			lv2_atom_forge_int(&self->forge, self->bim_den);

			lv2_atom_forge_property_head(&self->forge, self->uris.bim_data, 0);
			lv2_atom_forge_vector(&self->forge, sizeof(int32_t), self->uris.atom_Int, BIM_LAST, self->histS);
			lv2_atom_forge_pop(&self->forge, &frame);
		}

		if (self->ui_active) {
			LV2_Atom_Forge_Frame frame;
			lv2_atom_forge_frame_time(&self->forge, 0);
			x_forge_object(&self->forge, &frame, 1, self->uris.bim_information);
			lv2_atom_forge_property_head(&self->forge, self->uris.ebu_integrating, 0);
			lv2_atom_forge_bool(&self->forge, self->ebu_integrating);
			lv2_atom_forge_property_head(&self->forge, self->uris.bim_averaging, 0);
			lv2_atom_forge_bool(&self->forge, self->bim_average);
			lv2_atom_forge_pop(&self->forge, &frame);
		}

		if (!self->bim_average) {
			bim_clear (self);
		}
	}

	/* foward audio-data */
	if (self->input[0] != self->output[0]) {
		memcpy(self->output[0], self->input[0], sizeof(float) * n_samples);
	}

#if 0
	//printf("forged %d bytes\n", self->notify->atom.size);
	static uint32_t max_cap = 0;
	if (self->notify->atom.size > max_cap) {
		max_cap = self->notify->atom.size;
		printf("new max: %d (of %d avail)\n", max_cap, capacity);
	}
#endif
}