Mercurial > hg > sonic-annotator
comparison runner/FeatureExtractionManager.cpp @ 227:88044af67bd1
Better error reporting for transform load (from RDF and XML)
author | Chris Cannam |
---|---|
date | Thu, 25 Feb 2016 10:53:10 +0000 |
parents | d0fe861bb116 |
children | 9a10c3ffff47 |
comparison
equal
deleted
inserted
replaced
226:4941e8b167c0 | 227:88044af67bd1 |
---|---|
425 } | 425 } |
426 return result; | 426 return result; |
427 } | 427 } |
428 | 428 |
429 bool FeatureExtractionManager::addFeatureExtractorFromFile | 429 bool FeatureExtractionManager::addFeatureExtractorFromFile |
430 (QString transformXmlFile, const vector<FeatureWriter*> &writers) | 430 (QString transformFile, const vector<FeatureWriter*> &writers) |
431 { | 431 { |
432 // We support two formats for transform description files, XML (in | |
433 // a format specific to Sonic Annotator) and RDF/Turtle. The RDF | |
434 // format can describe multiple transforms in a single file, the | |
435 // XML only one. | |
436 | |
437 // Possible errors we should report: | |
438 // | |
439 // 1. File does not exist or cannot be opened | |
440 // 2. File is ostensibly XML, but is not parseable | |
441 // 3. File is ostensibly Turtle, but is not parseable | |
442 // 4. File is XML, but contains no valid transform (e.g. is unrelated XML) | |
443 // 5. File is Turtle, but contains no valid transform(s) | |
444 // 6. File is Turtle and contains both valid and invalid transform(s) | |
445 | |
446 { | |
447 // We don't actually need to open this here yet, we just hoist | |
448 // it to the top for error reporting purposes | |
449 QFile file(transformFile); | |
450 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { | |
451 // Error case 1. File does not exist or cannot be opened | |
452 cerr << "ERROR: Failed to open transform file \"" << transformFile | |
453 << "\" for reading" << endl; | |
454 return false; | |
455 } | |
456 } | |
457 | |
432 bool tryRdf = true; | 458 bool tryRdf = true; |
433 | 459 if (transformFile.endsWith(".xml") || transformFile.endsWith(".XML")) { |
434 if (transformXmlFile.endsWith(".xml") || transformXmlFile.endsWith(".XML")) { | |
435 // We don't support RDF-XML (and nor does the underlying | 460 // We don't support RDF-XML (and nor does the underlying |
436 // parser library) so skip the RDF parse if the filename | 461 // parser library) so skip the RDF parse if the filename |
437 // suggests XML, to avoid puking out a load of errors from | 462 // suggests XML, to avoid puking out a load of errors from |
438 // feeding XML to a Turtle parser | 463 // feeding XML to a Turtle parser |
439 tryRdf = false; | 464 tryRdf = false; |
440 } | 465 } |
441 | 466 |
467 bool tryXml = true; | |
468 if (transformFile.endsWith(".ttl") || transformFile.endsWith(".TTL") || | |
469 transformFile.endsWith(".ntriples") || transformFile.endsWith(".NTRIPLES") || | |
470 transformFile.endsWith(".n3") || transformFile.endsWith(".N3")) { | |
471 tryXml = false; | |
472 } | |
473 | |
474 QString rdfError, xmlError; | |
475 | |
442 if (tryRdf) { | 476 if (tryRdf) { |
477 | |
443 RDFTransformFactory factory | 478 RDFTransformFactory factory |
444 (QUrl::fromLocalFile(QFileInfo(transformXmlFile).absoluteFilePath()) | 479 (QUrl::fromLocalFile(QFileInfo(transformFile).absoluteFilePath()) |
445 .toString()); | 480 .toString()); |
446 ProgressPrinter printer("Parsing transforms RDF file"); | 481 ProgressPrinter printer("Parsing transforms RDF file"); |
447 std::vector<Transform> transforms = factory.getTransforms(&printer); | 482 std::vector<Transform> transforms = factory.getTransforms(&printer); |
448 if (!factory.isOK()) { | 483 |
449 cerr << "WARNING: FeatureExtractionManager::addFeatureExtractorFromFile: Failed to parse transforms file: " << factory.getErrorString().toStdString() << endl; | 484 if (factory.isOK()) { |
485 if (transforms.empty()) { | |
486 cerr << "ERROR: Transform file \"" << transformFile | |
487 << "\" is valid RDF but defines no transforms" << endl; | |
488 return false; | |
489 } else { | |
490 bool success = true; | |
491 for (int i = 0; i < (int)transforms.size(); ++i) { | |
492 if (!addFeatureExtractor(transforms[i], writers)) { | |
493 success = false; | |
494 } | |
495 } | |
496 return success; | |
497 } | |
498 } else { // !factory.isOK() | |
450 if (factory.isRDF()) { | 499 if (factory.isRDF()) { |
451 return false; // no point trying it as XML | 500 cerr << "ERROR: Invalid transform RDF file \"" << transformFile |
452 } | 501 << "\": " << factory.getErrorString() << endl; |
453 } | 502 return false; |
454 if (!transforms.empty()) { | 503 } |
455 bool success = true; | 504 |
456 for (int i = 0; i < (int)transforms.size(); ++i) { | 505 // the not-RDF case: fall through without reporting an |
457 if (!addFeatureExtractor(transforms[i], writers)) { | 506 // error, so we try the file as XML, and if that fails, we |
458 success = false; | 507 // print a general unparseable-file error |
459 } | 508 rdfError = factory.getErrorString(); |
460 } | 509 } |
461 return success; | 510 } |
462 } | 511 |
463 } | 512 if (tryXml) { |
464 | 513 |
465 QFile file(transformXmlFile); | 514 QFile file(transformFile); |
466 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { | 515 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { |
467 cerr << "ERROR: Failed to open transform XML file \"" | 516 cerr << "ERROR: Failed to open transform file \"" |
468 << transformXmlFile.toStdString() << "\" for reading" << endl; | 517 << transformFile.toStdString() << "\" for reading" << endl; |
469 return false; | 518 return false; |
470 } | 519 } |
471 | 520 |
472 QTextStream *qts = new QTextStream(&file); | 521 QTextStream *qts = new QTextStream(&file); |
473 QString qs = qts->readAll(); | 522 QString qs = qts->readAll(); |
474 delete qts; | 523 delete qts; |
475 file.close(); | 524 file.close(); |
476 | 525 |
477 Transform transform(qs); | 526 Transform transform(qs); |
478 | 527 xmlError = transform.getErrorString(); |
479 return addFeatureExtractor(transform, writers); | 528 |
529 if (xmlError == "") { | |
530 | |
531 if (transform.getIdentifier() == "") { | |
532 cerr << "ERROR: Transform file \"" << transformFile | |
533 << "\" is valid XML but defines no transform" << endl; | |
534 return false; | |
535 } | |
536 | |
537 return addFeatureExtractor(transform, writers); | |
538 } | |
539 } | |
540 | |
541 cerr << "ERROR: Transform file \"" << transformFile | |
542 << "\" could not be parsed" << endl; | |
543 if (rdfError != "") { | |
544 cerr << "ERROR: RDF parser reported: " << rdfError << endl; | |
545 } | |
546 if (xmlError != "") { | |
547 cerr << "ERROR: XML parser reported: " << xmlError << endl; | |
548 } | |
549 | |
550 return false; | |
480 } | 551 } |
481 | 552 |
482 void FeatureExtractionManager::addSource(QString audioSource, bool willMultiplex) | 553 void FeatureExtractionManager::addSource(QString audioSource, bool willMultiplex) |
483 { | 554 { |
484 std::cerr << "Have audio source: \"" << audioSource.toStdString() << "\"" << std::endl; | 555 std::cerr << "Have audio source: \"" << audioSource.toStdString() << "\"" << std::endl; |
487 // first audio source and we need it to establish default channel | 558 // first audio source and we need it to establish default channel |
488 // count and sample rate | 559 // count and sample rate |
489 | 560 |
490 if (m_channels == 0 || m_defaultSampleRate == 0) { | 561 if (m_channels == 0 || m_defaultSampleRate == 0) { |
491 | 562 |
492 ProgressPrinter retrievalProgress("Determining default rate and channel count from first input file..."); | 563 ProgressPrinter retrievalProgress("Retrieving first input file to determine default rate and channel count..."); |
493 | 564 |
494 FileSource source(audioSource, &retrievalProgress); | 565 FileSource source(audioSource, &retrievalProgress); |
495 if (!source.isAvailable()) { | 566 if (!source.isAvailable()) { |
496 cerr << "ERROR: File or URL \"" << audioSource.toStdString() | 567 cerr << "ERROR: File or URL \"" << audioSource.toStdString() |
497 << "\" could not be located"; | 568 << "\" could not be located"; |
522 | 593 |
523 if (!willMultiplex) { | 594 if (!willMultiplex) { |
524 if (m_channels == 0) { | 595 if (m_channels == 0) { |
525 m_channels = reader->getChannelCount(); | 596 m_channels = reader->getChannelCount(); |
526 cerr << "Taking default channel count of " | 597 cerr << "Taking default channel count of " |
527 << reader->getChannelCount() << " from file" << endl; | 598 << reader->getChannelCount() << " from audio file" << endl; |
528 } | 599 } |
529 } | 600 } |
530 | 601 |
531 if (m_defaultSampleRate == 0) { | 602 if (m_defaultSampleRate == 0) { |
532 m_defaultSampleRate = reader->getNativeRate(); | 603 m_defaultSampleRate = reader->getNativeRate(); |
533 cerr << "Taking default sample rate of " | 604 cerr << "Taking default sample rate of " |
534 << reader->getNativeRate() << "Hz from file" << endl; | 605 << reader->getNativeRate() << "Hz from audio file" << endl; |
535 cerr << "(Note: Default may be overridden by transforms)" << endl; | 606 cerr << "(Note: Default may be overridden by transforms)" << endl; |
536 } | 607 } |
537 | 608 |
538 m_readyReaders[audioSource] = reader; | 609 m_readyReaders[audioSource] = reader; |
539 } | 610 } |