18 #include "vamp-hostsdk/PluginHostAdapter.h" 19 #include "vamp-hostsdk/PluginLoader.h" 27 #include <QTextStream> 34 using Vamp::PluginBase;
38 SupportOneFilePerTrack |
43 m_networkRetrieved(false),
59 p.
description =
"Use \"plain\" RDF even if transform metadata is available.";
63 p.
name =
"audiofile-uri";
64 p.
description =
"Link the output RDF to the given audio file URI instead of its actual location.";
69 p.
description =
"Link the output RDF to the given track URI.";
74 p.
description =
"Link the track in the output RDF to the given foaf:maker URI.";
79 p.
description =
"Attempt to retrieve RDF descriptions of plugins from network, if not available locally";
91 for (map<string, string>::iterator i = params.begin();
92 i != params.end(); ++i) {
93 if (i->first ==
"plain") {
96 if (i->first ==
"audiofile-uri") {
99 if (i->first ==
"track-uri") {
102 if (i->first ==
"maker-uri") {
105 if (i->first ==
"network") {
128 const Plugin::OutputDescriptor& output,
129 const Plugin::FeatureList& features,
130 std::string summaryType)
144 cerr <<
"NOTE: Have RDF description for plugin ID \"" 145 << pluginId <<
"\"" << endl;
147 cerr <<
"NOTE: No RDF description for plugin ID \"" 148 << pluginId <<
"\"" << endl;
150 cerr <<
" Consider using the --rdf-network option to retrieve plugin descriptions" << endl;
151 cerr <<
" from the network where possible." << endl;
190 if (timelineURI ==
"") {
191 cerr <<
"RDFFeatureWriter: INTERNAL ERROR: writing features without having established a timeline URI!" << endl;
195 if (summaryType !=
"") {
202 (output.identifier.c_str()) ==
207 if (signalURI ==
"") {
208 cerr <<
"RDFFeatureWriter: INTERNAL ERROR: writing dense features without having established a signal URI!" << endl;
218 (output.identifier.c_str()) ==
221 (output.identifier.c_str()) !=
"") {
225 if (signalURI ==
"") {
226 cerr <<
"RDFFeatureWriter: INTERNAL ERROR: writing track-level features without having established a signal URI!" << endl;
243 QTextStream &stream = *sptr;
245 stream <<
"@prefix dc: <http://purl.org/dc/elements/1.1/> .\n" 246 <<
"@prefix mo: <http://purl.org/ontology/mo/> .\n" 247 <<
"@prefix af: <http://purl.org/ontology/af/> .\n" 248 <<
"@prefix foaf: <http://xmlns.com/foaf/0.1/> . \n" 249 <<
"@prefix event: <http://purl.org/NET/c4dm/event.owl#> .\n" 250 <<
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n" 251 <<
"@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n" 252 <<
"@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n" 253 <<
"@prefix tl: <http://purl.org/NET/c4dm/timeline.owl#> .\n" 254 <<
"@prefix vamp: <http://purl.org/ontology/vamp/> .\n" 255 <<
"@prefix : <#> .\n\n";
268 QFile file(filename);
271 if (!file.open(QIODevice::ReadOnly))
return;
273 QTextStream in(&file);
275 QRegExp localObjectUriWithDigits(
":[^ ]+_([0-9]+) a ");
277 while (!in.atEnd()) {
278 QString line = in.readLine();
279 if (line.length() > 120) {
282 if (localObjectUriWithDigits.indexIn(line) > -1) {
283 QString numeric = localObjectUriWithDigits.cap(1);
284 int number = numeric.toInt();
298 QTextStream &stream = *sptr;
304 QUrl url(trackId, QUrl::StrictMode);
305 QString scheme = url.scheme().toLower();
306 bool local = (scheme ==
"" || scheme ==
"file" || scheme.length() == 1);
310 url.setScheme(
"file");
311 url.setPath(QFileInfo(url.path()).absoluteFilePath());
312 }
else if (scheme.length() == 1) {
313 url.setScheme(
"file");
314 url.setPath(scheme +
":" + url.path());
320 unsigned long signalCount =
m_count++;
332 bool userSpecifiedTrack =
false;
336 userSpecifiedTrack =
true;
344 QString afURI = url.toEncoded().data();
347 bool wantTrack = (userSpecifiedTrack ||
367 stream << trackURI <<
" a mo:Track ";
368 if (tm.
title !=
"") {
369 stream <<
";\n dc:title \"\"\"" << tm.
title <<
"\"\"\" ";
373 }
else if (tm.
maker !=
"") {
374 stream <<
";\n foaf:maker [ a mo:MusicArtist; foaf:name \"\"\"" << tm.
maker <<
"\"\"\" ] ";
377 stream <<
";\n mo:available_as <" << afURI <<
"> ";
383 stream <<
"<" << afURI <<
"> a mo:AudioFile ;\n";
384 stream <<
" mo:encodes " << signalURI <<
".\n\n";
387 stream << signalURI <<
" a mo:Signal ;\n";
389 stream <<
" mo:time [\n" 390 <<
" a tl:Interval ;\n" 392 << timelineURI <<
"\n ] .\n\n";
394 stream << timelineURI <<
" a tl:Timeline .\n\n";
400 const Plugin::OutputDescriptor &od,
402 std::string summaryType)
404 QString outputId = od.identifier.c_str();
405 QTextStream &stream = *sptr;
412 bool needEventType =
false;
413 bool needSignalType =
false;
417 if (summaryType ==
"" &&
426 needSignalType =
true;
430 needSignalType =
true;
441 needEventType =
true;
447 needEventType =
true;
457 needEventType =
true;
461 needEventType =
true;
465 QString transformUri;
469 transformUri = QString(
":transform_%1_%2").arg(
m_count++).arg(outputId);
486 uri = QString(
":event_type_%1").arg(
m_count++);
491 <<
" rdfs:subClassOf event:Event ;" << endl
492 <<
" dc:title \"" << od.name.c_str() <<
"\" ;" << endl
493 <<
" dc:format \"" << od.unit.c_str() <<
"\" ;" << endl
494 <<
" dc:description \"" << od.description.c_str() <<
"\" ." 498 if (needSignalType) {
505 uri = QString(
":signal_type_%1").arg(
m_count++);
510 <<
" rdfs:subClassOf af:Signal ;" << endl
511 <<
" dc:title \"" << od.name.c_str() <<
"\" ;" << endl
512 <<
" dc:format \"" << od.unit.c_str() <<
"\" ;" << endl
513 <<
" dc:description \"" << od.description.c_str() <<
"\" ." 521 const Plugin::OutputDescriptor& od,
522 const Plugin::FeatureList& featureList,
528 if (featureList.empty())
return;
529 QTextStream &stream = *sptr;
533 QString outputId = od.identifier.c_str();
537 for (
int i = 0; i < (int)featureList.size(); ++i) {
539 const Plugin::Feature &feature = featureList[i];
540 unsigned long featureNumber =
m_count++;
542 stream <<
":event_" << featureNumber <<
" a ";
548 if (plain || eventTypeURI ==
"") {
553 stream <<
":event_type_" << outputId <<
" ;\n";
556 stream <<
"<" << eventTypeURI <<
"> ;\n";
560 QString timestamp = feature.timestamp.toString().c_str();
561 timestamp.replace(QRegExp(
"^ +"),
"");
563 if (feature.hasDuration && feature.duration > Vamp::RealTime::zeroTime) {
565 QString duration = feature.duration.toString().c_str();
566 duration.replace(QRegExp(
"^ +"),
"");
568 stream <<
" event:time [ \n" 569 <<
" a tl:Interval ;\n" 570 <<
" tl:onTimeLine " << timelineURI <<
" ;\n" 571 <<
" tl:beginsAt \"PT" << timestamp
572 <<
"S\"^^xsd:duration ;\n" 573 <<
" tl:duration \"PT" << duration
574 <<
"S\"^^xsd:duration ;\n" 579 stream <<
" event:time [ \n" 580 <<
" a tl:Instant ;\n" 581 <<
" tl:onTimeLine " << timelineURI <<
" ;\n" 582 <<
" tl:at \"PT" << timestamp
583 <<
"S\"^^xsd:duration ;\n ] ";
591 if (feature.label.length() > 0) {
593 stream <<
" rdfs:label \"\"\"" << feature.label.c_str() <<
"\"\"\" ";
596 if (!feature.values.empty()) {
599 stream <<
" af:feature \"" << feature.values[0];
600 for (
int j = 1; j < (int)feature.values.size(); ++j) {
601 stream <<
" " << feature.values[j];
613 const Plugin::OutputDescriptor& od,
614 const Plugin::FeatureList& featureList,
618 if (featureList.empty())
return;
619 QTextStream &stream = *sptr;
623 QString outputId = od.identifier.c_str();
626 if (featureUri ==
"") {
627 SVDEBUG <<
"RDFFeatureWriter::writeTrackLevelRDF: ERROR: No feature URI available -- this function should not have been called!" << endl;
631 for (
int i = 0; i < (int)featureList.size(); ++i) {
633 const Plugin::Feature &feature = featureList[i];
635 if (feature.values.empty()) {
637 if (feature.label ==
"")
continue;
639 stream << signalURI <<
" " << featureUri <<
" \"\"\"" 640 << feature.label.c_str() <<
"\"\"\" .\n";
644 stream << signalURI <<
" " << featureUri <<
" \"" 645 << feature.values[0] <<
"\"^^xsd:float .\n";
653 const Plugin::OutputDescriptor& od,
654 const Plugin::FeatureList& featureList,
659 if (featureList.empty())
return;
669 QTextStream stream(&str);
672 QString outputId = od.identifier.c_str();
674 unsigned long featureNumber =
m_count++;
680 stream <<
"\n:feature_timeline_" << featureNumber <<
" a tl:DiscreteTimeLine .\n\n";
684 cerr <<
"RDFFeatureWriter: INTERNAL ERROR: writing dense features without having set the step size properly!" << endl;
689 if (blockSize == 0) {
690 cerr <<
"RDFFeatureWriter: INTERNAL ERROR: writing dense features without having set the block size properly!" << endl;
695 if (sampleRate == 0.f) {
696 cerr <<
"RDFFeatureWriter: INTERNAL ERROR: writing dense features without having set the sample rate properly!" << endl;
700 stream <<
":feature_timeline_map_" << featureNumber
701 <<
" a tl:UniformSamplingWindowingMap ;\n" 702 <<
" tl:rangeTimeLine :feature_timeline_" << featureNumber <<
" ;\n" 703 <<
" tl:domainTimeLine " << timelineURI <<
" ;\n" 704 <<
" tl:sampleRate \"" << int(sampleRate) <<
"\"^^xsd:int ;\n" 705 <<
" tl:windowLength \"" << blockSize <<
"\"^^xsd:int ;\n" 706 <<
" tl:hopSize \"" << stepSize <<
"\"^^xsd:int .\n\n";
708 stream << signalURI <<
" af:signal_feature :feature_" 709 << featureNumber <<
" ." << endl << endl;
711 stream <<
":feature_" << featureNumber <<
" a ";
714 if (plain || signalTypeURI ==
"") {
719 stream <<
":signal_type_" << outputId <<
" ;\n";
722 stream <<
"<" << signalTypeURI <<
"> ;\n";
725 stream <<
" mo:time [" 726 <<
"\n a tl:Interval ;" 727 <<
"\n tl:onTimeLine :feature_timeline_" << featureNumber <<
" ;";
736 stream <<
"\n tl:start \"" << start <<
"\"^^xsd:int ;";
739 stream <<
"\n tl:duration \"" << duration <<
"\"^^xsd:int ;";
742 stream <<
"\n ] ;\n";
745 stream <<
" vamp:computed_by " <<
m_transformURIs[transform] <<
" ;\n";
748 if (od.hasFixedBinCount) {
750 stream <<
" af:dimensions \"" << od.binCount <<
" 0\" ;\n";
753 stream <<
" af:value \"";
757 QTextStream stream(&str);
759 for (
int i = 0; i < (int)featureList.size(); ++i) {
761 const Plugin::Feature &feature = featureList[i];
763 for (
int j = 0; j < (int)feature.values.size(); ++j) {
764 stream << feature.values[j] <<
" ";
775 for (map<StringTransformPair, StreamBuffer>::iterator i =
780 *(b.first) << b.second <<
"\" ." << endl;
void writeLocalFeatureTypes(QTextStream *, const Transform &, const Vamp::Plugin::OutputDescriptor &, PluginRDFDescription &, std::string summaryType)
virtual ParameterList getSupportedParameters() const
virtual void setParameters(map< string, string > ¶ms)
virtual void setTrackMetadata(QString trackid, TrackMetadata metadata)
QString getOutputFeatureAttributeURI(QString outputId) const
map< StringTransformPair, StreamBuffer > m_openDenseFeatures
pair< QTextStream *, QString > StreamBuffer
virtual void setFixedEventTypeURI(QString uri)
virtual ParameterList getSupportedParameters() const
map< QTextStream *, set< Transform > > m_startedStreamTransforms
vector< Parameter > ParameterList
set< QString > m_startedTrackIds
void writeTrackLevelRDF(QTextStream *stream, const Transform &transform, const Vamp::Plugin::OutputDescriptor &output, const Vamp::Plugin::FeatureList &features, PluginRDFDescription &desc, QString signalURI)
map< Transform, QString > m_syntheticSignalTypeURIs
map< QString, QString > m_trackTrackURIs
pair< QString, Transform > StringTransformPair
OutputDisposition getOutputDisposition(QString outputId) const
QString getOutputSignalTypeURI(QString outputId) const
void writeSignalDescription(QTextStream *, QString)
virtual void setParameters(map< string, string > ¶ms)
RDFDescriptionMap m_rdfDescriptions
void writePrefixes(QTextStream *)
QString getOutputEventTypeURI(QString outputId) const
virtual ~RDFFeatureWriter()
QString m_userAudioFileUri
map< Transform, QString > m_transformURIs
void writeSparseRDF(QTextStream *stream, const Transform &transform, const Vamp::Plugin::OutputDescriptor &output, const Vamp::Plugin::FeatureList &features, PluginRDFDescription &desc, QString timelineURI)
map< QString, QString > m_trackSignalURIs
QString m_fixedEventTypeURI
static long realTime2Frame(const RealTime &r, unsigned int sampleRate)
Convert a RealTime into a sample frame at the given sample rate.
virtual void reviewFileForAppending(QString filename)
bool haveDescription() const
bool indexConfiguredURLs()
Index all URLs obtained from index files defined in the current settings.
map< QString, QString > m_trackTimelineURIs
virtual void write(QString trackid, const Transform &transform, const Vamp::Plugin::OutputDescriptor &output, const Vamp::Plugin::FeatureList &features, std::string summaryType="")
static PluginRDFIndexer * getInstance()
QTextStream * getOutputStream(QString, TransformId)
map< Transform, QString > m_syntheticEventTypeURIs
TrackMetadataMap m_metadata
void writeDenseRDF(QTextStream *stream, const Transform &transform, const Vamp::Plugin::OutputDescriptor &output, const Vamp::Plugin::FeatureList &features, PluginRDFDescription &desc, QString signalURI, QString timelineURI)
RealTime represents time values to nanosecond precision with accurate arithmetic and frame-rate conve...