diff options
Diffstat (limited to 'lv2')
| -rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/atom-test.c | 39 | ||||
| -rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/atom.h | 128 | ||||
| -rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/atom.ttl | 40 | ||||
| -rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/forge.h | 122 | ||||
| -rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/manifest.ttl | 2 | ||||
| -rw-r--r-- | lv2/lv2plug.in/ns/ext/atom/util.h | 82 | 
6 files changed, 239 insertions, 174 deletions
| diff --git a/lv2/lv2plug.in/ns/ext/atom/atom-test.c b/lv2/lv2plug.in/ns/ext/atom/atom-test.c index 8e56c79..7e90c15 100644 --- a/lv2/lv2plug.in/ns/ext/atom/atom-test.c +++ b/lv2/lv2plug.in/ns/ext/atom/atom-test.c @@ -94,43 +94,43 @@ main()  	// eg_one = (Int32)1  	lv2_atom_forge_property_head(&forge, eg_one, 0);  	LV2_Atom_Int32* one = lv2_atom_forge_int32(&forge, 1); -	if (one->value != 1) { -		return test_fail("%d != 1\n", one->value); +	if (one->body != 1) { +		return test_fail("%d != 1\n", one->body);  	}  	// eg_two = (Int64)2  	lv2_atom_forge_property_head(&forge, eg_two, 0);  	LV2_Atom_Int64* two = lv2_atom_forge_int64(&forge, 2); -	if (two->value != 2) { -		return test_fail("%ld != 2\n", two->value); +	if (two->body != 2) { +		return test_fail("%ld != 2\n", two->body);  	}  	// eg_three = (Float)3.0  	lv2_atom_forge_property_head(&forge, eg_three, 0);  	LV2_Atom_Float* three = lv2_atom_forge_float(&forge, 3.0f); -	if (three->value != 3) { -		return test_fail("%f != 3\n", three->value); +	if (three->body != 3) { +		return test_fail("%f != 3\n", three->body);  	}  	// eg_four = (Double)4.0  	lv2_atom_forge_property_head(&forge, eg_four, 0);  	LV2_Atom_Double* four = lv2_atom_forge_double(&forge, 4.0); -	if (four->value != 4) { -		return test_fail("%ld != 4\n", four->value); +	if (four->body != 4) { +		return test_fail("%ld != 4\n", four->body);  	}  	// eg_true = (Bool)1  	lv2_atom_forge_property_head(&forge, eg_true, 0);  	LV2_Atom_Bool* t = lv2_atom_forge_bool(&forge, true); -	if (t->value != 1) { -		return test_fail("%ld != 1 (true)\n", t->value); +	if (t->body != 1) { +		return test_fail("%ld != 1 (true)\n", t->body);  	}  	// eg_false = (Bool)0  	lv2_atom_forge_property_head(&forge, eg_false, 0);  	LV2_Atom_Bool* f = lv2_atom_forge_bool(&forge, false); -	if (f->value != 0) { -		return test_fail("%ld != 0 (false)\n", f->value); +	if (f->body != 0) { +		return test_fail("%ld != 0 (false)\n", f->body);  	}  	// eg_path = (Path)"/foo/bar" @@ -159,8 +159,8 @@ main()  	LV2_URID eg_value = urid_map(NULL, "http://example.org/value");  	lv2_atom_forge_property_head(&forge, eg_urid, 0);  	LV2_Atom_URID* urid = lv2_atom_forge_urid(&forge, eg_value); -	if (urid->id != eg_value) { -		return test_fail("%u != %u\n", urid->id, eg_value); +	if (urid->body != eg_value) { +		return test_fail("%u != %u\n", urid->body, eg_value);  	}  	// eg_string = (String)"hello" @@ -226,9 +226,9 @@ main()  	lv2_atom_forge_property_head(&forge, eg_seq, 0);  	LV2_Atom_Forge_Frame seq_frame;  	LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)lv2_atom_forge_sequence_head(&forge, &seq_frame, 0); -	lv2_atom_forge_audio_time(&forge, 0, 0); +	lv2_atom_forge_frame_time(&forge, 0);  	lv2_atom_forge_int32(&forge, 1); -	lv2_atom_forge_audio_time(&forge, 1, 0); +	lv2_atom_forge_frame_time(&forge, 1);  	lv2_atom_forge_int32(&forge, 2);  	lv2_atom_forge_pop(&forge, &seq_frame); @@ -240,17 +240,18 @@ main()  		return test_fail("1 == 2.0\n");  	} else if (lv2_atom_equals((LV2_Atom*)one, (LV2_Atom*)&itwo)) {  		return test_fail("1 == 2\n"); +	} else if (!lv2_atom_equals((LV2_Atom*)one, (LV2_Atom*)one)) { +		return test_fail("1 != 1\n");  	}  	unsigned n_events = 0;  	LV2_SEQUENCE_FOREACH(seq, i) {  		LV2_Atom_Event* ev = lv2_sequence_iter_get(i); -		if (ev->time.audio.frames != n_events -		    || ev->time.audio.subframes != 0) { +		if (ev->time.frames != n_events) {  			return test_fail("Corrupt event %u has bad time\n", n_events);  		} else if (ev->body.type != forge.Int32) {  			return test_fail("Corrupt event %u has bad type\n", n_events); -		} else if (((LV2_Atom_Int32*)&ev->body)->value != (int)n_events + 1) { +		} else if (((LV2_Atom_Int32*)&ev->body)->body != (int)n_events + 1) {  			return test_fail("Event %u != %d\n", n_events, n_events + 1);  		}  		++n_events; diff --git a/lv2/lv2plug.in/ns/ext/atom/atom.h b/lv2/lv2plug.in/ns/ext/atom/atom.h index 3609cc9..6f104e2 100644 --- a/lv2/lv2plug.in/ns/ext/atom/atom.h +++ b/lv2/lv2plug.in/ns/ext/atom/atom.h @@ -28,34 +28,37 @@  #define LV2_ATOM_URI "http://lv2plug.in/ns/ext/atom"  #define LV2_ATOM__Atom          LV2_ATOM_URI "#Atom" -#define LV2_ATOM__Number        LV2_ATOM_URI "#Number" +#define LV2_ATOM__AtomPort      LV2_ATOM_URI "#AtomPort" +#define LV2_ATOM__AudioFrames   LV2_ATOM_URI "#AudioFrames" +#define LV2_ATOM__Beats         LV2_ATOM_URI "#Beats" +#define LV2_ATOM__Blank         LV2_ATOM_URI "#Blank" +#define LV2_ATOM__Bool          LV2_ATOM_URI "#Bool" +#define LV2_ATOM__Double        LV2_ATOM_URI "#Double" +#define LV2_ATOM__Event         LV2_ATOM_URI "#Event" +#define LV2_ATOM__Float         LV2_ATOM_URI "#Float"  #define LV2_ATOM__Int32         LV2_ATOM_URI "#Int32"  #define LV2_ATOM__Int64         LV2_ATOM_URI "#Int64" -#define LV2_ATOM__Float         LV2_ATOM_URI "#Float" -#define LV2_ATOM__Double        LV2_ATOM_URI "#Double" -#define LV2_ATOM__Bool          LV2_ATOM_URI "#Bool" -#define LV2_ATOM__String        LV2_ATOM_URI "#String"  #define LV2_ATOM__Literal       LV2_ATOM_URI "#Literal" +#define LV2_ATOM__MessagePort   LV2_ATOM_URI "#MessagePort" +#define LV2_ATOM__Number        LV2_ATOM_URI "#Number" +#define LV2_ATOM__Object        LV2_ATOM_URI "#Object"  #define LV2_ATOM__Path          LV2_ATOM_URI "#Path" -#define LV2_ATOM__URI           LV2_ATOM_URI "#URI" -#define LV2_ATOM__URID          LV2_ATOM_URI "#URID" -#define LV2_ATOM__Vector        LV2_ATOM_URI "#Vector" -#define LV2_ATOM__Tuple         LV2_ATOM_URI "#Tuple"  #define LV2_ATOM__Property      LV2_ATOM_URI "#Property" -#define LV2_ATOM__Object        LV2_ATOM_URI "#Object"  #define LV2_ATOM__Resource      LV2_ATOM_URI "#Resource" -#define LV2_ATOM__Blank         LV2_ATOM_URI "#Blank" -#define LV2_ATOM__TimeUnit      LV2_ATOM_URI "#TimeUnit" -#define LV2_ATOM__AudioFrames   LV2_ATOM_URI "#AudioFrames" -#define LV2_ATOM__Beats         LV2_ATOM_URI "#Beats" -#define LV2_ATOM__Event         LV2_ATOM_URI "#Event"  #define LV2_ATOM__Sequence      LV2_ATOM_URI "#Sequence" -#define LV2_ATOM__AtomPort      LV2_ATOM_URI "#AtomPort" +#define LV2_ATOM__String        LV2_ATOM_URI "#String" +#define LV2_ATOM__TimeUnit      LV2_ATOM_URI "#TimeUnit" +#define LV2_ATOM__Tuple         LV2_ATOM_URI "#Tuple" +#define LV2_ATOM__URI           LV2_ATOM_URI "#URI" +#define LV2_ATOM__URID          LV2_ATOM_URI "#URID"  #define LV2_ATOM__ValuePort     LV2_ATOM_URI "#ValuePort" -#define LV2_ATOM__MessagePort   LV2_ATOM_URI "#MessagePort" +#define LV2_ATOM__Vector        LV2_ATOM_URI "#Vector" +#define LV2_ATOM__beatTime      LV2_ATOM_URI "#beatTime"  #define LV2_ATOM__bufferType    LV2_ATOM_URI "#bufferType" -#define LV2_ATOM__supports      LV2_ATOM_URI "#supports"  #define LV2_ATOM__eventTransfer LV2_ATOM_URI "#eventTransfer" +#define LV2_ATOM__frameTime     LV2_ATOM_URI "#frameTime" +#define LV2_ATOM__supports      LV2_ATOM_URI "#supports" +#define LV2_ATOM__timeUnit      LV2_ATOM_URI "#timeUnit"  #define LV2_ATOM_REFERENCE_TYPE 0 @@ -68,14 +71,18 @@ typedef char lv2_atom_assert_double_fits_in_64_bits[  	((sizeof(double) <= sizeof(uint64_t)) * 2) - 1];  /** -   Return a pointer to the contents of an Atom. +   Return a pointer to the contents of an Atom.  The "contents" of an atom +   is the data past the complete type-specific header.     @param type The type of the atom, e.g. LV2_Atom_String.     @param atom A variable-sized atom.  */  #define LV2_ATOM_CONTENTS(type, atom) \  	((void*)((uint8_t*)(atom) + sizeof(type))) -/** Return a pointer to the body of @p atom (just past the LV2_Atom head). */ +/** +   Return a pointer to the body of an Atom.  The "body" of an atom is the +   data just past the LV2_Atom head (i.e. the same offset for all types). +*/  #define LV2_ATOM_BODY(atom) LV2_ATOM_CONTENTS(LV2_Atom, atom)  /** The header of an atom:Atom. */ @@ -86,26 +93,26 @@ typedef struct {  /** An atom:Int32 or atom:Bool.  May be cast to LV2_Atom. */  typedef struct { -	LV2_Atom atom;   /**< Atom header. */ -	int32_t  value;  /**< Integer value. */ +	LV2_Atom atom;  /**< Atom header. */ +	int32_t  body;  /**< Integer value. */  } LV2_Atom_Int32;  /** An atom:Int64.  May be cast to LV2_Atom. */  typedef struct { -	LV2_Atom atom;   /**< Atom header. */ -	int64_t  value;  /**< Integer value. */ +	LV2_Atom atom;  /**< Atom header. */ +	int64_t  body;  /**< Integer value. */  } LV2_Atom_Int64;  /** An atom:Float.  May be cast to LV2_Atom. */  typedef struct { -	LV2_Atom atom;   /**< Atom header. */ -	float    value;  /**< Floating point value. */ +	LV2_Atom atom;  /**< Atom header. */ +	float    body;  /**< Floating point value. */  } LV2_Atom_Float;  /** An atom:Double.  May be cast to LV2_Atom. */  typedef struct { -	LV2_Atom atom;   /**< Atom header. */ -	double   value;  /**< Floating point value. */ +	LV2_Atom atom;  /**< Atom header. */ +	double   body;  /**< Floating point value. */  } LV2_Atom_Double;  /** An atom:Bool.  May be cast to LV2_Atom. */ @@ -114,83 +121,87 @@ typedef LV2_Atom_Int32 LV2_Atom_Bool;  /** An atom:URID.  May be cast to LV2_Atom. */  typedef struct {  	LV2_Atom atom;  /**< Atom header. */ -	uint32_t id;    /**< URID. */ +	uint32_t body;  /**< URID. */  } LV2_Atom_URID; -/** The complete header of an atom:String. */ +/** An atom:String.  May be cast to LV2_Atom. */  typedef struct {  	LV2_Atom atom;  /**< Atom header. */  	/* Contents (a null-terminated UTF-8 string) follow here. */  } LV2_Atom_String; -/** The complete header of an atom:Literal. */ +/** The body of an atom:Literal. */  typedef struct { -	LV2_Atom atom;      /**< Atom header. */  	uint32_t datatype;  /**< Datatype URID. */  	uint32_t lang;      /**< Language URID. */  	/* Contents (a null-terminated UTF-8 string) follow here. */ +} LV2_Atom_Literal_Body; + +/** An atom:Literal.  May be cast to LV2_Atom. */ +typedef struct { +	LV2_Atom              atom;  /**< Atom header. */ +	LV2_Atom_Literal_Body body;  /**< Body. */  } LV2_Atom_Literal; -/** The complete header of an atom:Tuple. */ +/** An atom:Tuple.  May be cast to LV2_Atom. */  typedef struct {  	LV2_Atom atom;  /**< Atom header. */  	/* Contents (a series of complete atoms) follow here. */  } LV2_Atom_Tuple; -/** The complete header of an atom:Vector. */ +/** The body of an atom:Vector. */  typedef struct { -	LV2_Atom atom;        /**< Atom header. */  	uint32_t elem_count;  /**< The number of elements in the vector */  	uint32_t elem_type;   /**< The type of each element in the vector */  	/* Contents (a series of packed atom bodies) follow here. */ +} LV2_Atom_Vector_Body; + +/** An atom:Vector.  May be cast to LV2_Atom. */ +typedef struct { +	LV2_Atom             atom;  /**< Atom header. */ +	LV2_Atom_Vector_Body body;  /**< Body. */  } LV2_Atom_Vector; -/** The header of an atom:Property body (e.g. in an atom:Object). */ +/** The body of an atom:Property (e.g. in an atom:Object). */  typedef struct {  	uint32_t key;      /**< Key (predicate) (mapped URI). */  	uint32_t context;  /**< Context URID (may be, and generally is, 0). */  	LV2_Atom value;    /**< Value atom header. */ +	/* Value atom body follows here. */  } LV2_Atom_Property_Body; -/** The complete header of an atom:Property. */ +/** An atom:Property.  May be cast to LV2_Atom. */  typedef struct { -	LV2_Atom atom;     /**< Atom header. */ -	uint32_t key;      /**< Key (predicate) (mapped URI). */ -	uint32_t context;  /**< Context URID (may be, and generally is, 0). */ -	LV2_Atom value;    /**< Value atom header. */ -	/* Value atom body follows here. */ +	LV2_Atom               atom;  /**< Atom header. */ +	LV2_Atom_Property_Body body;  /**< Body. */  } LV2_Atom_Property; -/** The complete header of an atom:Object. */ +/** The body of an atom:Object. May be cast to LV2_Atom. */  typedef struct { -	LV2_Atom atom;   /**< Atom header. */  	uint32_t id;     /**< URID (atom:Resource) or blank ID (atom:Blank). */  	uint32_t otype;  /**< Type URID (same as rdf:type, for fast dispatch). */  	/* Contents (a series of property bodies) follow here. */ -} LV2_Atom_Object; +} LV2_Atom_Object_Body; -/** A time stamp in frames.  Note this type is NOT an LV2_Atom. */ +/** An atom:Object.  May be cast to LV2_Atom. */  typedef struct { -	uint32_t frames;     /**< Time in frames relative to this block. */ -	uint32_t subframes;  /**< Fractional time in 1/(2^32)ths of a frame. */ -} LV2_Atom_Audio_Time; +	LV2_Atom             atom;  /**< Atom header. */ +	LV2_Atom_Object_Body body;  /**< Body. */ +} LV2_Atom_Object;  /** The header of an atom:Event.  Note this type is NOT an LV2_Atom. */  typedef struct {  	/** Time stamp.  Which type is valid is determined by context. */  	union { -		LV2_Atom_Audio_Time audio;  /**< Time in audio frames. */ -		double              beats;  /**< Time in beats. */ +		int64_t frames;  /**< Time in audio frames. */ +		double  beats;   /**< Time in beats. */  	} time;  	LV2_Atom body;  /**< Event body atom header. */  	/* Body atom contents follow here. */  } LV2_Atom_Event;  /** -   A sequence of events (time-stamped atoms). - -   This is used as the contents of an atom:EventPort, but is a generic Atom -   type which can be used anywhere. +   The body of an atom:Sequence (a sequence of events).     The unit field is either a URID that described an appropriate time stamp     type, or may be 0 where a default stamp type is known.  For @@ -207,10 +218,15 @@ typedef struct {     </pre>  */  typedef struct { -	LV2_Atom atom;  /**< Atom header. */  	uint32_t unit;  /**< URID of unit of event time stamps. */  	uint32_t pad;   /**< Currently unused. */  	/* Contents (a series of events) follow here. */ +} LV2_Atom_Sequence_Body; + +/** An atom:Sequence. */ +typedef struct { +	LV2_Atom              atom;  /**< Atom header. */ +	LV2_Atom_Literal_Body body;  /**< Body. */  } LV2_Atom_Sequence;  /** diff --git a/lv2/lv2plug.in/ns/ext/atom/atom.ttl b/lv2/lv2plug.in/ns/ext/atom/atom.ttl index e6b5207..b939f33 100644 --- a/lv2/lv2plug.in/ns/ext/atom/atom.ttl +++ b/lv2/lv2plug.in/ns/ext/atom/atom.ttl @@ -30,14 +30,14 @@  	rdfs:seeAlso <util.h> ,  		<forge.h> ;  	doap:release [ -		doap:revision "0.5" ; -		doap:created "2012-02-18" +		doap:revision "0.6" ; +		doap:created "2012-02-22" ;  	] ;  	doap:maintainer [  		a foaf:Person ;  		foaf:name "David Robillard" ;  		foaf:homepage <http://drobilla.net/> ; -		rdfs:seeAlso <http://drobilla.net/drobilla.rdf> +		rdfs:seeAlso <http://drobilla.net/drobilla.rdf> ;  	] ;  	lv2:documentation """  <p>This extension defines a generic container for data, called an <q>Atom</q>, @@ -177,9 +177,8 @@ string in any language or a value of any type.  A Literal has a  encoding.  The length of the string data in bytes is <code>size -  sizeof(LV2_Atom_Literal)</code>, including the terminating NULL character.  The  <code>lang</code> field SHOULD be a URI of the form -<http://lexvo.org/id/term/LANG> where LANG is an <a -href="http://www.loc.gov/standards/iso639-2/">ISO 693-2</a> or <a -href="http://www.loc.gov/standards/iso639-2/">ISO 693-3</a> language code.</p> +<http://lexvo.org/id/iso639-3/LANG> where LANG is an <a +href="http://www.loc.gov/standards/iso639-3/">ISO 693-3</a> language code.</p>  <p>A Literal may have a <code>datatype</code> OR a <code>lang</code>, but never  both.</p> @@ -190,7 +189,7 @@ void set_to_hello_in_english(LV2_Atom_Literal* lit) {       lit->atom.type = map(expand("atom:Literal"));       lit->atom.size = 14;       lit->datatype  = 0; -     lit->lang      = map("http://lexvo.org/id/term/en"); +     lit->lang      = map("http://lexvo.org/id/iso639-3/eng");       memcpy(LV2_ATOM_CONTENTS(LV2_Atom_Literal, lit),              "Hello",              sizeof("Hello"));  // Assumes enough space @@ -265,7 +264,7 @@ struct VectorOf42Floats {      uint32_t size;        // sizeof(LV2_Atom_Vector) + (42 * sizeof(float);      uint32_t elem_count;  // 42      uint32_t elem_type;   // map(expand("atom:Float")) -    float    elems[32]; +    float    elems[42];  };  </pre> @@ -347,14 +346,31 @@ atom:TimeUnit  	rdfs:label "Time Unit" ;  	lv2:documentation "<p>A unit for atom:Event time stamps.</p>" . -atom:AudioFrames +atom:frameTime +	a rdfs:Property ; +	rdfs:range xsd:decimal ; +	rdfs:label "Frame time" ; +	lv2:documentation """ +<p>Time stamp in audio frames.  Typically used for events.</p> +""" . + +atom:beatTime +	a rdfs:Property ; +	rdfs:range xsd:decimal ; +	rdfs:label "Beat time" ; +	lv2:documentation """ +<p>Time stamp in beats.  Typically used for events.</p> +""" . + +atom:Frames  	a rdfs:Class ;  	rdfs:subClassOf atom:TimeUnit ; -	rdfs:label "Audio frames" ; +	rdfs:label "Frames" ;  	lv2:documentation """  <p>Time in audio frames.  Converting this to absolute time depends on the -sample rate.  When this is the stamp unit for an atom:Sequence, the events in -that sequence have LV2_Atom_Audio_Time stamps (<code>event.time.audio</code>)</p>""" . +sample rate.  When this is the stamp unit for an atom:Sequence, its events have +int64_t time stamps (<code>event.time.frames</code>)</p> +""" .  atom:Beats  	a rdfs:Class ; diff --git a/lv2/lv2plug.in/ns/ext/atom/forge.h b/lv2/lv2plug.in/ns/ext/atom/forge.h index 9c553d2..5ad6d1d 100644 --- a/lv2/lv2plug.in/ns/ext/atom/forge.h +++ b/lv2/lv2plug.in/ns/ext/atom/forge.h @@ -185,10 +185,13 @@ lv2_atom_forge_init(LV2_Atom_Forge* forge, LV2_URID_Map* map)  	forge->Vector   = map->map(map->handle, LV2_ATOM_URI "#Vector");  } +/** +   Write raw output.  This is used internally, but is also useful for writing +   atom types not explicitly supported by the forge API.  Note the caller is +   responsible for ensuring the output is approriately padded. +*/  static inline void* -lv2_atom_forge_write_nopad(LV2_Atom_Forge* forge, -                           const void*     data, -                           uint32_t        size) +lv2_atom_forge_raw(LV2_Atom_Forge* forge, const void* data, uint32_t size)  {  	uint8_t* out = NULL;  	if (forge->sink) { @@ -209,27 +212,34 @@ lv2_atom_forge_write_nopad(LV2_Atom_Forge* forge,  	return out;  } +/** Pad output accordingly so next write is 64-bit aligned. */  static inline void -lv2_atom_forge_pad(LV2_Atom_Forge* forge, -                   uint32_t        written) +lv2_atom_forge_pad(LV2_Atom_Forge* forge, uint32_t written)  {  	const uint64_t pad      = 0;  	const uint32_t pad_size = lv2_atom_pad_size(written) - written; -	lv2_atom_forge_write_nopad(forge, &pad, pad_size); +	lv2_atom_forge_raw(forge, &pad, pad_size);  } +/** Write raw output, padding to 64-bits as necessary. */  static inline void* -lv2_atom_forge_write(LV2_Atom_Forge* forge, -                     const void*     data, -                     uint32_t        size) +lv2_atom_forge_write(LV2_Atom_Forge* forge, const void* data, uint32_t size)  { -	void* out = lv2_atom_forge_write_nopad(forge, data, size); +	void* out = lv2_atom_forge_raw(forge, data, size);  	if (out) {  		lv2_atom_forge_pad(forge, size);  	}  	return out;  } +/** Write an atom:Atom header. */ +static inline LV2_Atom* +lv2_atom_forge_atom(LV2_Atom_Forge* forge, uint32_t type, uint32_t size) +{ +	const LV2_Atom a = { type, size }; +	return (LV2_Atom*)lv2_atom_forge_raw(forge, &a, sizeof(a)); +} +  /** Write an atom:Int32. */  static inline LV2_Atom_Int32*  lv2_atom_forge_int32(LV2_Atom_Forge* forge, int32_t val) @@ -283,25 +293,26 @@ lv2_atom_forge_urid(LV2_Atom_Forge* forge, LV2_URID id)  static inline uint8_t*  lv2_atom_forge_string_body(LV2_Atom_Forge* forge,                             const uint8_t*  str, -                           size_t          len) +                           uint32_t        len)  {  	uint8_t* out = NULL; -	if ((out = lv2_atom_forge_write_nopad(forge, str, len)) -	    && (out = lv2_atom_forge_write_nopad(forge, "", 1))) { +	if (   (out = lv2_atom_forge_raw(forge, str, len)) +	    && (out = lv2_atom_forge_raw(forge, "", 1))) {  		lv2_atom_forge_pad(forge, len + 1);  	}  	return out;  } -/** Write an atom:String.  Note that @p str need not be NULL terminated. */ +/** Write an atom compatible with atom:String.  Used internally. */  static inline LV2_Atom_String* -lv2_atom_forge_string(LV2_Atom_Forge* forge, -                      const uint8_t*  str, -                      size_t          len) +lv2_atom_forge_typed_string(LV2_Atom_Forge* forge, +                            uint32_t        type, +                            const uint8_t*  str, +                            uint32_t        len)  { -	const LV2_Atom_String a = { { forge->String, len + 1 } }; +	const LV2_Atom_String a = { { type, len + 1 } };  	LV2_Atom_String* out = (LV2_Atom_String*) -		lv2_atom_forge_write_nopad(forge, &a, sizeof(a)); +		lv2_atom_forge_raw(forge, &a, sizeof(a));  	if (out) {  		if (!lv2_atom_forge_string_body(forge, str, len)) {  			out->atom.type = 0; @@ -312,64 +323,47 @@ lv2_atom_forge_string(LV2_Atom_Forge* forge,  	return out;  } +/** Write an atom:String.  Note that @p str need not be NULL terminated. */ +static inline LV2_Atom_String* +lv2_atom_forge_string(LV2_Atom_Forge* forge, const uint8_t* str, uint32_t len) +{ +	return lv2_atom_forge_typed_string(forge, forge->String, str, len); +} +  /**     Write an atom:URI.  Note that @p uri need not be NULL terminated.     This does not map the URI, but writes the complete URI string.  To write     a mapped URI, use lv2_atom_forge_urid().  */  static inline LV2_Atom_String* -lv2_atom_forge_uri(LV2_Atom_Forge* forge, -                   const uint8_t*  uri, -                   size_t          len) +lv2_atom_forge_uri(LV2_Atom_Forge* forge, const uint8_t* uri, uint32_t len)  { -	const LV2_Atom_String a = { { forge->URI, len + 1 } }; -	LV2_Atom_String* out = (LV2_Atom_String*) -		lv2_atom_forge_write_nopad(forge, &a, sizeof(a)); -	if (out) { -		if (!lv2_atom_forge_string_body(forge, uri, len)) { -			out->atom.type = 0; -			out->atom.size = 0; -			out = NULL; -		} -	} -	return out; +	return lv2_atom_forge_typed_string(forge, forge->URI, uri, len);  }  /** Write an atom:Path.  Note that @p path need not be NULL terminated. */  static inline LV2_Atom_String* -lv2_atom_forge_path(LV2_Atom_Forge* forge, -                    const uint8_t*  path, -                    size_t          len) +lv2_atom_forge_path(LV2_Atom_Forge* forge, const uint8_t* path, uint32_t len)  { -	const LV2_Atom_String a = { { forge->Path, len + 1 } }; -	LV2_Atom_String* out = (LV2_Atom_String*) -		lv2_atom_forge_write_nopad(forge, &a, sizeof(a)); -	if (out) { -		if (!lv2_atom_forge_string_body(forge, path, len)) { -			out->atom.type = 0; -			out->atom.size = 0; -			out = NULL; -		} -	} -	return out; +	return lv2_atom_forge_typed_string(forge, forge->Path, path, len);  }  /** Write an atom:Literal. */  static inline LV2_Atom_Literal*  lv2_atom_forge_literal(LV2_Atom_Forge* forge,                         const uint8_t*  str, -                       size_t          len, +                       uint32_t        len,                         uint32_t        datatype,                         uint32_t        lang)  {  	const LV2_Atom_Literal a = {  		{ forge->Literal,  		  sizeof(LV2_Atom_Literal) - sizeof(LV2_Atom) + len + 1 }, -		datatype, -		lang +		{ datatype, +		  lang }  	};  	LV2_Atom_Literal* out = (LV2_Atom_Literal*) -		lv2_atom_forge_write_nopad(forge, &a, sizeof(a)); +		lv2_atom_forge_raw(forge, &a, sizeof(a));  	if (out) {  		if (!lv2_atom_forge_string_body(forge, str, len)) {  			out->atom.type = 0; @@ -387,11 +381,10 @@ lv2_atom_forge_vector_head(LV2_Atom_Forge* forge,                             uint32_t        elem_type,                             uint32_t        elem_size)  { -	const size_t size = sizeof(LV2_Atom_Vector) + (elem_size * elem_count); +	const uint32_t size = sizeof(LV2_Atom_Vector) + (elem_size * elem_count);  	const LV2_Atom_Vector a = {  		{ forge->Vector, size - sizeof(LV2_Atom) }, -		elem_count, -		elem_type +		{ elem_count, elem_type }  	};  	return (LV2_Atom_Vector*)lv2_atom_forge_write(forge, &a, sizeof(a));  } @@ -469,8 +462,7 @@ lv2_atom_forge_resource(LV2_Atom_Forge*       forge,  {  	const LV2_Atom_Object a = {  		{ forge->Resource, sizeof(LV2_Atom_Object) - sizeof(LV2_Atom) }, -		id, -		otype +		{ id, otype }  	};  	LV2_Atom* atom = (LV2_Atom*)lv2_atom_forge_write(forge, &a, sizeof(a));  	return (LV2_Atom_Object*)lv2_atom_forge_push(forge, frame, atom); @@ -487,8 +479,7 @@ lv2_atom_forge_blank(LV2_Atom_Forge*       forge,  {  	const LV2_Atom_Object a = {  		{ forge->Blank, sizeof(LV2_Atom_Object) - sizeof(LV2_Atom) }, -		id, -		otype +		{ id, otype }  	};  	LV2_Atom* atom = (LV2_Atom*)lv2_atom_forge_write(forge, &a, sizeof(a));  	return (LV2_Atom_Object*)lv2_atom_forge_push(forge, frame, atom); @@ -520,8 +511,7 @@ lv2_atom_forge_sequence_head(LV2_Atom_Forge*       forge,  {  	const LV2_Atom_Sequence a = {  		{ forge->Sequence, sizeof(LV2_Atom_Sequence) - sizeof(LV2_Atom) }, -		unit, -		0 +		{ unit, 0 }  	};  	LV2_Atom* atom = (LV2_Atom*)lv2_atom_forge_write(forge, &a, sizeof(a));  	return (LV2_Atom_Sequence*)lv2_atom_forge_push(forge, frame, atom); @@ -532,13 +522,10 @@ lv2_atom_forge_sequence_head(LV2_Atom_Forge*       forge,     After this, call the appropriate forge method(s) to write the body, passing     the same @p parent parameter.  Note the returned LV2_Event is NOT an Atom.  */ -static inline LV2_Atom_Audio_Time* -lv2_atom_forge_audio_time(LV2_Atom_Forge* forge, -                          uint32_t        frames, -                          uint32_t        subframes) +static inline int64_t* +lv2_atom_forge_frame_time(LV2_Atom_Forge* forge, int64_t frames)  { -	const LV2_Atom_Audio_Time a = { frames, subframes }; -	return (LV2_Atom_Audio_Time*)lv2_atom_forge_write(forge, &a, sizeof(a)); +	return (int64_t*)lv2_atom_forge_write(forge, &frames, sizeof(frames));  }  /** @@ -547,8 +534,7 @@ lv2_atom_forge_audio_time(LV2_Atom_Forge* forge,     the same @p parent parameter.  Note the returned LV2_Event is NOT an Atom.  */  static inline double* -lv2_atom_forge_beat_time(LV2_Atom_Forge* forge, -                         double          beats) +lv2_atom_forge_beat_time(LV2_Atom_Forge* forge, double beats)  {  	return (double*)lv2_atom_forge_write(forge, &beats, sizeof(beats));  } diff --git a/lv2/lv2plug.in/ns/ext/atom/manifest.ttl b/lv2/lv2plug.in/ns/ext/atom/manifest.ttl index 9730981..6af1973 100644 --- a/lv2/lv2plug.in/ns/ext/atom/manifest.ttl +++ b/lv2/lv2plug.in/ns/ext/atom/manifest.ttl @@ -4,5 +4,5 @@  <http://lv2plug.in/ns/ext/atom>  	a lv2:Specification ;  	lv2:minorVersion 0 ; -	lv2:microVersion 5 ; +	lv2:microVersion 6 ;  	rdfs:seeAlso <atom.ttl> . diff --git a/lv2/lv2plug.in/ns/ext/atom/util.h b/lv2/lv2plug.in/ns/ext/atom/util.h index 9015a01..8ca3795 100644 --- a/lv2/lv2plug.in/ns/ext/atom/util.h +++ b/lv2/lv2plug.in/ns/ext/atom/util.h @@ -62,12 +62,9 @@ lv2_atom_is_null(const LV2_Atom* atom)  static inline bool  lv2_atom_equals(const LV2_Atom* a, const LV2_Atom* b)  { -	return (a == b) || ( -		(a->type == b->type) && -		(a->size == b->size) && -		!memcmp(LV2_ATOM_CONTENTS(LV2_Atom, a), -		        LV2_ATOM_CONTENTS(LV2_Atom, b), -		        a->size)); +	return (a == b) || ((a->type == b->type) && +	                    (a->size == b->size) && +	                    !memcmp(a + 1, b + 1, a->size));  }  /** @@ -78,14 +75,30 @@ lv2_atom_equals(const LV2_Atom* a, const LV2_Atom* b)  /** An iterator over the elements of an LV2_Atom_Sequence. */  typedef LV2_Atom_Event* LV2_Atom_Sequence_Iter; -/** Get an iterator pointing to the first element in @p tup. */ +/** Get an iterator pointing to the first element in a Sequence body. */ +static inline LV2_Atom_Sequence_Iter +lv2_sequence_body_begin(const LV2_Atom_Sequence_Body* body) +{ +	return (LV2_Atom_Sequence_Iter)(body + 1); +} + +/** Get an iterator pointing to the first element in a Sequence. */  static inline LV2_Atom_Sequence_Iter  lv2_sequence_begin(const LV2_Atom_Sequence* seq)  { -	return (LV2_Atom_Sequence_Iter)(LV2_ATOM_CONTENTS(LV2_Atom_Sequence, seq)); +	return (LV2_Atom_Sequence_Iter)(seq + 1);  } -/** Return true iff @p i has reached the end of @p tup. */ +/** Return true iff @p i has reached the end of @p body. */ +static inline bool +lv2_sequence_body_is_end(const LV2_Atom_Sequence_Body* body, +                         uint32_t                      size, +                         LV2_Atom_Sequence_Iter        i) +{ +	return (uint8_t*)i >= ((uint8_t*)body + size); +} + +/** Return true iff @p i has reached the end of @p seq. */  static inline bool  lv2_sequence_is_end(const LV2_Atom_Sequence* seq, LV2_Atom_Sequence_Iter i)  { @@ -126,6 +139,12 @@ lv2_sequence_iter_get(LV2_Atom_Sequence_Iter i)  	     !lv2_sequence_is_end(sequence, (iter)); \  	     (iter) = lv2_sequence_iter_next(iter)) +/** A version of LV2_SEQUENCE_FOREACH for when only the body is available. */ +#define LV2_SEQUENCE_BODY_FOREACH(body, size, iter) \ +	for (LV2_Atom_Sequence_Iter (iter) = lv2_sequence_body_begin(body); \ +	     !lv2_sequence_body_is_end(body, size, (iter)); \ +	     (iter) = lv2_sequence_iter_next(iter)) +  /**     @}     @name Tuple Iterator @@ -142,11 +161,20 @@ lv2_tuple_begin(const LV2_Atom_Tuple* tup)  	return (LV2_Atom_Tuple_Iter)(LV2_ATOM_BODY(tup));  } +/** Return true iff @p i has reached the end of @p body. */ +static inline bool +lv2_atom_tuple_body_is_end(const void*         body, +                           uint32_t            size, +                           LV2_Atom_Tuple_Iter i) +{ +	return (uint8_t*)i >= ((uint8_t*)body + size); +} +  /** Return true iff @p i has reached the end of @p tup. */  static inline bool  lv2_tuple_is_end(const LV2_Atom_Tuple* tup, LV2_Atom_Tuple_Iter i)  { -	return (uint8_t*)i >= ((uint8_t*)tup + sizeof(LV2_Atom) + tup->atom.size); +	return lv2_atom_tuple_body_is_end(LV2_ATOM_BODY(tup), tup->atom.size, i);  }  /** Return an iterator to the element following @p i. */ @@ -182,6 +210,12 @@ lv2_tuple_iter_get(LV2_Atom_Tuple_Iter i)  	     !lv2_tuple_is_end(tuple, (iter)); \  	     (iter) = lv2_tuple_iter_next(iter)) +/** A version of LV2_TUPLE_FOREACH for when only the body is available. */ +#define LV2_TUPLE_BODY_FOREACH(body, size, iter) \ +	for (LV2_Atom_Tuple_Iter (iter) = (LV2_Atom_Tuple_Iter)body; \ +	     !lv2_atom_tuple_body_is_end(body, size, (iter)); \ +	     (iter) = lv2_tuple_iter_next(iter)) +  /**     @}     @name Object Iterator @@ -191,26 +225,32 @@ lv2_tuple_iter_get(LV2_Atom_Tuple_Iter i)  /** An iterator over the properties of an LV2_Atom_Object. */  typedef LV2_Atom_Property_Body* LV2_Atom_Object_Iter; +static inline LV2_Atom_Object_Iter +lv2_object_body_begin(const LV2_Atom_Object_Body* body) +{ +	return (LV2_Atom_Object_Iter)(body + 1); +} +  /** Get an iterator pointing to the first property in @p obj. */  static inline LV2_Atom_Object_Iter  lv2_object_begin(const LV2_Atom_Object* obj)  { -	return (LV2_Atom_Object_Iter)(LV2_ATOM_CONTENTS(LV2_Atom_Object, obj)); +	return (LV2_Atom_Object_Iter)(obj + 1);  } -/** Return true iff @p i has reached the end of @p obj. */  static inline bool -lv2_object_is_end(const LV2_Atom_Object* obj, LV2_Atom_Object_Iter i) +lv2_atom_object_body_is_end(const LV2_Atom_Object_Body* body, +                            uint32_t                    size, +                            LV2_Atom_Object_Iter        i)  { -	return (uint8_t*)i >= ((uint8_t*)obj + sizeof(LV2_Atom) + obj->atom.size); +	return (uint8_t*)i >= ((uint8_t*)body + size);  } -/** Return true iff @p l points to the same property as @p r. */ +/** Return true iff @p i has reached the end of @p obj. */  static inline bool -lv2_object_iter_equals(const LV2_Atom_Object_Iter l, -                       const LV2_Atom_Object_Iter r) +lv2_object_is_end(const LV2_Atom_Object* obj, LV2_Atom_Object_Iter i)  { -	return l == r; +	return (uint8_t*)i >= ((uint8_t*)obj + sizeof(LV2_Atom) + obj->atom.size);  }  /** Return an iterator to the property following @p i. */ @@ -248,6 +288,12 @@ lv2_object_iter_get(LV2_Atom_Object_Iter i)  	     !lv2_object_is_end(object, (iter)); \  	     (iter) = lv2_object_iter_next(iter)) +/** A version of LV2_OBJECT_FOREACH for when only the body is available. */ +#define LV2_OBJECT_BODY_FOREACH(body, size, iter) \ +	for (LV2_Atom_Object_Iter (iter) = lv2_object_body_begin(body); \ +	     !lv2_atom_object_body_is_end(body, size, (iter)); \ +	     (iter) = lv2_object_iter_next(iter)) +  /**     @}     @name Object Query |