mas01cr@554: #include mas01cr@553: #include mas01cr@644: #include mas01cr@554: #include mas01cr@553: #include mas01cr@553: #include mas01cr@553: #include mas01cr@553: #include mas01cr@553: mas01cr@553: #include mas01cr@553: mas01cr@553: const char * qstring = mas01cr@553: " PREFIX af: " mas01cr@553: " PREFIX dc: " mas01cr@553: " PREFIX mo: " mas01cr@553: " PREFIX tl: " mas01cr@553: mas01cr@644: " SELECT ?key ?value ?sample_rate ?window_length ?hop_size ?dimensions" mas01cr@553: mas01cr@553: " WHERE { " mas01mj@583: " ?key a mo:AudioFile . " mas01mj@583: " ?signal a mo:Signal . " mas01mj@583: " ?key mo:encodes ?signal ." mas01cr@553: " ?signal mo:time [ tl:onTimeLine ?signal_timeline ] . " mas01cr@553: mas01cr@553: " ?timeline_map a tl:UniformSamplingWindowingMap ; " mas01cr@553: " tl:rangeTimeLine ?feature_timeline ; " mas01cr@553: " tl:domainTimeLine ?signal_timeline ; " mas01cr@553: " tl:sampleRate ?sample_rate ; " mas01cr@553: " tl:windowLength ?window_length ; " mas01cr@553: " tl:hopSize ?hop_size . " mas01cr@553: mas01cr@553: " ?signal af:signal_feature ?feature . " mas01cr@553: mas01cr@553: " ?feature a ?feature_signal_type ; " mas01cr@553: " mo:time [ tl:onTimeLine ?feature_timeline ] ; " mas01cr@553: " af:value ?value . " mas01mj@583: " ?feature af:dimensions ?dimensions ." mas01cr@553: mas01cr@553: " } " mas01cr@553: ; mas01cr@553: mas01cr@553: double *parse_value_string(const char *value_string, size_t *nelements) { mas01cr@553: /* What error checking? */ mas01cr@553: mas01mj@583: mas01cr@553: *nelements = 0; mas01cr@553: mas01cr@553: const char *current = value_string; mas01cr@553: char *next = 0; mas01cr@553: mas01cr@553: size_t size = 1; mas01cr@553: double *buf = (double *) malloc(size * sizeof(double)); mas01cr@553: double value = strtod(current, &next); mas01cr@553: while(next != current) { mas01cr@553: buf[(*nelements)++] = value; mas01cr@553: if((*nelements) == size) { mas01cr@553: size *= 2; mas01cr@553: buf = (double *) realloc(buf, 2 * size * sizeof(double)); mas01cr@553: } mas01cr@553: current = next; mas01cr@553: value = strtod(current, &next); mas01cr@553: } mas01cr@571: return buf; mas01cr@553: } mas01cr@553: mas01mj@583: int main(int argc, char* argv[]) { mas01mj@583: mas01mj@583: if(argc != 3) mas01mj@583: { mas01mj@583: fprintf(stderr, "Usage: %s \n", argv[0]); mas01mj@583: return 2; mas01mj@583: } mas01mj@583: mas01mj@583: char* n3file = argv[1]; mas01mj@583: char* dbfile = argv[2]; mas01mj@583: mas01cr@554: librdf_world *world; mas01cr@554: if (!(world = librdf_new_world())) mas01cr@554: goto librdf_error; mas01cr@553: mas01cr@554: librdf_storage *storage; mas01cr@554: if (!(storage = librdf_new_storage(world, "memory", NULL, NULL))) mas01cr@554: goto librdf_error; mas01cr@553: mas01cr@554: librdf_model *model; mas01cr@554: if (!(model = librdf_new_model(world, storage, NULL))) mas01cr@554: goto librdf_error; mas01mj@583: mas01cr@554: librdf_uri *uri; mas01cr@644: if (!(uri = librdf_new_uri_from_filename(world, n3file))) mas01cr@554: goto librdf_error; mas01cr@553: mas01cr@554: librdf_parser *parser; mas01cr@554: if (!(parser = librdf_new_parser(world, "guess", NULL, NULL))) mas01cr@554: goto librdf_error; mas01cr@553: mas01cr@554: if(librdf_parser_parse_into_model(parser, uri, NULL, model)) mas01cr@554: goto librdf_error; mas01cr@553: mas01cr@554: librdf_query *query; mas01cr@554: if (!(query = librdf_new_query(world, "sparql", NULL, qstring, NULL))) mas01cr@554: goto librdf_error; mas01cr@553: mas01cr@554: librdf_query_results *results; mas01cr@554: if (!(results = librdf_query_execute(query, model))) mas01cr@554: goto librdf_error; mas01cr@553: mas01cr@554: if(!librdf_query_results_is_bindings(results)) mas01cr@554: goto librdf_error; mas01cr@554: mas01cr@554: adb_t *adb; mas01mj@583: if(!(adb = audiodb_open(dbfile, O_RDWR))) { mas01mj@583: mas01cr@554: struct stat st; mas01mj@583: if(!(stat(dbfile, &st))) { mas01mj@583: fprintf(stderr, "%s not opened.\n", dbfile); mas01cr@554: return 1; mas01cr@554: } else { mas01cr@554: /* FIXME: if we are doing a proper SPARQL query over a mas01cr@554: * potentially unbounded number of results, we could use mas01cr@554: * librdf_query_results_get_count() to estimate how much space mas01cr@554: * our database will need. mas01cr@554: mas01cr@554: * If we're doing a SPARQL query over a number of RDF files, mas01cr@554: * with an expected number of datasets per file of 1 (as might mas01cr@554: * be produced by runner(?)) then obviously we can use that as mas01cr@554: * an estimate of number of tracks instead. mas01cr@554: mas01cr@554: * Specifying the data dimensionality should be easy from the mas01cr@554: * semantics of the feature being inserted; it's not immediately mas01cr@554: * obvious to me how to estimate the data size required, unless mas01cr@554: * we maybe do a preliminary query to find out the total time mas01cr@554: * (or similar) of all the tracks we're about to insert. mas01cr@554: mas01cr@554: * (also NOTE: this audiodb_create() interface is scheduled for mas01cr@554: * being made less inelegant.) */ mas01mj@583: if(!(adb = audiodb_create(dbfile, 0, 0, 0))) { mas01mj@583: fprintf(stderr, "failed to create %s.\n", dbfile); mas01cr@554: return 1; mas01cr@554: } mas01cr@554: } mas01cr@553: } mas01cr@554: mas01mj@583: if(librdf_query_results_finished(results)) mas01mj@583: { mas01mj@583: fprintf(stderr, "No features found!\n"); mas01mj@583: return 3; mas01mj@583: } mas01mj@583: mas01mj@583: mas01cr@553: while(!librdf_query_results_finished(results)) { mas01mj@583: mas01cr@553: adb_datum_t datum = {0}; mas01mj@583: mas01mj@583: // Pull out the dimension mas01mj@583: mas01mj@583: librdf_node *node = librdf_query_results_get_binding_value_by_name(results, "dimensions"); mas01mj@583: char* dimensions = librdf_node_get_literal_value(node); mas01mj@583: mas01mj@583: int dimension = 0; mas01mj@583: sscanf(dimensions, "%d", &dimension); mas01mj@583: datum.dim = dimension; mas01cr@644: mas01mj@583: // Grab key and value mas01mj@583: mas01mj@583: node = librdf_query_results_get_binding_value_by_name(results, "key"); mas01cr@644: char *key = strdup(librdf_uri_to_filename(librdf_node_get_uri(node))); mas01cr@644: datum.key = basename(key); mas01mj@583: mas01mj@583: size_t nelements = 0; mas01mj@583: node = librdf_query_results_get_binding_value_by_name(results, "value"); mas01mj@583: datum.data = parse_value_string(librdf_node_get_literal_value(node), &nelements); mas01mj@583: mas01mj@583: // Validate that we have the correct number of elements mas01mj@583: mas01mj@583: if(nelements % dimension) return 4; mas01mj@583: datum.nvectors = nelements / dimension; mas01mj@583: mas01mj@583: printf("Dimension: %d\n", dimension); mas01mj@583: printf("Key: %s\n", datum.key); mas01mj@583: printf("Vectors: %d\n", datum.nvectors); mas01mj@583: mas01mj@583: librdf_free_node(node); mas01mj@583: mas01cr@553: if(audiodb_insert_datum(adb, &datum)) { mas01cr@554: fprintf(stderr, "failed to insert datum with key %s.\n", datum.key); mas01cr@554: return 1; mas01cr@553: } mas01cr@571: free(datum.data); mas01cr@553: librdf_query_results_next(results); mas01cr@553: } mas01cr@553: mas01cr@553: audiodb_close(adb); mas01cr@553: librdf_free_query_results(results); mas01cr@553: librdf_free_query(query); mas01cr@571: librdf_free_parser(parser); mas01cr@553: librdf_free_uri(uri); mas01cr@553: librdf_free_model(model); mas01cr@553: librdf_free_storage(storage); mas01cr@553: librdf_free_world(world); mas01cr@554: mas01cr@554: return 0; mas01cr@554: mas01cr@554: librdf_error: mas01cr@554: fprintf(stderr, "Something went wrong in librdf.\n"); mas01cr@554: return 1; mas01cr@553: }