Mercurial > hg > classical
view common/FeatureFileIndex.cpp @ 45:0033259c6772
* More Music Ontology-like structure for audio files & signals
author | Chris Cannam |
---|---|
date | Fri, 14 May 2010 17:58:04 +0100 |
parents | ed2befdf1e98 |
children | c8b777862198 |
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ #include "FeatureFileIndex.h" #include "TypeRegistrar.h" #include <QMutexLocker> #include <QDir> #include "base/TempDirectory.h" #include "base/Exceptions.h" using namespace Dataquay; namespace ClassicalData { FeatureFileIndex * FeatureFileIndex::getInstance() { static FeatureFileIndex instance; return &instance; } FeatureFileIndex::FeatureFileIndex() : m_bs(0), m_index(0) { try { m_indexFileName = getIndexFileName(); } catch (DirectoryCreationFailed f) { std::cerr << "FeatureFileIndex: ERROR: Failed to find or create index directory: " << f.what() << std::endl; return; } m_bs = new BasicStore; m_index = new TransactionalStore(m_bs); TypeRegistrar::addMappings(m_bs, 0); if (QFile(m_indexFileName).exists()) { m_bs->import(QUrl::fromLocalFile(m_indexFileName), BasicStore::ImportIgnoreDuplicates); //!!! catch } } FeatureFileIndex::~FeatureFileIndex() { delete m_index; delete m_bs; } QString FeatureFileIndex::getIndexFileName() { QDir d = TempDirectory::getInstance()->getContainingPath(); QString n("index"); QFileInfo fi(d.filePath(n)); if ((fi.exists() && !fi.isDir()) || (!fi.exists() && !d.mkdir(n))) { throw DirectoryCreationFailed(fi.filePath()); } return QDir(fi.filePath()).filePath("features.ttl"); } QString FeatureFileIndex::getFeatureDirectoryName() { QDir d = TempDirectory::getInstance()->getContainingPath(); QString n("features"); QFileInfo fi(d.filePath(n)); if ((fi.exists() && !fi.isDir()) || (!fi.exists() && !d.mkdir(n))) { throw DirectoryCreationFailed(fi.filePath()); } return fi.filePath(); } void FeatureFileIndex::loadFor(AudioFile *tf, Store *store) { if (!m_index) { std::cerr << "FeatureFileIndex::loadFor: No index!" << std::endl; return; } updateIndex(); // The AudioFile object has a URI and a hash. Feature files // generated for this AudioFile should ideally have a matching // hash; if they have no hash, then the URI should match. If the // hash is present in the feature file but does not match, then it // cannot be the right track even if the URI matches. Triple t(Node(), "foaf:primaryTopic", tf->uri()); Triples results = m_index->match(t); std::cerr << "FeatureFileIndex::loadFor: " << results.size() << " feature file(s) for audio file " << tf->uri() << std::endl; t = Triple(Node(), "foaf:primaryTopic", Uri(QString::fromUtf8(QUrl(tf->uri().toString()).toEncoded()))); Triples moreResults = m_index->match(t); std::cerr << "FeatureFileIndex::loadFor: " << moreResults.size() << " feature file(s) for audio file " << t.c << std::endl; //!!! what's the right approach here? if (results.empty() && moreResults.empty()) { return; } } void FeatureFileIndex::featureFileAdded(QString filepath) { index(QUrl::fromLocalFile(filepath)); } void FeatureFileIndex::updateIndex() { QMutexLocker locker(&m_mutex); if (!m_index) return; QDir featureDir; try { QString s = getFeatureDirectoryName(); featureDir = QDir(s); } catch (DirectoryCreationFailed f) { std::cerr << "FeatureFileIndex::updateIndex: ERROR: Failed to find or create feature directory: " << f.what() << std::endl; return; } featureDir.setFilter(QDir::Files); for (unsigned int i = 0; i < featureDir.count(); ++i) { QFileInfo fi(featureDir.filePath(featureDir[i])); if (fi.isFile() && fi.isReadable()) { index(QUrl::fromLocalFile(fi.filePath())); } } //!!! remove triples from index that refer to nonexistent files? std::cerr << "Saving index to " << m_indexFileName.toStdString() << std::endl; m_bs->save(m_indexFileName); } void FeatureFileIndex::index(QUrl fileUrl) { Triple typeTriple(Uri(fileUrl), "a", m_index->expand("foaf:Document")); if (m_index->contains(typeTriple)) { return; } Transaction *tx = m_index->startTransaction(); tx->add(typeTriple); try { BasicStore *b = BasicStore::load(fileUrl); Triples ts = b->match (Triple(Node(), "a", m_index->expand("mo:AudioFile"))); foreach (Triple t, ts) { tx->add(Triple(Uri(fileUrl), "foaf:primaryTopic", t.a));; } } catch (...) { } delete tx; } }