mas01cr@554
|
1 #include <sys/types.h>
|
mas01cr@553
|
2 #include <sys/stat.h>
|
mas01cr@554
|
3 #include <unistd.h>
|
mas01cr@553
|
4 #include <librdf.h>
|
mas01cr@553
|
5 #include <fcntl.h>
|
mas01cr@553
|
6 #include <string.h>
|
mas01cr@553
|
7 #include <stdlib.h>
|
mas01cr@553
|
8
|
mas01cr@553
|
9 #include <audioDB_API.h>
|
mas01cr@553
|
10
|
mas01cr@553
|
11 const char * qstring =
|
mas01cr@553
|
12 " PREFIX af: <http://purl.org/ontology/af/>"
|
mas01cr@553
|
13 " PREFIX dc: <http://purl.org/dc/elements/1.1/>"
|
mas01cr@553
|
14 " PREFIX mo: <http://purl.org/ontology/mo/>"
|
mas01cr@553
|
15 " PREFIX tl: <http://purl.org/NET/c4dm/timeline.owl#>"
|
mas01cr@553
|
16
|
mas01mj@583
|
17 " SELECT ?key ?value ?sample_rate ?window_length ?hop_size ?dimensions ?typetitle"
|
mas01mj@583
|
18 " FROM <file:///home/csr21/tmp/rdf/test2.n3> "
|
mas01cr@553
|
19
|
mas01cr@553
|
20 " WHERE { "
|
mas01mj@583
|
21 " ?key a mo:AudioFile . "
|
mas01mj@583
|
22 " ?signal a mo:Signal . "
|
mas01mj@583
|
23 " ?key mo:encodes ?signal ."
|
mas01cr@553
|
24 " ?signal mo:time [ tl:onTimeLine ?signal_timeline ] . "
|
mas01cr@553
|
25
|
mas01cr@553
|
26 " ?timeline_map a tl:UniformSamplingWindowingMap ; "
|
mas01cr@553
|
27 " tl:rangeTimeLine ?feature_timeline ; "
|
mas01cr@553
|
28 " tl:domainTimeLine ?signal_timeline ; "
|
mas01cr@553
|
29 " tl:sampleRate ?sample_rate ; "
|
mas01cr@553
|
30 " tl:windowLength ?window_length ; "
|
mas01cr@553
|
31 " tl:hopSize ?hop_size . "
|
mas01cr@553
|
32
|
mas01cr@553
|
33 " ?signal af:signal_feature ?feature . "
|
mas01cr@553
|
34
|
mas01cr@553
|
35 " ?feature a ?feature_signal_type ; "
|
mas01cr@553
|
36 " mo:time [ tl:onTimeLine ?feature_timeline ] ; "
|
mas01cr@553
|
37 " af:value ?value . "
|
mas01mj@583
|
38 " ?feature af:dimensions ?dimensions ."
|
mas01cr@553
|
39
|
mas01mj@583
|
40 " ?feature_signal_type dc:title ?typetitle "
|
mas01cr@553
|
41
|
mas01cr@553
|
42 " } "
|
mas01cr@553
|
43 ;
|
mas01cr@553
|
44
|
mas01cr@553
|
45 double *parse_value_string(const char *value_string, size_t *nelements) {
|
mas01cr@553
|
46 /* What error checking? */
|
mas01cr@553
|
47
|
mas01mj@583
|
48
|
mas01cr@553
|
49 *nelements = 0;
|
mas01cr@553
|
50
|
mas01cr@553
|
51 const char *current = value_string;
|
mas01cr@553
|
52 char *next = 0;
|
mas01cr@553
|
53
|
mas01cr@553
|
54 size_t size = 1;
|
mas01cr@553
|
55 double *buf = (double *) malloc(size * sizeof(double));
|
mas01cr@553
|
56 double value = strtod(current, &next);
|
mas01cr@553
|
57 while(next != current) {
|
mas01cr@553
|
58 buf[(*nelements)++] = value;
|
mas01cr@553
|
59 if((*nelements) == size) {
|
mas01cr@553
|
60 size *= 2;
|
mas01cr@553
|
61 buf = (double *) realloc(buf, 2 * size * sizeof(double));
|
mas01cr@553
|
62 }
|
mas01cr@553
|
63 current = next;
|
mas01cr@553
|
64 value = strtod(current, &next);
|
mas01cr@553
|
65 }
|
mas01cr@571
|
66 return buf;
|
mas01cr@553
|
67 }
|
mas01cr@553
|
68
|
mas01mj@583
|
69 int main(int argc, char* argv[]) {
|
mas01mj@583
|
70
|
mas01mj@583
|
71 if(argc != 3)
|
mas01mj@583
|
72 {
|
mas01mj@583
|
73 fprintf(stderr, "Usage: %s <n3file> <dbfile>\n", argv[0]);
|
mas01mj@583
|
74 return 2;
|
mas01mj@583
|
75 }
|
mas01mj@583
|
76
|
mas01mj@583
|
77 char* n3file = argv[1];
|
mas01mj@583
|
78 char* dbfile = argv[2];
|
mas01mj@583
|
79
|
mas01cr@554
|
80 librdf_world *world;
|
mas01cr@554
|
81 if (!(world = librdf_new_world()))
|
mas01cr@554
|
82 goto librdf_error;
|
mas01cr@553
|
83
|
mas01cr@554
|
84 librdf_storage *storage;
|
mas01cr@554
|
85 if (!(storage = librdf_new_storage(world, "memory", NULL, NULL)))
|
mas01cr@554
|
86 goto librdf_error;
|
mas01cr@553
|
87
|
mas01cr@554
|
88 librdf_model *model;
|
mas01cr@554
|
89 if (!(model = librdf_new_model(world, storage, NULL)))
|
mas01cr@554
|
90 goto librdf_error;
|
mas01mj@583
|
91
|
mas01mj@583
|
92
|
mas01mj@583
|
93 char *fileUri = malloc(sizeof(char)*(strlen(n3file)+6));
|
mas01mj@583
|
94 sprintf(fileUri, "file:%s\0", n3file);
|
mas01cr@553
|
95
|
mas01cr@554
|
96 librdf_uri *uri;
|
mas01mj@583
|
97 if (!(uri = librdf_new_uri(world, fileUri)))
|
mas01cr@554
|
98 goto librdf_error;
|
mas01cr@553
|
99
|
mas01mj@583
|
100 free(fileUri);
|
mas01mj@583
|
101
|
mas01cr@554
|
102 librdf_parser *parser;
|
mas01cr@554
|
103 if (!(parser = librdf_new_parser(world, "guess", NULL, NULL)))
|
mas01cr@554
|
104 goto librdf_error;
|
mas01cr@553
|
105
|
mas01cr@554
|
106 if(librdf_parser_parse_into_model(parser, uri, NULL, model))
|
mas01cr@554
|
107 goto librdf_error;
|
mas01cr@553
|
108
|
mas01cr@554
|
109 librdf_query *query;
|
mas01cr@554
|
110 if (!(query = librdf_new_query(world, "sparql", NULL, qstring, NULL)))
|
mas01cr@554
|
111 goto librdf_error;
|
mas01cr@553
|
112
|
mas01cr@554
|
113 librdf_query_results *results;
|
mas01cr@554
|
114 if (!(results = librdf_query_execute(query, model)))
|
mas01cr@554
|
115 goto librdf_error;
|
mas01cr@553
|
116
|
mas01cr@554
|
117 if(!librdf_query_results_is_bindings(results))
|
mas01cr@554
|
118 goto librdf_error;
|
mas01cr@554
|
119
|
mas01cr@554
|
120 adb_t *adb;
|
mas01mj@583
|
121 if(!(adb = audiodb_open(dbfile, O_RDWR))) {
|
mas01mj@583
|
122
|
mas01cr@554
|
123 struct stat st;
|
mas01mj@583
|
124 if(!(stat(dbfile, &st))) {
|
mas01mj@583
|
125 fprintf(stderr, "%s not opened.\n", dbfile);
|
mas01cr@554
|
126 return 1;
|
mas01cr@554
|
127 } else {
|
mas01cr@554
|
128 /* FIXME: if we are doing a proper SPARQL query over a
|
mas01cr@554
|
129 * potentially unbounded number of results, we could use
|
mas01cr@554
|
130 * librdf_query_results_get_count() to estimate how much space
|
mas01cr@554
|
131 * our database will need.
|
mas01cr@554
|
132
|
mas01cr@554
|
133 * If we're doing a SPARQL query over a number of RDF files,
|
mas01cr@554
|
134 * with an expected number of datasets per file of 1 (as might
|
mas01cr@554
|
135 * be produced by runner(?)) then obviously we can use that as
|
mas01cr@554
|
136 * an estimate of number of tracks instead.
|
mas01cr@554
|
137
|
mas01cr@554
|
138 * Specifying the data dimensionality should be easy from the
|
mas01cr@554
|
139 * semantics of the feature being inserted; it's not immediately
|
mas01cr@554
|
140 * obvious to me how to estimate the data size required, unless
|
mas01cr@554
|
141 * we maybe do a preliminary query to find out the total time
|
mas01cr@554
|
142 * (or similar) of all the tracks we're about to insert.
|
mas01cr@554
|
143
|
mas01cr@554
|
144 * (also NOTE: this audiodb_create() interface is scheduled for
|
mas01cr@554
|
145 * being made less inelegant.) */
|
mas01mj@583
|
146 if(!(adb = audiodb_create(dbfile, 0, 0, 0))) {
|
mas01mj@583
|
147 fprintf(stderr, "failed to create %s.\n", dbfile);
|
mas01cr@554
|
148 return 1;
|
mas01cr@554
|
149 }
|
mas01cr@554
|
150 }
|
mas01cr@553
|
151 }
|
mas01cr@554
|
152
|
mas01mj@583
|
153 if(librdf_query_results_finished(results))
|
mas01mj@583
|
154 {
|
mas01mj@583
|
155 fprintf(stderr, "No features found!\n");
|
mas01mj@583
|
156 return 3;
|
mas01mj@583
|
157 }
|
mas01mj@583
|
158
|
mas01mj@583
|
159
|
mas01cr@553
|
160 while(!librdf_query_results_finished(results)) {
|
mas01mj@583
|
161
|
mas01cr@553
|
162 adb_datum_t datum = {0};
|
mas01mj@583
|
163
|
mas01mj@583
|
164 // Pull out the dimension
|
mas01mj@583
|
165
|
mas01mj@583
|
166 librdf_node *node = librdf_query_results_get_binding_value_by_name(results, "dimensions");
|
mas01mj@583
|
167 char* dimensions = librdf_node_get_literal_value(node);
|
mas01mj@583
|
168
|
mas01mj@583
|
169 int dimension = 0;
|
mas01mj@583
|
170 sscanf(dimensions, "%d", &dimension);
|
mas01mj@583
|
171 datum.dim = dimension;
|
mas01mj@583
|
172
|
mas01mj@583
|
173 node = librdf_query_results_get_binding_value_by_name(results, "typetitle");
|
mas01mj@583
|
174 printf("Insert feature of type %s\n", librdf_node_get_literal_value(node));
|
mas01mj@583
|
175
|
mas01mj@583
|
176 // Grab key and value
|
mas01mj@583
|
177
|
mas01mj@583
|
178 node = librdf_query_results_get_binding_value_by_name(results, "key");
|
mas01mj@583
|
179 datum.key = librdf_uri_as_string(librdf_node_get_uri(node));
|
mas01mj@583
|
180
|
mas01mj@583
|
181 size_t nelements = 0;
|
mas01mj@583
|
182 node = librdf_query_results_get_binding_value_by_name(results, "value");
|
mas01mj@583
|
183 datum.data = parse_value_string(librdf_node_get_literal_value(node), &nelements);
|
mas01mj@583
|
184
|
mas01mj@583
|
185 // Validate that we have the correct number of elements
|
mas01mj@583
|
186
|
mas01mj@583
|
187 if(nelements % dimension) return 4;
|
mas01mj@583
|
188 datum.nvectors = nelements / dimension;
|
mas01mj@583
|
189
|
mas01mj@583
|
190 printf("Dimension: %d\n", dimension);
|
mas01mj@583
|
191 printf("Key: %s\n", datum.key);
|
mas01mj@583
|
192 printf("Vectors: %d\n", datum.nvectors);
|
mas01mj@583
|
193
|
mas01mj@583
|
194 librdf_free_node(node);
|
mas01mj@583
|
195
|
mas01cr@553
|
196 if(audiodb_insert_datum(adb, &datum)) {
|
mas01cr@554
|
197 fprintf(stderr, "failed to insert datum with key %s.\n", datum.key);
|
mas01cr@554
|
198 return 1;
|
mas01cr@553
|
199 }
|
mas01cr@571
|
200 free(datum.data);
|
mas01cr@553
|
201 librdf_query_results_next(results);
|
mas01cr@553
|
202 }
|
mas01cr@553
|
203
|
mas01cr@553
|
204 audiodb_close(adb);
|
mas01cr@553
|
205 librdf_free_query_results(results);
|
mas01cr@553
|
206 librdf_free_query(query);
|
mas01cr@571
|
207 librdf_free_parser(parser);
|
mas01cr@553
|
208 librdf_free_uri(uri);
|
mas01cr@553
|
209 librdf_free_model(model);
|
mas01cr@553
|
210 librdf_free_storage(storage);
|
mas01cr@553
|
211 librdf_free_world(world);
|
mas01cr@554
|
212
|
mas01cr@554
|
213 return 0;
|
mas01cr@554
|
214
|
mas01cr@554
|
215 librdf_error:
|
mas01cr@554
|
216 fprintf(stderr, "Something went wrong in librdf.\n");
|
mas01cr@554
|
217 return 1;
|
mas01cr@553
|
218 }
|