Changeset 561

Show
Ignore:
Timestamp:
02/22/12 17:53:15 (3 months ago)
Author:
drobilla
Message:

Separately define body types for atoms with non-trivial bodies so the type definitions are useful when only the body is available (e.g. state API).
Use a single int64_t stamp for frame times since range is more important now and subframes was never really used anyway.
Add atom:frameTime and atom:beatTime for serialising events.
Consistently use name "body" for all types of atom bodies.
Add lv2_atom_forge_atom() and lv2_atom_forge_raw() for constructing arbitrary atoms.
Merge similar string-like forge methods.
Update language URI requirements to match current (and hopefully permanent, geeze)  http://lexvo.org reality.

Location:
trunk
Files:
8 modified

Legend:

Unmodified
Added
Removed
  • trunk/lv2/lv2plug.in/ns/ext/atom/atom-test.c

    r558 r561  
    9595        lv2_atom_forge_property_head(&forge, eg_one, 0); 
    9696        LV2_Atom_Int32* one = lv2_atom_forge_int32(&forge, 1); 
    97         if (one->value != 1) { 
    98                 return test_fail("%d != 1\n", one->value); 
     97        if (one->body != 1) { 
     98                return test_fail("%d != 1\n", one->body); 
    9999        } 
    100100 
     
    102102        lv2_atom_forge_property_head(&forge, eg_two, 0); 
    103103        LV2_Atom_Int64* two = lv2_atom_forge_int64(&forge, 2); 
    104         if (two->value != 2) { 
    105                 return test_fail("%ld != 2\n", two->value); 
     104        if (two->body != 2) { 
     105                return test_fail("%ld != 2\n", two->body); 
    106106        } 
    107107 
     
    109109        lv2_atom_forge_property_head(&forge, eg_three, 0); 
    110110        LV2_Atom_Float* three = lv2_atom_forge_float(&forge, 3.0f); 
    111         if (three->value != 3) { 
    112                 return test_fail("%f != 3\n", three->value); 
     111        if (three->body != 3) { 
     112                return test_fail("%f != 3\n", three->body); 
    113113        } 
    114114 
     
    116116        lv2_atom_forge_property_head(&forge, eg_four, 0); 
    117117        LV2_Atom_Double* four = lv2_atom_forge_double(&forge, 4.0); 
    118         if (four->value != 4) { 
    119                 return test_fail("%ld != 4\n", four->value); 
     118        if (four->body != 4) { 
     119                return test_fail("%ld != 4\n", four->body); 
    120120        } 
    121121 
     
    123123        lv2_atom_forge_property_head(&forge, eg_true, 0); 
    124124        LV2_Atom_Bool* t = lv2_atom_forge_bool(&forge, true); 
    125         if (t->value != 1) { 
    126                 return test_fail("%ld != 1 (true)\n", t->value); 
     125        if (t->body != 1) { 
     126                return test_fail("%ld != 1 (true)\n", t->body); 
    127127        } 
    128128 
     
    130130        lv2_atom_forge_property_head(&forge, eg_false, 0); 
    131131        LV2_Atom_Bool* f = lv2_atom_forge_bool(&forge, false); 
    132         if (f->value != 0) { 
    133                 return test_fail("%ld != 0 (false)\n", f->value); 
     132        if (f->body != 0) { 
     133                return test_fail("%ld != 0 (false)\n", f->body); 
    134134        } 
    135135 
     
    160160        lv2_atom_forge_property_head(&forge, eg_urid, 0); 
    161161        LV2_Atom_URID* urid = lv2_atom_forge_urid(&forge, eg_value); 
    162         if (urid->id != eg_value) { 
    163                 return test_fail("%u != %u\n", urid->id, eg_value); 
     162        if (urid->body != eg_value) { 
     163                return test_fail("%u != %u\n", urid->body, eg_value); 
    164164        } 
    165165 
     
    227227        LV2_Atom_Forge_Frame seq_frame; 
    228228        LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)lv2_atom_forge_sequence_head(&forge, &seq_frame, 0); 
    229         lv2_atom_forge_audio_time(&forge, 0, 0); 
     229        lv2_atom_forge_frame_time(&forge, 0); 
    230230        lv2_atom_forge_int32(&forge, 1); 
    231         lv2_atom_forge_audio_time(&forge, 1, 0); 
     231        lv2_atom_forge_frame_time(&forge, 1); 
    232232        lv2_atom_forge_int32(&forge, 2); 
    233233        lv2_atom_forge_pop(&forge, &seq_frame); 
     
    241241        } else if (lv2_atom_equals((LV2_Atom*)one, (LV2_Atom*)&itwo)) { 
    242242                return test_fail("1 == 2\n"); 
     243        } else if (!lv2_atom_equals((LV2_Atom*)one, (LV2_Atom*)one)) { 
     244                return test_fail("1 != 1\n"); 
    243245        } 
    244246 
     
    246248        LV2_SEQUENCE_FOREACH(seq, i) { 
    247249                LV2_Atom_Event* ev = lv2_sequence_iter_get(i); 
    248                 if (ev->time.audio.frames != n_events 
    249                     || ev->time.audio.subframes != 0) { 
     250                if (ev->time.frames != n_events) { 
    250251                        return test_fail("Corrupt event %u has bad time\n", n_events); 
    251252                } else if (ev->body.type != forge.Int32) { 
    252253                        return test_fail("Corrupt event %u has bad type\n", n_events); 
    253                 } else if (((LV2_Atom_Int32*)&ev->body)->value != (int)n_events + 1) { 
     254                } else if (((LV2_Atom_Int32*)&ev->body)->body != (int)n_events + 1) { 
    254255                        return test_fail("Event %u != %d\n", n_events, n_events + 1); 
    255256                } 
  • trunk/lv2/lv2plug.in/ns/ext/atom/atom.h

    r557 r561  
    2929 
    3030#define LV2_ATOM__Atom          LV2_ATOM_URI "#Atom" 
    31 #define LV2_ATOM__Number        LV2_ATOM_URI "#Number" 
     31#define LV2_ATOM__AtomPort      LV2_ATOM_URI "#AtomPort" 
     32#define LV2_ATOM__AudioFrames   LV2_ATOM_URI "#AudioFrames" 
     33#define LV2_ATOM__Beats         LV2_ATOM_URI "#Beats" 
     34#define LV2_ATOM__Blank         LV2_ATOM_URI "#Blank" 
     35#define LV2_ATOM__Bool          LV2_ATOM_URI "#Bool" 
     36#define LV2_ATOM__Double        LV2_ATOM_URI "#Double" 
     37#define LV2_ATOM__Event         LV2_ATOM_URI "#Event" 
     38#define LV2_ATOM__Float         LV2_ATOM_URI "#Float" 
    3239#define LV2_ATOM__Int32         LV2_ATOM_URI "#Int32" 
    3340#define LV2_ATOM__Int64         LV2_ATOM_URI "#Int64" 
    34 #define LV2_ATOM__Float         LV2_ATOM_URI "#Float" 
    35 #define LV2_ATOM__Double        LV2_ATOM_URI "#Double" 
    36 #define LV2_ATOM__Bool          LV2_ATOM_URI "#Bool" 
     41#define LV2_ATOM__Literal       LV2_ATOM_URI "#Literal" 
     42#define LV2_ATOM__MessagePort   LV2_ATOM_URI "#MessagePort" 
     43#define LV2_ATOM__Number        LV2_ATOM_URI "#Number" 
     44#define LV2_ATOM__Object        LV2_ATOM_URI "#Object" 
     45#define LV2_ATOM__Path          LV2_ATOM_URI "#Path" 
     46#define LV2_ATOM__Property      LV2_ATOM_URI "#Property" 
     47#define LV2_ATOM__Resource      LV2_ATOM_URI "#Resource" 
     48#define LV2_ATOM__Sequence      LV2_ATOM_URI "#Sequence" 
    3749#define LV2_ATOM__String        LV2_ATOM_URI "#String" 
    38 #define LV2_ATOM__Literal       LV2_ATOM_URI "#Literal" 
    39 #define LV2_ATOM__Path          LV2_ATOM_URI "#Path" 
     50#define LV2_ATOM__TimeUnit      LV2_ATOM_URI "#TimeUnit" 
     51#define LV2_ATOM__Tuple         LV2_ATOM_URI "#Tuple" 
    4052#define LV2_ATOM__URI           LV2_ATOM_URI "#URI" 
    4153#define LV2_ATOM__URID          LV2_ATOM_URI "#URID" 
     54#define LV2_ATOM__ValuePort     LV2_ATOM_URI "#ValuePort" 
    4255#define LV2_ATOM__Vector        LV2_ATOM_URI "#Vector" 
    43 #define LV2_ATOM__Tuple         LV2_ATOM_URI "#Tuple" 
    44 #define LV2_ATOM__Property      LV2_ATOM_URI "#Property" 
    45 #define LV2_ATOM__Object        LV2_ATOM_URI "#Object" 
    46 #define LV2_ATOM__Resource      LV2_ATOM_URI "#Resource" 
    47 #define LV2_ATOM__Blank         LV2_ATOM_URI "#Blank" 
    48 #define LV2_ATOM__TimeUnit      LV2_ATOM_URI "#TimeUnit" 
    49 #define LV2_ATOM__AudioFrames   LV2_ATOM_URI "#AudioFrames" 
    50 #define LV2_ATOM__Beats         LV2_ATOM_URI "#Beats" 
    51 #define LV2_ATOM__Event         LV2_ATOM_URI "#Event" 
    52 #define LV2_ATOM__Sequence      LV2_ATOM_URI "#Sequence" 
    53 #define LV2_ATOM__AtomPort      LV2_ATOM_URI "#AtomPort" 
    54 #define LV2_ATOM__ValuePort     LV2_ATOM_URI "#ValuePort" 
    55 #define LV2_ATOM__MessagePort   LV2_ATOM_URI "#MessagePort" 
     56#define LV2_ATOM__beatTime      LV2_ATOM_URI "#beatTime" 
    5657#define LV2_ATOM__bufferType    LV2_ATOM_URI "#bufferType" 
     58#define LV2_ATOM__eventTransfer LV2_ATOM_URI "#eventTransfer" 
     59#define LV2_ATOM__frameTime     LV2_ATOM_URI "#frameTime" 
    5760#define LV2_ATOM__supports      LV2_ATOM_URI "#supports" 
    58 #define LV2_ATOM__eventTransfer LV2_ATOM_URI "#eventTransfer" 
     61#define LV2_ATOM__timeUnit      LV2_ATOM_URI "#timeUnit" 
    5962 
    6063#define LV2_ATOM_REFERENCE_TYPE 0 
     
    6972 
    7073/** 
    71    Return a pointer to the contents of an Atom. 
     74   Return a pointer to the contents of an Atom.  The "contents" of an atom 
     75   is the data past the complete type-specific header. 
    7276   @param type The type of the atom, e.g. LV2_Atom_String. 
    7377   @param atom A variable-sized atom. 
     
    7680        ((void*)((uint8_t*)(atom) + sizeof(type))) 
    7781 
    78 /** Return a pointer to the body of @p atom (just past the LV2_Atom head). */ 
     82/** 
     83   Return a pointer to the body of an Atom.  The "body" of an atom is the 
     84   data just past the LV2_Atom head (i.e. the same offset for all types). 
     85*/ 
    7986#define LV2_ATOM_BODY(atom) LV2_ATOM_CONTENTS(LV2_Atom, atom) 
    8087 
     
    8794/** An atom:Int32 or atom:Bool.  May be cast to LV2_Atom. */ 
    8895typedef struct { 
    89         LV2_Atom atom;   /**< Atom header. */ 
    90         int32_t  value;  /**< Integer value. */ 
     96        LV2_Atom atom;  /**< Atom header. */ 
     97        int32_t  body;  /**< Integer value. */ 
    9198} LV2_Atom_Int32; 
    9299 
    93100/** An atom:Int64.  May be cast to LV2_Atom. */ 
    94101typedef struct { 
    95         LV2_Atom atom;   /**< Atom header. */ 
    96         int64_t  value;  /**< Integer value. */ 
     102        LV2_Atom atom;  /**< Atom header. */ 
     103        int64_t  body;  /**< Integer value. */ 
    97104} LV2_Atom_Int64; 
    98105 
    99106/** An atom:Float.  May be cast to LV2_Atom. */ 
    100107typedef struct { 
    101         LV2_Atom atom;   /**< Atom header. */ 
    102         float    value;  /**< Floating point value. */ 
     108        LV2_Atom atom;  /**< Atom header. */ 
     109        float    body;  /**< Floating point value. */ 
    103110} LV2_Atom_Float; 
    104111 
    105112/** An atom:Double.  May be cast to LV2_Atom. */ 
    106113typedef struct { 
    107         LV2_Atom atom;   /**< Atom header. */ 
    108         double   value;  /**< Floating point value. */ 
     114        LV2_Atom atom;  /**< Atom header. */ 
     115        double   body;  /**< Floating point value. */ 
    109116} LV2_Atom_Double; 
    110117 
     
    115122typedef struct { 
    116123        LV2_Atom atom;  /**< Atom header. */ 
    117         uint32_t id;    /**< URID. */ 
     124        uint32_t body;  /**< URID. */ 
    118125} LV2_Atom_URID; 
    119126 
    120 /** The complete header of an atom:String. */ 
     127/** An atom:String.  May be cast to LV2_Atom. */ 
    121128typedef struct { 
    122129        LV2_Atom atom;  /**< Atom header. */ 
     
    124131} LV2_Atom_String; 
    125132 
    126 /** The complete header of an atom:Literal. */ 
    127 typedef struct { 
    128         LV2_Atom atom;      /**< Atom header. */ 
     133/** The body of an atom:Literal. */ 
     134typedef struct { 
    129135        uint32_t datatype;  /**< Datatype URID. */ 
    130136        uint32_t lang;      /**< Language URID. */ 
    131137        /* Contents (a null-terminated UTF-8 string) follow here. */ 
     138} LV2_Atom_Literal_Body; 
     139 
     140/** An atom:Literal.  May be cast to LV2_Atom. */ 
     141typedef struct { 
     142        LV2_Atom              atom;  /**< Atom header. */ 
     143        LV2_Atom_Literal_Body body;  /**< Body. */ 
    132144} LV2_Atom_Literal; 
    133145 
    134 /** The complete header of an atom:Tuple. */ 
     146/** An atom:Tuple.  May be cast to LV2_Atom. */ 
    135147typedef struct { 
    136148        LV2_Atom atom;  /**< Atom header. */ 
     
    138150} LV2_Atom_Tuple; 
    139151 
    140 /** The complete header of an atom:Vector. */ 
    141 typedef struct { 
    142         LV2_Atom atom;        /**< Atom header. */ 
     152/** The body of an atom:Vector. */ 
     153typedef struct { 
    143154        uint32_t elem_count;  /**< The number of elements in the vector */ 
    144155        uint32_t elem_type;   /**< The type of each element in the vector */ 
    145156        /* Contents (a series of packed atom bodies) follow here. */ 
     157} LV2_Atom_Vector_Body; 
     158 
     159/** An atom:Vector.  May be cast to LV2_Atom. */ 
     160typedef struct { 
     161        LV2_Atom             atom;  /**< Atom header. */ 
     162        LV2_Atom_Vector_Body body;  /**< Body. */ 
    146163} LV2_Atom_Vector; 
    147164 
    148 /** The header of an atom:Property body (e.g. in an atom:Object). */ 
    149 typedef struct { 
    150         uint32_t key;      /**< Key (predicate) (mapped URI). */ 
    151         uint32_t context;  /**< Context URID (may be, and generally is, 0). */ 
    152         LV2_Atom value;    /**< Value atom header. */ 
    153 } LV2_Atom_Property_Body; 
    154  
    155 /** The complete header of an atom:Property. */ 
    156 typedef struct { 
    157         LV2_Atom atom;     /**< Atom header. */ 
     165/** The body of an atom:Property (e.g. in an atom:Object). */ 
     166typedef struct { 
    158167        uint32_t key;      /**< Key (predicate) (mapped URI). */ 
    159168        uint32_t context;  /**< Context URID (may be, and generally is, 0). */ 
    160169        LV2_Atom value;    /**< Value atom header. */ 
    161170        /* Value atom body follows here. */ 
     171} LV2_Atom_Property_Body; 
     172 
     173/** An atom:Property.  May be cast to LV2_Atom. */ 
     174typedef struct { 
     175        LV2_Atom               atom;  /**< Atom header. */ 
     176        LV2_Atom_Property_Body body;  /**< Body. */ 
    162177} LV2_Atom_Property; 
    163178 
    164 /** The complete header of an atom:Object. */ 
    165 typedef struct { 
    166         LV2_Atom atom;   /**< Atom header. */ 
     179/** The body of an atom:Object. May be cast to LV2_Atom. */ 
     180typedef struct { 
    167181        uint32_t id;     /**< URID (atom:Resource) or blank ID (atom:Blank). */ 
    168182        uint32_t otype;  /**< Type URID (same as rdf:type, for fast dispatch). */ 
    169183        /* Contents (a series of property bodies) follow here. */ 
     184} LV2_Atom_Object_Body; 
     185 
     186/** An atom:Object.  May be cast to LV2_Atom. */ 
     187typedef struct { 
     188        LV2_Atom             atom;  /**< Atom header. */ 
     189        LV2_Atom_Object_Body body;  /**< Body. */ 
    170190} LV2_Atom_Object; 
    171  
    172 /** A time stamp in frames.  Note this type is NOT an LV2_Atom. */ 
    173 typedef struct { 
    174         uint32_t frames;     /**< Time in frames relative to this block. */ 
    175         uint32_t subframes;  /**< Fractional time in 1/(2^32)ths of a frame. */ 
    176 } LV2_Atom_Audio_Time; 
    177191 
    178192/** The header of an atom:Event.  Note this type is NOT an LV2_Atom. */ 
     
    180194        /** Time stamp.  Which type is valid is determined by context. */ 
    181195        union { 
    182                 LV2_Atom_Audio_Time audio;  /**< Time in audio frames. */ 
    183                 double              beats;  /**< Time in beats. */ 
     196                int64_t frames;  /**< Time in audio frames. */ 
     197                double  beats;   /**< Time in beats. */ 
    184198        } time; 
    185199        LV2_Atom body;  /**< Event body atom header. */ 
     
    188202 
    189203/** 
    190    A sequence of events (time-stamped atoms). 
    191  
    192    This is used as the contents of an atom:EventPort, but is a generic Atom 
    193    type which can be used anywhere. 
     204   The body of an atom:Sequence (a sequence of events). 
    194205 
    195206   The unit field is either a URID that described an appropriate time stamp 
     
    208219*/ 
    209220typedef struct { 
    210         LV2_Atom atom;  /**< Atom header. */ 
    211221        uint32_t unit;  /**< URID of unit of event time stamps. */ 
    212222        uint32_t pad;   /**< Currently unused. */ 
    213223        /* Contents (a series of events) follow here. */ 
     224} LV2_Atom_Sequence_Body; 
     225 
     226/** An atom:Sequence. */ 
     227typedef struct { 
     228        LV2_Atom              atom;  /**< Atom header. */ 
     229        LV2_Atom_Literal_Body body;  /**< Body. */ 
    214230} LV2_Atom_Sequence; 
    215231 
  • trunk/lv2/lv2plug.in/ns/ext/atom/atom.ttl

    r557 r561  
    3131                <forge.h> ; 
    3232        doap:release [ 
    33                 doap:revision "0.5" ; 
    34                 doap:created "2012-02-18" 
     33                doap:revision "0.6" ; 
     34                doap:created "2012-02-22" ; 
    3535        ] ; 
    3636        doap:maintainer [ 
     
    3838                foaf:name "David Robillard" ; 
    3939                foaf:homepage <http://drobilla.net/> ; 
    40                 rdfs:seeAlso <http://drobilla.net/drobilla.rdf> 
     40                rdfs:seeAlso <http://drobilla.net/drobilla.rdf> ; 
    4141        ] ; 
    4242        lv2:documentation """ 
     
    178178sizeof(LV2_Atom_Literal)</code>, including the terminating NULL character.  The 
    179179<code>lang</code> field SHOULD be a URI of the form 
    180 &lt;http://lexvo.org/id/term/LANG&gt; where LANG is an <a 
    181 href="http://www.loc.gov/standards/iso639-2/">ISO 693-2</a> or <a 
    182 href="http://www.loc.gov/standards/iso639-2/">ISO 693-3</a> language code.</p> 
     180&lt;http://lexvo.org/id/iso639-3/LANG&gt; where LANG is an <a 
     181href="http://www.loc.gov/standards/iso639-3/">ISO 693-3</a> language code.</p> 
    183182 
    184183<p>A Literal may have a <code>datatype</code> OR a <code>lang</code>, but never 
     
    191190     lit->atom.size = 14; 
    192191     lit->datatype  = 0; 
    193      lit->lang      = map("http://lexvo.org/id/term/en"); 
     192     lit->lang      = map("http://lexvo.org/id/iso639-3/eng"); 
    194193     memcpy(LV2_ATOM_CONTENTS(LV2_Atom_Literal, lit), 
    195194            "Hello", 
     
    266265    uint32_t elem_count;  // 42 
    267266    uint32_t elem_type;   // map(expand("atom:Float")) 
    268     float    elems[32]; 
     267    float    elems[42]; 
    269268}; 
    270269</pre> 
     
    348347        lv2:documentation "<p>A unit for atom:Event time stamps.</p>" . 
    349348 
    350 atom:AudioFrames 
     349atom:frameTime 
     350        a rdfs:Property ; 
     351        rdfs:range xsd:decimal ; 
     352        rdfs:label "Frame time" ; 
     353        lv2:documentation """ 
     354<p>Time stamp in audio frames.  Typically used for events.</p> 
     355""" . 
     356 
     357atom:beatTime 
     358        a rdfs:Property ; 
     359        rdfs:range xsd:decimal ; 
     360        rdfs:label "Beat time" ; 
     361        lv2:documentation """ 
     362<p>Time stamp in beats.  Typically used for events.</p> 
     363""" . 
     364 
     365atom:Frames 
    351366        a rdfs:Class ; 
    352367        rdfs:subClassOf atom:TimeUnit ; 
    353         rdfs:label "Audio frames" ; 
     368        rdfs:label "Frames" ; 
    354369        lv2:documentation """ 
    355370<p>Time in audio frames.  Converting this to absolute time depends on the 
    356 sample rate.  When this is the stamp unit for an atom:Sequence, the events in 
    357 that sequence have LV2_Atom_Audio_Time stamps (<code>event.time.audio</code>)</p>""" . 
     371sample rate.  When this is the stamp unit for an atom:Sequence, its events have 
     372int64_t time stamps (<code>event.time.frames</code>)</p> 
     373""" . 
    358374 
    359375atom:Beats 
  • trunk/lv2/lv2plug.in/ns/ext/atom/forge.h

    r559 r561  
    186186} 
    187187 
     188/** 
     189   Write raw output.  This is used internally, but is also useful for writing 
     190   atom types not explicitly supported by the forge API.  Note the caller is 
     191   responsible for ensuring the output is approriately padded. 
     192*/ 
    188193static inline void* 
    189 lv2_atom_forge_write_nopad(LV2_Atom_Forge* forge, 
    190                            const void*     data, 
    191                            uint32_t        size) 
     194lv2_atom_forge_raw(LV2_Atom_Forge* forge, const void* data, uint32_t size) 
    192195{ 
    193196        uint8_t* out = NULL; 
     
    210213} 
    211214 
     215/** Pad output accordingly so next write is 64-bit aligned. */ 
    212216static inline void 
    213 lv2_atom_forge_pad(LV2_Atom_Forge* forge, 
    214                    uint32_t        written) 
     217lv2_atom_forge_pad(LV2_Atom_Forge* forge, uint32_t written) 
    215218{ 
    216219        const uint64_t pad      = 0; 
    217220        const uint32_t pad_size = lv2_atom_pad_size(written) - written; 
    218         lv2_atom_forge_write_nopad(forge, &pad, pad_size); 
    219 } 
    220  
     221        lv2_atom_forge_raw(forge, &pad, pad_size); 
     222} 
     223 
     224/** Write raw output, padding to 64-bits as necessary. */ 
    221225static inline void* 
    222 lv2_atom_forge_write(LV2_Atom_Forge* forge, 
    223                      const void*     data, 
    224                      uint32_t        size) 
    225 { 
    226         void* out = lv2_atom_forge_write_nopad(forge, data, size); 
     226lv2_atom_forge_write(LV2_Atom_Forge* forge, const void* data, uint32_t size) 
     227{ 
     228        void* out = lv2_atom_forge_raw(forge, data, size); 
    227229        if (out) { 
    228230                lv2_atom_forge_pad(forge, size); 
    229231        } 
    230232        return out; 
     233} 
     234 
     235/** Write an atom:Atom header. */ 
     236static inline LV2_Atom* 
     237lv2_atom_forge_atom(LV2_Atom_Forge* forge, uint32_t type, uint32_t size) 
     238{ 
     239        const LV2_Atom a = { type, size }; 
     240        return (LV2_Atom*)lv2_atom_forge_raw(forge, &a, sizeof(a)); 
    231241} 
    232242 
     
    284294lv2_atom_forge_string_body(LV2_Atom_Forge* forge, 
    285295                           const uint8_t*  str, 
    286                            size_t          len) 
     296                           uint32_t        len) 
    287297{ 
    288298        uint8_t* out = NULL; 
    289         if ((out = lv2_atom_forge_write_nopad(forge, str, len)) 
    290             && (out = lv2_atom_forge_write_nopad(forge, "", 1))) { 
     299        if (   (out = lv2_atom_forge_raw(forge, str, len)) 
     300            && (out = lv2_atom_forge_raw(forge, "", 1))) { 
    291301                lv2_atom_forge_pad(forge, len + 1); 
    292302        } 
     
    294304} 
    295305 
    296 /** Write an atom:String.  Note that @p str need not be NULL terminated. */ 
     306/** Write an atom compatible with atom:String.  Used internally. */ 
    297307static inline LV2_Atom_String* 
    298 lv2_atom_forge_string(LV2_Atom_Forge* forge, 
    299                       const uint8_t*  str, 
    300                       size_t          len) 
    301 { 
    302         const LV2_Atom_String a = { { forge->String, len + 1 } }; 
     308lv2_atom_forge_typed_string(LV2_Atom_Forge* forge, 
     309                            uint32_t        type, 
     310                            const uint8_t*  str, 
     311                            uint32_t        len) 
     312{ 
     313        const LV2_Atom_String a = { { type, len + 1 } }; 
    303314        LV2_Atom_String* out = (LV2_Atom_String*) 
    304                 lv2_atom_forge_write_nopad(forge, &a, sizeof(a)); 
     315                lv2_atom_forge_raw(forge, &a, sizeof(a)); 
    305316        if (out) { 
    306317                if (!lv2_atom_forge_string_body(forge, str, len)) { 
     
    313324} 
    314325 
     326/** Write an atom:String.  Note that @p str need not be NULL terminated. */ 
     327static inline LV2_Atom_String* 
     328lv2_atom_forge_string(LV2_Atom_Forge* forge, const uint8_t* str, uint32_t len) 
     329{ 
     330        return lv2_atom_forge_typed_string(forge, forge->String, str, len); 
     331} 
     332 
    315333/** 
    316334   Write an atom:URI.  Note that @p uri need not be NULL terminated. 
     
    319337*/ 
    320338static inline LV2_Atom_String* 
    321 lv2_atom_forge_uri(LV2_Atom_Forge* forge, 
    322                    const uint8_t*  uri, 
    323                    size_t          len) 
    324 { 
    325         const LV2_Atom_String a = { { forge->URI, len + 1 } }; 
    326         LV2_Atom_String* out = (LV2_Atom_String*) 
    327                 lv2_atom_forge_write_nopad(forge, &a, sizeof(a)); 
    328         if (out) { 
    329                 if (!lv2_atom_forge_string_body(forge, uri, len)) { 
    330                         out->atom.type = 0; 
    331                         out->atom.size = 0; 
    332                         out = NULL; 
    333                 } 
    334         } 
    335         return out; 
     339lv2_atom_forge_uri(LV2_Atom_Forge* forge, const uint8_t* uri, uint32_t len) 
     340{ 
     341        return lv2_atom_forge_typed_string(forge, forge->URI, uri, len); 
    336342} 
    337343 
    338344/** Write an atom:Path.  Note that @p path need not be NULL terminated. */ 
    339345static inline LV2_Atom_String* 
    340 lv2_atom_forge_path(LV2_Atom_Forge* forge, 
    341                     const uint8_t*  path, 
    342                     size_t          len) 
    343 { 
    344         const LV2_Atom_String a = { { forge->Path, len + 1 } }; 
    345         LV2_Atom_String* out = (LV2_Atom_String*) 
    346                 lv2_atom_forge_write_nopad(forge, &a, sizeof(a)); 
    347         if (out) { 
    348                 if (!lv2_atom_forge_string_body(forge, path, len)) { 
    349                         out->atom.type = 0; 
    350                         out->atom.size = 0; 
    351                         out = NULL; 
    352                 } 
    353         } 
    354         return out; 
     346lv2_atom_forge_path(LV2_Atom_Forge* forge, const uint8_t* path, uint32_t len) 
     347{ 
     348        return lv2_atom_forge_typed_string(forge, forge->Path, path, len); 
    355349} 
    356350 
     
    359353lv2_atom_forge_literal(LV2_Atom_Forge* forge, 
    360354                       const uint8_t*  str, 
    361                        size_t          len, 
     355                       uint32_t        len, 
    362356                       uint32_t        datatype, 
    363357                       uint32_t        lang) 
     
    366360                { forge->Literal, 
    367361                  sizeof(LV2_Atom_Literal) - sizeof(LV2_Atom) + len + 1 }, 
    368                 datatype, 
    369                 lang 
     362                { datatype, 
     363                  lang } 
    370364        }; 
    371365        LV2_Atom_Literal* out = (LV2_Atom_Literal*) 
    372                 lv2_atom_forge_write_nopad(forge, &a, sizeof(a)); 
     366                lv2_atom_forge_raw(forge, &a, sizeof(a)); 
    373367        if (out) { 
    374368                if (!lv2_atom_forge_string_body(forge, str, len)) { 
     
    388382                           uint32_t        elem_size) 
    389383{ 
    390         const size_t size = sizeof(LV2_Atom_Vector) + (elem_size * elem_count); 
     384        const uint32_t size = sizeof(LV2_Atom_Vector) + (elem_size * elem_count); 
    391385        const LV2_Atom_Vector a = { 
    392386                { forge->Vector, size - sizeof(LV2_Atom) }, 
    393                 elem_count, 
    394                 elem_type 
     387                { elem_count, elem_type } 
    395388        }; 
    396389        return (LV2_Atom_Vector*)lv2_atom_forge_write(forge, &a, sizeof(a)); 
     
    470463        const LV2_Atom_Object a = { 
    471464                { forge->Resource, sizeof(LV2_Atom_Object) - sizeof(LV2_Atom) }, 
    472                 id, 
    473                 otype 
     465                { id, otype } 
    474466        }; 
    475467        LV2_Atom* atom = (LV2_Atom*)lv2_atom_forge_write(forge, &a, sizeof(a)); 
     
    488480        const LV2_Atom_Object a = { 
    489481                { forge->Blank, sizeof(LV2_Atom_Object) - sizeof(LV2_Atom) }, 
    490                 id, 
    491                 otype 
     482                { id, otype } 
    492483        }; 
    493484        LV2_Atom* atom = (LV2_Atom*)lv2_atom_forge_write(forge, &a, sizeof(a)); 
     
    521512        const LV2_Atom_Sequence a = { 
    522513                { forge->Sequence, sizeof(LV2_Atom_Sequence) - sizeof(LV2_Atom) }, 
    523                 unit, 
    524                 0 
     514                { unit, 0 } 
    525515        }; 
    526516        LV2_Atom* atom = (LV2_Atom*)lv2_atom_forge_write(forge, &a, sizeof(a)); 
     
    533523   the same @p parent parameter.  Note the returned LV2_Event is NOT an Atom. 
    534524*/ 
    535 static inline LV2_Atom_Audio_Time* 
    536 lv2_atom_forge_audio_time(LV2_Atom_Forge* forge, 
    537                           uint32_t        frames, 
    538                           uint32_t        subframes) 
    539 { 
    540         const LV2_Atom_Audio_Time a = { frames, subframes }; 
    541         return (LV2_Atom_Audio_Time*)lv2_atom_forge_write(forge, &a, sizeof(a)); 
     525static inline int64_t* 
     526lv2_atom_forge_frame_time(LV2_Atom_Forge* forge, int64_t frames) 
     527{ 
     528        return (int64_t*)lv2_atom_forge_write(forge, &frames, sizeof(frames)); 
    542529} 
    543530 
     
    548535*/ 
    549536static inline double* 
    550 lv2_atom_forge_beat_time(LV2_Atom_Forge* forge, 
    551                          double          beats) 
     537lv2_atom_forge_beat_time(LV2_Atom_Forge* forge, double beats) 
    552538{ 
    553539        return (double*)lv2_atom_forge_write(forge, &beats, sizeof(beats)); 
  • trunk/lv2/lv2plug.in/ns/ext/atom/manifest.ttl

    r556 r561  
    55        a lv2:Specification ; 
    66        lv2:minorVersion 0 ; 
    7         lv2:microVersion 5 ; 
     7        lv2:microVersion 6 ; 
    88        rdfs:seeAlso <atom.ttl> . 
  • trunk/lv2/lv2plug.in/ns/ext/atom/util.h

    r556 r561  
    6363lv2_atom_equals(const LV2_Atom* a, const LV2_Atom* b) 
    6464{ 
    65         return (a == b) || ( 
    66                 (a->type == b->type) && 
    67                 (a->size == b->size) && 
    68                 !memcmp(LV2_ATOM_CONTENTS(LV2_Atom, a), 
    69                         LV2_ATOM_CONTENTS(LV2_Atom, b), 
    70                         a->size)); 
     65        return (a == b) || ((a->type == b->type) && 
     66                            (a->size == b->size) && 
     67                            !memcmp(a + 1, b + 1, a->size)); 
    7168} 
    7269 
     
    7976typedef LV2_Atom_Event* LV2_Atom_Sequence_Iter; 
    8077 
    81 /** Get an iterator pointing to the first element in @p tup. */ 
     78/** Get an iterator pointing to the first element in a Sequence body. */ 
     79static inline LV2_Atom_Sequence_Iter 
     80lv2_sequence_body_begin(const LV2_Atom_Sequence_Body* body) 
     81{ 
     82        return (LV2_Atom_Sequence_Iter)(body + 1); 
     83} 
     84 
     85/** Get an iterator pointing to the first element in a Sequence. */ 
    8286static inline LV2_Atom_Sequence_Iter 
    8387lv2_sequence_begin(const LV2_Atom_Sequence* seq) 
    8488{ 
    85         return (LV2_Atom_Sequence_Iter)(LV2_ATOM_CONTENTS(LV2_Atom_Sequence, seq)); 
    86 } 
    87  
    88 /** Return true iff @p i has reached the end of @p tup. */ 
     89        return (LV2_Atom_Sequence_Iter)(seq + 1); 
     90} 
     91 
     92/** Return true iff @p i has reached the end of @p body. */ 
     93static inline bool 
     94lv2_sequence_body_is_end(const LV2_Atom_Sequence_Body* body, 
     95                         uint32_t                      size, 
     96                         LV2_Atom_Sequence_Iter        i) 
     97{ 
     98        return (uint8_t*)i >= ((uint8_t*)body + size); 
     99} 
     100 
     101/** Return true iff @p i has reached the end of @p seq. */ 
    89102static inline bool 
    90103lv2_sequence_is_end(const LV2_Atom_Sequence* seq, LV2_Atom_Sequence_Iter i) 
     
    127140             (iter) = lv2_sequence_iter_next(iter)) 
    128141 
     142/** A version of LV2_SEQUENCE_FOREACH for when only the body is available. */ 
     143#define LV2_SEQUENCE_BODY_FOREACH(body, size, iter) \ 
     144        for (LV2_Atom_Sequence_Iter (iter) = lv2_sequence_body_begin(body); \ 
     145             !lv2_sequence_body_is_end(body, size, (iter)); \ 
     146             (iter) = lv2_sequence_iter_next(iter)) 
     147 
    129148/** 
    130149   @} 
     
    143162} 
    144163 
     164/** Return true iff @p i has reached the end of @p body. */ 
     165static inline bool 
     166lv2_atom_tuple_body_is_end(const void*         body, 
     167                           uint32_t            size, 
     168                           LV2_Atom_Tuple_Iter i) 
     169{ 
     170        return (uint8_t*)i >= ((uint8_t*)body + size); 
     171} 
     172 
    145173/** Return true iff @p i has reached the end of @p tup. */ 
    146174static inline bool 
    147175lv2_tuple_is_end(const LV2_Atom_Tuple* tup, LV2_Atom_Tuple_Iter i) 
    148176{ 
    149         return (uint8_t*)i >= ((uint8_t*)tup + sizeof(LV2_Atom) + tup->atom.size); 
     177        return lv2_atom_tuple_body_is_end(LV2_ATOM_BODY(tup), tup->atom.size, i); 
    150178} 
    151179 
     
    183211             (iter) = lv2_tuple_iter_next(iter)) 
    184212 
     213/** A version of LV2_TUPLE_FOREACH for when only the body is available. */ 
     214#define LV2_TUPLE_BODY_FOREACH(body, size, iter) \ 
     215        for (LV2_Atom_Tuple_Iter (iter) = (LV2_Atom_Tuple_Iter)body; \ 
     216             !lv2_atom_tuple_body_is_end(body, size, (iter)); \ 
     217             (iter) = lv2_tuple_iter_next(iter)) 
     218 
    185219/** 
    186220   @} 
     
    192226typedef LV2_Atom_Property_Body* LV2_Atom_Object_Iter; 
    193227 
     228static inline LV2_Atom_Object_Iter 
     229lv2_object_body_begin(const LV2_Atom_Object_Body* body) 
     230{ 
     231        return (LV2_Atom_Object_Iter)(body + 1); 
     232} 
     233 
    194234/** Get an iterator pointing to the first property in @p obj. */ 
    195235static inline LV2_Atom_Object_Iter 
    196236lv2_object_begin(const LV2_Atom_Object* obj) 
    197237{ 
    198         return (LV2_Atom_Object_Iter)(LV2_ATOM_CONTENTS(LV2_Atom_Object, obj)); 
     238        return (LV2_Atom_Object_Iter)(obj + 1); 
     239} 
     240 
     241static inline bool 
     242lv2_atom_object_body_is_end(const LV2_Atom_Object_Body* body, 
     243                            uint32_t                    size, 
     244                            LV2_Atom_Object_Iter        i) 
     245{ 
     246        return (uint8_t*)i >= ((uint8_t*)body + size); 
    199247} 
    200248 
     
    204252{ 
    205253        return (uint8_t*)i >= ((uint8_t*)obj + sizeof(LV2_Atom) + obj->atom.size); 
    206 } 
    207  
    208 /** Return true iff @p l points to the same property as @p r. */ 
    209 static inline bool 
    210 lv2_object_iter_equals(const LV2_Atom_Object_Iter l, 
    211                        const LV2_Atom_Object_Iter r) 
    212 { 
    213         return l == r; 
    214254} 
    215255 
     
    247287        for (LV2_Atom_Object_Iter (iter) = lv2_object_begin(object); \ 
    248288             !lv2_object_is_end(object, (iter)); \ 
     289             (iter) = lv2_object_iter_next(iter)) 
     290 
     291/** A version of LV2_OBJECT_FOREACH for when only the body is available. */ 
     292#define LV2_OBJECT_BODY_FOREACH(body, size, iter) \ 
     293        for (LV2_Atom_Object_Iter (iter) = lv2_object_body_begin(body); \ 
     294             !lv2_atom_object_body_is_end(body, size, (iter)); \ 
    249295             (iter) = lv2_object_iter_next(iter)) 
    250296 
  • trunk/plugins/eg-sampler.lv2/sampler.c

    r555 r561  
    336336                        uint8_t* const data = (uint8_t* const)(ev + 1); 
    337337                        if ((data[0] & 0xF0) == 0x90) { 
    338                                 start_frame   = ev->time.audio.frames; 
     338                                start_frame   = ev->time.frames; 
    339339                                plugin->frame = 0; 
    340340                                plugin->play  = true; 
     
    342342                } else if (is_object_type(uris, ev->body.type)) { 
    343343                        const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body; 
    344                         if (obj->otype == uris->msg_Set) { 
     344                        if (obj->body.otype == uris->msg_Set) { 
    345345                                /* Received a set message, send it to the worker thread. */ 
    346346                                fprintf(stderr, "Queueing set message\n"); 
     
    351351                                zix_sem_post(&plugin->signal); 
    352352                        } else { 
    353                                 fprintf(stderr, "Unknown object type %d\n", obj->otype); 
     353                                fprintf(stderr, "Unknown object type %d\n", obj->body.otype); 
    354354                        } 
    355355                } else { 
     
    411411 
    412412                        /* Send a notification that we're using a new sample. */ 
    413                         lv2_atom_forge_audio_time(&plugin->forge, 0, 0); 
     413                        lv2_atom_forge_frame_time(&plugin->forge, 0); 
    414414                        write_set_file(&plugin->forge, uris, 
    415415                                       plugin->sample->path, 
  • trunk/plugins/eg-sampler.lv2/uris.h

    r556 r561  
    108108              const LV2_Atom_Object* obj) 
    109109{ 
    110         if (obj->otype != uris->msg_Set) { 
    111                 fprintf(stderr, "Ignoring unknown message type %d\n", obj->otype); 
     110        if (obj->body.otype != uris->msg_Set) { 
     111                fprintf(stderr, "Ignoring unknown message type %d\n", obj->body.otype); 
    112112                return NULL; 
    113113        }