1 /*
2  * Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch)
3  *
4  * This is free software: you can redistribute it and/or modify
5  * it under the terms of the Artistic License 2.0 as published by
6  * The Perl Foundation.
7  *
8  * This source is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * Artistic License 2.0 for more details.
12  *
13  * You should have received a copy of the Artistic License 2.0
14  * along the source as a COPYING file. If not, obtain it from
15  * http://www.perlfoundation.org/artistic_license_2_0.
16  */
17 
18 #ifndef LV2_OSC_H
19 #define LV2_OSC_H
20 
21 #include <stdint.h>
22 
23 #include <lv2/lv2plug.in/ns/ext/urid/urid.h>
24 #include <lv2/lv2plug.in/ns/ext/atom/atom.h>
25 #include <lv2/lv2plug.in/ns/ext/midi/midi.h>
26 
27 #define LV2_OSC_URI                 "http://open-music-kontrollers.ch/lv2/osc"
28 #define LV2_OSC_PREFIX              LV2_OSC_URI "#"
29 
30 #define LV2_OSC__Event              LV2_OSC_PREFIX "Event" // atom message type
31 #define LV2_OSC__schedule           LV2_OSC_PREFIX "schedule" // feature
32 
33 #define LV2_OSC__Packet             LV2_OSC_PREFIX "Packet" // atom object type
34 
35 #define LV2_OSC__Bundle             LV2_OSC_PREFIX "Bundle" // atom object type
36 #define LV2_OSC__bundleTimetag      LV2_OSC_PREFIX "bundleTimetag" // atom object property
37 #define LV2_OSC__bundleItems        LV2_OSC_PREFIX "bundleItems"
38 
39 #define LV2_OSC__Message            LV2_OSC_PREFIX "Message" // atom object type
40 #define LV2_OSC__messagePath        LV2_OSC_PREFIX "messagePath" // atom object property
41 #define LV2_OSC__messageArguments   LV2_OSC_PREFIX "messageArguments" // atom object property
42 
43 #define LV2_OSC__Timetag            LV2_OSC_PREFIX "Timetag" // atom object type
44 #define LV2_OSC__timetagIntegral    LV2_OSC_PREFIX "timetagIntegral" // atom object property
45 #define LV2_OSC__timetagFraction    LV2_OSC_PREFIX "timetagFraction" // atom object property
46 
47 #define LV2_OSC__Nil                LV2_OSC_PREFIX "Nil" // atom literal type
48 #define LV2_OSC__Impulse            LV2_OSC_PREFIX "Impulse" // atom literal type
49 #define LV2_OSC__Char               LV2_OSC_PREFIX "Char" // atom literal type
50 #define LV2_OSC__RGBA               LV2_OSC_PREFIX "RGBA" // atom literal type
51 
52 #define LV2_OSC_PADDED_SIZE(size) ( ( (size_t)(size) + 3 ) & ( ~3 ) )
53 #define LV2_OSC_IMMEDIATE         1ULL
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 typedef void *LV2_OSC_Schedule_Handle;
60 
61 typedef double (*LV2_OSC_Schedule_OSC2Frames)(
62 	LV2_OSC_Schedule_Handle handle,
63 	uint64_t timetag);
64 
65 typedef uint64_t (*LV2_OSC_Schedule_Frames2OSC)(
66 	LV2_OSC_Schedule_Handle handle,
67 	double frames);
68 
69 typedef struct _LV2_OSC_Schedule {
70 	LV2_OSC_Schedule_Handle handle;
71 	LV2_OSC_Schedule_OSC2Frames osc2frames;
72 	LV2_OSC_Schedule_Frames2OSC frames2osc;
73 } LV2_OSC_Schedule;
74 
75 typedef enum LV2_OSC_Type {
76 	LV2_OSC_INT32   =	'i',
77 	LV2_OSC_FLOAT   =	'f',
78 	LV2_OSC_STRING  =	's',
79 	LV2_OSC_BLOB    =	'b',
80 
81 	LV2_OSC_TRUE    =	'T',
82 	LV2_OSC_FALSE   =	'F',
83 	LV2_OSC_NIL     =	'N',
84 	LV2_OSC_IMPULSE =	'I',
85 
86 	LV2_OSC_INT64   =	'h',
87 	LV2_OSC_DOUBLE  =	'd',
88 	LV2_OSC_TIMETAG =	't',
89 
90 	LV2_OSC_SYMBOL  =	'S',
91 	LV2_OSC_CHAR    =	'c',
92 	LV2_OSC_MIDI    =	'm',
93 	LV2_OSC_RGBA    =	'r'
94 } LV2_OSC_Type;
95 
96 union swap32_t {
97 	uint32_t u;
98 
99 	int32_t i;
100 	float f;
101 };
102 
103 union swap64_t {
104 	uint64_t u;
105 
106 	int64_t h;
107 	uint64_t t;
108 	double d;
109 };
110 
111 typedef struct _LV2_OSC_Timetag {
112 	uint32_t integral;
113 	uint32_t fraction;
114 } LV2_OSC_Timetag;
115 
116 typedef struct _LV2_OSC_URID {
117 	LV2_URID OSC_Packet;
118 
119 	LV2_URID OSC_Bundle;
120 	LV2_URID OSC_bundleTimetag;
121 	LV2_URID OSC_bundleItems;
122 
123 	LV2_URID OSC_Message;
124 	LV2_URID OSC_messagePath;
125 	LV2_URID OSC_messageArguments;
126 
127 	LV2_URID OSC_Timetag;
128 	LV2_URID OSC_timetagIntegral;
129 	LV2_URID OSC_timetagFraction;
130 
131 	LV2_URID OSC_Nil;
132 	LV2_URID OSC_Impulse;
133 	LV2_URID OSC_Char;
134 	LV2_URID OSC_RGBA;
135 
136 	LV2_URID MIDI_MidiEvent;
137 
138 	LV2_URID ATOM_Int;
139 	LV2_URID ATOM_Long;
140 	LV2_URID ATOM_String;
141 	LV2_URID ATOM_Literal;
142 	LV2_URID ATOM_Float;
143 	LV2_URID ATOM_Double;
144 	LV2_URID ATOM_URID;
145 	LV2_URID ATOM_Bool;
146 	LV2_URID ATOM_Tuple;
147 	LV2_URID ATOM_Object;
148 	LV2_URID ATOM_Chunk;
149 } LV2_OSC_URID;
150 
151 static inline void
lv2_osc_urid_init(LV2_OSC_URID * osc_urid,LV2_URID_Map * map)152 lv2_osc_urid_init(LV2_OSC_URID *osc_urid, LV2_URID_Map *map)
153 {
154 	osc_urid->OSC_Packet = map->map(map->handle, LV2_OSC__Packet);
155 
156 	osc_urid->OSC_Bundle = map->map(map->handle, LV2_OSC__Bundle);
157 	osc_urid->OSC_bundleTimetag = map->map(map->handle, LV2_OSC__bundleTimetag);
158 	osc_urid->OSC_bundleItems = map->map(map->handle, LV2_OSC__bundleItems);
159 
160 	osc_urid->OSC_Message = map->map(map->handle, LV2_OSC__Message);
161 	osc_urid->OSC_messagePath = map->map(map->handle, LV2_OSC__messagePath);
162 	osc_urid->OSC_messageArguments = map->map(map->handle, LV2_OSC__messageArguments);
163 
164 	osc_urid->OSC_Timetag = map->map(map->handle, LV2_OSC__Timetag);
165 	osc_urid->OSC_timetagIntegral = map->map(map->handle, LV2_OSC__timetagIntegral);
166 	osc_urid->OSC_timetagFraction = map->map(map->handle, LV2_OSC__timetagFraction);
167 
168 	osc_urid->OSC_Nil = map->map(map->handle, LV2_OSC__Nil);
169 	osc_urid->OSC_Impulse = map->map(map->handle, LV2_OSC__Impulse);
170 	osc_urid->OSC_Char = map->map(map->handle, LV2_OSC__Char);
171 	osc_urid->OSC_RGBA = map->map(map->handle, LV2_OSC__RGBA);
172 
173 	osc_urid->MIDI_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent);
174 
175 	osc_urid->ATOM_Int = map->map(map->handle, LV2_ATOM__Int);
176 	osc_urid->ATOM_Long = map->map(map->handle, LV2_ATOM__Long);
177 	osc_urid->ATOM_String = map->map(map->handle, LV2_ATOM__String);
178 	osc_urid->ATOM_Literal = map->map(map->handle, LV2_ATOM__Literal);
179 	osc_urid->ATOM_Float = map->map(map->handle, LV2_ATOM__Float);
180 	osc_urid->ATOM_Double = map->map(map->handle, LV2_ATOM__Double);
181 	osc_urid->ATOM_URID = map->map(map->handle, LV2_ATOM__URID);
182 	osc_urid->ATOM_Bool = map->map(map->handle, LV2_ATOM__Bool);
183 	osc_urid->ATOM_Tuple = map->map(map->handle, LV2_ATOM__Tuple);
184 	osc_urid->ATOM_Object = map->map(map->handle, LV2_ATOM__Object);
185 	osc_urid->ATOM_Chunk = map->map(map->handle, LV2_ATOM__Chunk);
186 }
187 
188 #ifdef __cplusplus
189 } // extern "C"
190 #endif
191 
192 #endif // LV2_OSC_H
193