39 #include <dataquay/BasicStore.h> 40 #include <dataquay/PropertyObject.h> 44 using Dataquay::Nodes;
45 using Dataquay::Triple;
46 using Dataquay::Triples;
47 using Dataquay::BasicStore;
48 using Dataquay::PropertyObject;
81 int &sampleRate,
int &windowLength,
82 int &hopSize,
int &width,
int &height);
84 void fillModel(
Model *,
long,
long,
bool, std::vector<float> &, QString);
90 return "*.rdf *.n3 *.ttl";
128 m_store(new BasicStore),
130 m_sampleRate(sampleRate)
134 m_store->addPrefix(
"mo", Uri(
"http://purl.org/ontology/mo/"));
135 m_store->addPrefix(
"af", Uri(
"http://purl.org/ontology/af/"));
136 m_store->addPrefix(
"dc", Uri(
"http://purl.org/dc/elements/1.1/"));
137 m_store->addPrefix(
"tl", Uri(
"http://purl.org/NET/c4dm/timeline.owl#"));
138 m_store->addPrefix(
"event", Uri(
"http://purl.org/NET/c4dm/event.owl#"));
139 m_store->addPrefix(
"rdfs", Uri(
"http://www.w3.org/2000/01/rdf-schema#"));
143 if (uri.startsWith(
"file:")) {
146 url = QUrl::fromLocalFile(uri);
148 m_store->import(url, BasicStore::ImportIgnoreDuplicates);
149 }
catch (std::exception &e) {
174 std::vector<Model *> models;
179 m_errorString = QString(
"Invalid audio data model (is audio file format supported?)");
212 (Triple(Node(), Uri(
"a"),
expand(
"mo:Signal"))).subjects();
214 foreach (Node sig, sigs) {
216 Node file =
m_store->complete(Triple(Node(),
expand(
"mo:encodes"), sig));
217 if (file == Node()) {
218 file =
m_store->complete(Triple(sig,
expand(
"mo:available_as"), Node()));
220 if (file == Node()) {
221 cerr <<
"RDFImporterImpl::getDataModelsAudio: ERROR: No source for signal " << sig << endl;
225 QString signal = sig.value;
226 QString source = file.value;
228 SVDEBUG <<
"NOTE: Seeking signal source \"" << source
233 SVDEBUG <<
"NOTE: Source is available: Local filename is \"" 240 m_errorString = QString(
"Signal source \"%1\" is not available").arg(source);
246 SVDEBUG <<
"NOTE: Signal source \"" << source
247 <<
"\" is not available, using file finder..." << endl;
254 cerr <<
"File finder returns: \"" << path
260 m_errorString = QString(
"Signal source \"%1\" is not available").arg(source);
269 reporter->
setMessage(RDFImporter::tr(
"Importing audio referenced in RDF..."));
273 if (newModel->
isOK()) {
274 cerr <<
"Successfully created wave file model from source at \"" << source <<
"\"" << endl;
275 models.push_back(newModel);
281 m_errorString = QString(
"Failed to create wave file model from source at \"%1\"").arg(source);
293 reporter->
setMessage(RDFImporter::tr(
"Importing dense signal data from RDF..."));
296 Nodes sigFeatures =
m_store->match
297 (Triple(Node(),
expand(
"af:signal_feature"), Node())).objects();
299 foreach (Node sf, sigFeatures) {
301 if (sf.type != Node::URI && sf.type != Node::Blank)
continue;
304 Node v =
m_store->complete(Triple(sf,
expand(
"af:value"), Node()));
306 QString feature = sf.value;
307 QString type = t.value;
308 QString value = v.value;
310 if (type ==
"" || value ==
"")
continue;
313 int windowLength = 0;
318 (feature, sampleRate, windowLength, hopSize, width, height);
321 cerr <<
"WARNING: Sample rate in dense feature description does not match our underlying rate -- using rate from feature description" << endl;
326 cerr <<
"WARNING: Dense feature description does not specify a hop size -- assuming 1" << endl;
331 cerr <<
"WARNING: Dense feature description does not specify feature signal dimensions -- assuming one-dimensional (height = 1)" << endl;
335 QStringList values = value.split(
' ', QString::SkipEmptyParts);
337 if (values.empty()) {
338 cerr <<
"WARNING: Dense feature description does not specify any values!" << endl;
345 (sampleRate, hopSize,
false);
347 for (
int j = 0; j < values.size(); ++j) {
348 float f = values[j].toFloat();
363 (sampleRate, hopSize, height,
370 for (
int j = 0; j < values.size(); ++j) {
371 if (j % height == 0 && !column.empty()) {
375 column.push_back(values[j].toFloat());
378 if (!column.empty()) {
394 QString featureTypeUri)
397 (Triple(Uri(featureUri),
expand(
"dc:title"), Node()));
399 if (n.type == Node::Literal && n.value !=
"") {
400 SVDEBUG <<
"RDFImporterImpl::getDenseModelTitle: Title (from signal) \"" << n.value <<
"\"" << endl;
401 m->setObjectName(n.value);
406 (Triple(Uri(featureTypeUri),
expand(
"dc:title"), Node()));
408 if (n.type == Node::Literal && n.value !=
"") {
409 SVDEBUG <<
"RDFImporterImpl::getDenseModelTitle: Title (from signal type) \"" << n.value <<
"\"" << endl;
410 m->setObjectName(n.value);
414 SVDEBUG <<
"RDFImporterImpl::getDenseModelTitle: No title available for feature <" << featureUri <<
">" << endl;
419 int &sampleRate,
int &windowLength,
420 int &hopSize,
int &width,
int &height)
423 (Triple(Uri(featureUri),
expand(
"af:dimensions"), Node()));
425 cerr <<
"Dimensions = \"" << dim.value <<
"\"" << endl;
427 if (dim.type == Node::Literal && dim.value !=
"") {
428 QStringList dl = dim.value.split(
" ");
429 if (dl.empty()) dl.push_back(dim.value);
430 if (dl.size() > 0) height = dl[0].toInt();
431 if (dl.size() > 1) width = dl[1].toInt();
444 Node interval =
m_store->complete(Triple(Uri(featureUri),
expand(
"mo:time"), Node()));
447 cerr <<
"RDFImporterImpl::getDenseFeatureProperties: Feature time node " 448 << interval <<
" is not a tl:Interval" << endl;
452 Node tl =
m_store->complete(Triple(interval,
expand(
"tl:onTimeLine"), Node()));
455 cerr <<
"RDFImporterImpl::getDenseFeatureProperties: Interval node " 456 << interval <<
" lacks tl:onTimeLine property" << endl;
460 Node map =
m_store->complete(Triple(Node(),
expand(
"tl:rangeTimeLine"), tl));
463 cerr <<
"RDFImporterImpl::getDenseFeatureProperties: No map for " 464 <<
"timeline node " << tl << endl;
467 PropertyObject po(
m_store,
"tl:", map);
469 if (po.hasProperty(
"sampleRate")) {
470 sampleRate = po.getProperty(
"sampleRate").toInt();
472 if (po.hasProperty(
"hopSize")) {
473 hopSize = po.getProperty(
"hopSize").toInt();
475 if (po.hasProperty(
"windowLength")) {
476 windowLength = po.getProperty(
"windowLength").toInt();
479 cerr <<
"sr = " << sampleRate <<
", hop = " << hopSize <<
", win = " << windowLength << endl;
487 reporter->
setMessage(RDFImporter::tr(
"Importing event data from RDF..."));
509 (Triple(Node(),
expand(
"a"),
expand(
"mo:Signal"))).subjects();
513 std::map<QString, std::map<QString, std::map<int, std::map<bool, Model *> > > >
516 foreach (Node sig, sigs) {
518 Node interval =
m_store->complete(Triple(sig,
expand(
"mo:time"), Node()));
519 if (interval == Node())
continue;
521 Node tl =
m_store->complete(Triple(interval,
expand(
"tl:onTimeLine"), Node()));
522 if (tl == Node())
continue;
524 Nodes times =
m_store->match(Triple(Node(),
expand(
"tl:onTimeLine"), tl)).subjects();
526 foreach (Node tn, times) {
528 Nodes timedThings =
m_store->match(Triple(Node(),
expand(
"event:time"), tn)).subjects();
530 foreach (Node thing, timedThings) {
532 Node typ =
m_store->complete(Triple(thing,
expand(
"a"), Node()));
533 if (typ == Node())
continue;
535 Node valu =
m_store->complete(Triple(thing,
expand(
"af:feature"), Node()));
537 QString source = sig.value;
538 QString timeline = tl.value;
539 QString type = typ.value;
540 QString thinguri = thing.value;
565 bool text = (type.contains(
"Text") || type.contains(
"text"));
566 bool note = (type.contains(
"Note") || type.contains(
"note"));
569 label =
m_store->complete(Triple(thing,
expand(
"af:text"), Node())).value;
573 label =
m_store->complete(Triple(thing,
expand(
"rdfs:label"), Node())).value;
580 bool haveDuration =
false;
582 Node at =
m_store->complete(Triple(tn,
expand(
"tl:at"), Node()));
592 Node start =
m_store->complete(Triple(tn,
expand(
"tl:beginsAt"), Node()));
593 Node dur =
m_store->complete(Triple(tn,
expand(
"tl:duration"), Node()));
594 if (start != Node() && dur != Node()) {
596 (start.value.toStdString());
598 (dur.value.toStdString());
603 QString valuestring = valu.value;
604 std::vector<float> values;
606 if (valuestring !=
"") {
607 QStringList vsl = valuestring.split(
" ", QString::SkipEmptyParts);
608 for (
int j = 0; j < vsl.size(); ++j) {
609 bool success =
false;
610 float v = vsl[j].toFloat(&success);
611 if (success) values.push_back(v);
616 if (values.size() == 1) dimensions = 2;
617 else if (values.size() > 1) dimensions = 3;
621 if (modelMap[timeline][type][dimensions].find(haveDuration) ==
622 modelMap[timeline][type][dimensions].end()) {
633 if (dimensions == 1) {
639 }
else if (dimensions == 2) {
657 if (note || (dimensions > 2)) {
669 cerr <<
"source model for " << model <<
" is " <<
m_audioModelMap[source] << endl;
673 QString title =
m_store->complete
674 (Triple(typ,
expand(
"dc:title"), Node())).value;
678 title.replace(QRegExp(
"^.*[/#]"),
"");
680 model->setObjectName(title);
682 modelMap[timeline][type][dimensions][haveDuration] = model;
683 models.push_back(model);
686 model = modelMap[timeline][type][dimensions][haveDuration];
691 fillModel(model, ftime, fduration, haveDuration, values, label);
703 std::vector<float> &values,
709 dynamic_cast<SparseOneDimensionalModel *>(model);
717 dynamic_cast<TextModel *>(model);
721 values.empty() ? 0.5f : values[0] < 0.f ? 0.f : values[0] > 1.f ? 1.f : values[0],
728 dynamic_cast<SparseTimeValueModel *>(model);
731 (ftime, values.empty() ? 0.f : values[0], label);
737 dynamic_cast<NoteModel *>(model);
740 float value = 0.f, level = 1.f;
741 if (!values.empty()) {
743 if (values.size() > 1) {
750 float value = 0.f, duration = 1.f, level = 1.f;
751 if (!values.empty()) {
753 if (values.size() > 1) {
754 duration = values[1];
755 if (values.size() > 2) {
767 dynamic_cast<RegionModel *>(model);
770 if (values.empty()) {
785 float duration = 1.f;
786 if (!values.empty()) {
788 if (values.size() > 1) {
789 duration = values[1];
798 cerr <<
"WARNING: RDFImporterImpl::fillModel: Unknown or unexpected model type" << endl;
805 bool haveAudio =
false;
806 bool haveAnnotations =
false;
807 bool haveRDF =
false;
809 BasicStore *store = 0;
815 store = BasicStore::load(QUrl(url));
816 Triple t = store->matchOnce(Triple());
817 if (t != Triple()) haveRDF =
true;
818 }
catch (std::exception &e) {
827 store->addPrefix(
"mo", Uri(
"http://purl.org/ontology/mo/"));
828 store->addPrefix(
"event", Uri(
"http://purl.org/NET/c4dm/event.owl#"));
829 store->addPrefix(
"af", Uri(
"http://purl.org/ontology/af/"));
833 Node n = store->complete(Triple(Node(), Uri(
"a"), store->expand(
"mo:AudioFile")));
834 if (n != Node() && n.type == Node::URI) {
844 Nodes sigs = store->match(Triple(Node(), Uri(
"a"), store->expand(
"mo:Signal"))).subjects();
845 foreach (Node sig, sigs) {
846 Node aa = store->complete(Triple(sig, store->expand(
"mo:available_as"), Node()));
854 SVDEBUG <<
"NOTE: RDFImporter::identifyDocumentType: haveAudio = " 855 << haveAudio << endl;
858 n = store->matchOnce(Triple(Node(), store->expand(
"event:time"), Node())).c;
860 haveAnnotations =
true;
863 if (!haveAnnotations) {
865 n = store->matchOnce(Triple(Node(), store->expand(
"af:signal_feature"), Node())).c;
867 haveAnnotations =
true;
871 SVDEBUG <<
"NOTE: RDFImporter::identifyDocumentType: haveAnnotations = " 872 << haveAnnotations << endl;
877 if (haveAnnotations) {
883 if (haveAnnotations) {
QString getErrorString() const
std::map< Model *, std::map< QString, float > > m_labelValueMap
static FileFinder * getInstance()
int getSampleRate() const
Return the frame rate in frames per second.
virtual float getValueMaximum() const
static QString getKnownExtensions()
Return the file extensions that we have data file readers for, in a format suitable for use with QFil...
void setRDFTypeURI(QString uri)
Set the event, feature, or signal type URI for the features contained in this model,...
void getDataModelsDense(std::vector< Model * > &, ProgressReporter *)
static RDFDocumentType identifyDocumentType(QString url)
QString getLocation() const
Return the location filename or URL as passed to the constructor.
std::map< QString, Model * > m_audioModelMap
std::vector< Model * > getDataModels(ProgressReporter *reporter)
NoteModel – a concrete IntervalModel for notes.
RegionModel – a concrete IntervalModel for intervals associated with a value, which we call regions f...
void fillModel(Model *, long, long, bool, std::vector< float > &, QString)
std::vector< Model * > getDataModels(ProgressReporter *)
QString getErrorString() const
virtual void addPoint(const PointType &point)
Add a point.
void waitForData()
Block on a sub-event-loop until the whole of the data has been retrieved (if it is remote).
Time/value point type for use in a SparseModel or SparseValueModel.
virtual void setSourceModel(Model *model)
Set the source model for this model.
Text point type for use in a SparseModel.
virtual void addPoint(const Point &point)
Add a point.
virtual void addPoint(const PointType &point)
Add a point.
Model is the base class for all data models that represent any sort of data on a time scale based on ...
FileSource is a class used to refer to the contents of a file that may be either local or at a remote...
void getDataModelsAudio(std::vector< Model * > &, ProgressReporter *)
void setSampleRate(int sampleRate)
RDFImporter(QString url, int sampleRate=0)
QString getLocalFilename() const
Return the name of the local file this FileSource refers to.
void getDenseFeatureProperties(QString featureUri, int &sampleRate, int &windowLength, int &hopSize, int &width, int &height)
static long realTime2Frame(const RealTime &r, unsigned int sampleRate)
Convert a RealTime into a sample frame at the given sample rate.
RDFImporterImpl(QString url, int sampleRate)
void getDataModelsSparse(std::vector< Model * > &, ProgressReporter *)
void getDenseModelTitle(Model *, QString, QString)
virtual ~RDFImporterImpl()
virtual QString find(FileType type, QString location, QString lastKnownLocation="")=0
virtual void setMessage(QString text)=0
bool isOK() const
Return true if the model was constructed successfully.
void setSampleRate(int sampleRate)
static RealTime fromXsdDuration(std::string xsdd)
virtual void setColumn(int x, const Column &values)
Set the entire set of bin values at the given column.
RealTime represents time values to nanosecond precision with accurate arithmetic and frame-rate conve...
bool isAvailable()
Return true if the file or remote URL exists.