Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f7d2bcaf82 | |||
| a98a77546f | |||
| 8912e4cad6 | |||
| e1dada8f10 | |||
| aa2c235e1e | |||
| f4d151f1dd | |||
| 2c5d541e3c | |||
| ed3b3a20ac | |||
| 5fd9e91f70 | |||
| c24e851e4e | |||
| 3a951787af | |||
| f8b5659d1a | |||
| a6a7242d22 | |||
| 31ee30d9fd | |||
| e054065a49 | |||
| 54ffb86f53 | |||
| 0ea6a3d047 | |||
| abd7866ae8 | |||
| 91005c27c0 | |||
| 6b7363ac5e | |||
| eb4479bf9d | |||
| a16a2e3a3e |
@@ -1 +1 @@
|
||||
-I ./include -I ./external/Catch/include/ -std=c++11
|
||||
-I ./include -I ./external/Catch/include/ -std=c++14
|
||||
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import pdb
|
||||
import fnmatch
|
||||
|
||||
import sys
|
||||
|
||||
def main():
|
||||
p = subprocess.Popen(["git", "rev-parse", "--show-toplevel"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
|
||||
out = out.strip('\n')
|
||||
track_filepath = os.path.join(out, ".gittrack")
|
||||
|
||||
p = subprocess.Popen(["git", "ls-files", out, "--exclude-standard", "--others"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
|
||||
out = out.splitlines()
|
||||
|
||||
try:
|
||||
with open(track_filepath) as f:
|
||||
content = f.read().splitlines()
|
||||
except IOError:
|
||||
return 0
|
||||
|
||||
|
||||
untracked = []
|
||||
for filepath in out:
|
||||
for name in content:
|
||||
if fnmatch.fnmatch(filepath, name):
|
||||
untracked.append(filepath)
|
||||
|
||||
if untracked:
|
||||
print "The following files are not tracked: "
|
||||
for i in untracked:
|
||||
print i
|
||||
print "Please either stage these files for the commit or add them to the project's .gitignore to disregard them."
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
||||
@@ -1,3 +1,5 @@
|
||||
.DS_Store
|
||||
bin/
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
@@ -27,3 +29,9 @@
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
|
||||
external/
|
||||
CMakeFiles/
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# Use this file to configure the Overcommit hooks you wish to use. This will
|
||||
# extend the default configuration defined in:
|
||||
# https://github.com/brigade/overcommit/blob/master/config/default.yml
|
||||
#
|
||||
# At the topmost level of this YAML file is a key representing type of hook
|
||||
# being run (e.g. pre-commit, commit-msg, etc.). Within each type you can
|
||||
# customize each hook, such as whether to only run it on certain files (via
|
||||
# `include`), whether to only display output if it fails (via `quiet`), etc.
|
||||
#
|
||||
# For a complete list of hooks, see:
|
||||
# https://github.com/brigade/overcommit/tree/master/lib/overcommit/hook
|
||||
#
|
||||
# For a complete list of options that you can use to customize hooks, see:
|
||||
# https://github.com/brigade/overcommit#configuration
|
||||
#
|
||||
# Uncomment the following lines to make the configuration take effect.
|
||||
|
||||
#PreCommit:
|
||||
# RuboCop:
|
||||
# enabled: true
|
||||
# on_warn: fail # Treat all warnings as failures
|
||||
#
|
||||
# TrailingWhitespace:
|
||||
# enabled: true
|
||||
# exclude:
|
||||
# - '**/db/structure.sql' # Ignore trailing whitespace in generated files
|
||||
#
|
||||
#PostCheckout:
|
||||
# ALL: # Special hook name that customizes all hooks of this type
|
||||
# quiet: true # Change all post-checkout hooks to only display output on failure
|
||||
#
|
||||
# IndexTags:
|
||||
# enabled: true # Generate a tags file with `ctags` each time HEAD changes
|
||||
|
||||
|
||||
PreCommit:
|
||||
CheckUntracked:
|
||||
enabled: true
|
||||
quiet: false
|
||||
description: 'Check for files that should be tracked or ignored.'
|
||||
required_executable: './.git-hooks/pre-commit/check_untracked.py'
|
||||
+23
-8
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.5.2)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
# Set the project name
|
||||
project (concatenator)
|
||||
|
||||
@@ -9,6 +9,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
|
||||
### Boost Settings
|
||||
find_package(Boost 1.60.0 COMPONENTS program_options log log_setup thread date_time filesystem system REQUIRED)
|
||||
find_package(LibSndFile REQUIRED)
|
||||
find_package(HDF5 COMPONENTS CXX REQUIRED)
|
||||
|
||||
if (NOT FO_BOOST_STATIC_LINK)
|
||||
add_definitions(-DBOOST_ALL_NO_LIB -DBOOST_ALL_DYN_LINK -DBOOST_LOG_DYN_LINK)
|
||||
@@ -24,34 +25,43 @@ set(CMAKE_CXX_FLAGS "-g -Wall")
|
||||
# Set cmake to output executable to the bin directory
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
|
||||
|
||||
|
||||
|
||||
set(CONCATENATOR_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src)
|
||||
set(CONCATENATOR_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
|
||||
set(CONCATENATOR_TEST_DIR ${PROJECT_SOURCE_DIR}/test)
|
||||
|
||||
set(CONCATENATOR_SOURCE_FILES
|
||||
${CONCATENATOR_SOURCE_DIR}/Concatenator.cpp
|
||||
# Declare source files that are used in both the tests and the main program.
|
||||
set(GLOBAL_SOURCE_FILES
|
||||
${CONCATENATOR_SOURCE_DIR}/AudioDatabase.cpp
|
||||
${CONCATENATOR_SOURCE_DIR}/AudioFile.cpp
|
||||
${CONCATENATOR_SOURCE_DIR}/Logger.cpp
|
||||
${CONCATENATOR_SOURCE_DIR}/ArgumentParser.cpp
|
||||
)
|
||||
|
||||
# Declare source files that are only used in the main program
|
||||
set(CONCATENATOR_SOURCE_FILES
|
||||
${CONCATENATOR_SOURCE_DIR}/Concatenator.cpp
|
||||
${GLOBAL_SOURCE_FILES}
|
||||
)
|
||||
|
||||
# Declare all header files
|
||||
set(CONCATENATOR_HEADER_FILES
|
||||
${CONCATENATOR_INCLUDE_DIR}/ArgumentParser.h
|
||||
${CONCATENATOR_INCLUDE_DIR}/AudioDatabase.h
|
||||
${CONCATENATOR_INCLUDE_DIR}/AudioFile.h
|
||||
${CONCATENATOR_INCLUDE_DIR}/Logger.h
|
||||
${CONCATENATOR_INCLUDE_DIR}/hdf5helper.h
|
||||
)
|
||||
|
||||
# Declare source files that are only used in the test suite
|
||||
set(CONCATENATOR_TEST_SOURCES
|
||||
${CONCATENATOR_TEST_DIR}/Concatenator_Test.cpp
|
||||
${CONCATENATOR_TEST_DIR}/Basic_Tests.cpp
|
||||
${GLOBAL_SOURCE_FILES}
|
||||
)
|
||||
|
||||
include_directories(${CONCATENATOR_INCLUDE_DIR})
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
include_directories(${LIBSNDFILE_INCLUDE_DIR})
|
||||
include_directories(${HDF5_INCLUDE_DIRS})
|
||||
add_subdirectory(external)
|
||||
|
||||
add_executable(concatenator ${CONCATENATOR_SOURCE_FILES} ${CONCATENATOR_HEADER_FILES})
|
||||
@@ -59,6 +69,7 @@ add_executable(concatenator ${CONCATENATOR_SOURCE_FILES} ${CONCATENATOR_HEADER_F
|
||||
# Link to external libraries
|
||||
target_link_libraries(concatenator ${Boost_LIBRARIES})
|
||||
target_link_libraries(concatenator ${LIBSNDFILE_LIBRARIES})
|
||||
target_link_libraries(concatenator ${HDF5_LIBRARIES})
|
||||
|
||||
# Test build options (this code adapted from: https://github.com/ComicSansMS/GhulbusBase/blob/master/CMakeLists.txt)
|
||||
option(BUILD_TESTS "Determines whether to build tests." ON)
|
||||
@@ -90,9 +101,13 @@ if(BUILD_TESTS)
|
||||
target_include_directories(Catch INTERFACE ${CMAKE_BINARY_DIR}/external/Catch/include)
|
||||
endif()
|
||||
|
||||
add_executable(Concatenator_Test ${CONCATENATOR_TEST_SOURCES} ${CONCATENATOR_HEADER_FILES})
|
||||
|
||||
add_executable(Concatenator_Test ${CONCATENATOR_TEST_SOURCES})
|
||||
target_link_libraries(Concatenator_Test ${Boost_LIBRARIES})
|
||||
target_link_libraries(Concatenator_Test ${LIBSNDFILE_LIBRARIES})
|
||||
target_link_libraries(Concatenator_Test ${HDF5_LIBRARIES})
|
||||
target_link_libraries(Concatenator_Test Catch)
|
||||
|
||||
add_test(NAME TestBase COMMAND Concatenator_Test)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
source = /Volumes/Storage/AudioDatabases/Viola/
|
||||
target = /Volumes/Storage/AnalysedAudioDatabases/C++_test1/
|
||||
output = /Volumes/Storage/OutputAudioDatabases/C++_test/
|
||||
|
||||
# Set the audio descriptors to be used for analysis and matching.
|
||||
active_analyses = f0
|
||||
active_analyses = rms
|
||||
|
||||
|
||||
@@ -3,16 +3,19 @@
|
||||
#include <vector>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include "logger.h"
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
namespace po = boost::program_options;
|
||||
namespace fs = boost::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
class ArgumentParser {
|
||||
public:
|
||||
ArgumentParser();
|
||||
~ArgumentParser() {};
|
||||
ArgumentParser(const ArgumentParser&);
|
||||
ArgumentParser& operator=(const ArgumentParser&);
|
||||
int parseargs(int argc, char** argv);
|
||||
@@ -27,14 +30,21 @@ class ArgumentParser {
|
||||
//Create a positional options object for parsing input, output etc
|
||||
//positional arguments from command line.
|
||||
po::positional_options_description positionalOptions;
|
||||
po::options_description desc;
|
||||
po::options_description generic;
|
||||
po::options_description config;
|
||||
string config_path;
|
||||
};
|
||||
|
||||
class ConcatenatorArgParse : public ArgumentParser {
|
||||
public:
|
||||
vector<string> get_analyses() { return (*this)["analyses"].as<vector<string>>(); }
|
||||
vector<string> get_analyses() {
|
||||
std::cout << (*this)["active_analyses"].as<vector<string>>()[0] << std::endl;
|
||||
return (*this)["active_analyses"].as<vector<string>>();
|
||||
}
|
||||
string get_source_db() { return (*this)["source"].as<string>(); }
|
||||
string get_target_db() { return (*this)["target"].as<string>(); }
|
||||
fs::path get_tar_audio_dir() { return ((*this)["tar_audio"].empty() ? fs::path("") : fs::path((*this)["tar_audio"].as<string>())); }
|
||||
fs::path get_src_audio_dir() { return ((*this)["src_audio"].empty() ? fs::path("") : fs::path((*this)["src_audio"].as<string>())); }
|
||||
fs::path get_config_path() { return fs::path((*this)["config"].as<string>()); }
|
||||
};
|
||||
|
||||
|
||||
+17
-6
@@ -1,9 +1,12 @@
|
||||
#ifndef AUDIODATABASE_H
|
||||
#define AUDIODATABASE_H
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <H5Cpp.h>
|
||||
#include "logger.h"
|
||||
|
||||
using std::string;
|
||||
@@ -12,6 +15,7 @@ using std::endl;
|
||||
using std::list;
|
||||
using std::vector;
|
||||
|
||||
|
||||
/*!
|
||||
* A class that encapsulates a collection of AudioFile objects in order to
|
||||
* perform analysis and synthesis operations on batches of audio files.
|
||||
@@ -21,24 +25,30 @@ class AudioDatabase {
|
||||
public:
|
||||
AudioDatabase(
|
||||
const std::string database_dir,
|
||||
vector<string>& analyses,
|
||||
Logger* log
|
||||
vector<string> analyses
|
||||
);
|
||||
void load_database(boost::filesystem::path source_dir, bool reanalyse=false);
|
||||
void load_database(boost::filesystem::path source_dir);
|
||||
void analyse_database(const bool& reanalyse=false);
|
||||
|
||||
private:
|
||||
boost::filesystem::path database_dir;
|
||||
boost::filesystem::path audio_dir;
|
||||
// Define a set that stores the locations of audiofiles in the database.
|
||||
std::set<boost::filesystem::path> audio_file_set;
|
||||
std::set<boost::filesystem::path> audio_files;
|
||||
std::vector<std::string> analyses;
|
||||
std::map<string, boost::filesystem::path> database_dirs;
|
||||
Logger* log;
|
||||
|
||||
void validate_analysis_list();
|
||||
void validate_analysis_list(vector<string>& analyses);
|
||||
bool validate_filetype(const boost::filesystem::path& filepath);
|
||||
void create_subdirs();
|
||||
void organise_audio(boost::filesystem::path source_dir, bool symlink=true);
|
||||
// Used to find and store paths to all audio that is part of the current database
|
||||
void register_audio();
|
||||
|
||||
// Declare a HDF5 file object to be used for storing analysis data.
|
||||
H5::H5File data_file;
|
||||
|
||||
void register_data();
|
||||
};
|
||||
|
||||
/*! A function that determines whether a string value is found in the container.
|
||||
@@ -86,3 +96,4 @@ std::list<string> check_analyses_valid(Iter iterator, Iter end)
|
||||
}
|
||||
return invalid;
|
||||
}
|
||||
#endif
|
||||
|
||||
+78
-14
@@ -1,19 +1,83 @@
|
||||
#ifndef AUDIOFILE_H
|
||||
#define AUDIOFILE_H
|
||||
|
||||
#include <string>
|
||||
#include <sndfile.hh>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <map>
|
||||
#include "analyses/analysis.h"
|
||||
#include "logger.h"
|
||||
#include "H5Cpp.h"
|
||||
|
||||
class AudioFile {
|
||||
public:
|
||||
AudioFile(const char * &name, const int &mode=SFM_RDWR, const int &format=0, const int &channels=0, const int &samplerate=0);
|
||||
int open(const int &mode=SFM_READ, const int &format=0, const int &channels=0, const int &samplerate=0);
|
||||
protected:
|
||||
SndfileHandle file;
|
||||
SF_INFO* file_info;
|
||||
private:
|
||||
std::string name;
|
||||
};
|
||||
namespace fs = boost::filesystem;
|
||||
namespace aa = AudioAnalysis;
|
||||
|
||||
class AnalysedAudioFile : public AudioFile {
|
||||
public:
|
||||
private:
|
||||
};
|
||||
namespace AudioFile {
|
||||
class AnalysedAudioFile {
|
||||
public:
|
||||
AnalysedAudioFile(fs::path filepath) : filepath(filepath) {}
|
||||
|
||||
template <typename T>
|
||||
int open_data(T& data)
|
||||
{
|
||||
try {
|
||||
data.createGroup(name());
|
||||
|
||||
LOGDEBUG << "Created data group for audio file: " << name();
|
||||
}
|
||||
catch(H5::Exception& e){
|
||||
filegroup = data.openGroup(name());
|
||||
LOGDEBUG << "Loaded data group for audio file: " << name();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename Iter>
|
||||
int analyse(Iter it, Iter end, const bool reanalyse)
|
||||
{
|
||||
LOGDEBUG << "Creating analyses for audio file: " << name();
|
||||
// Initialize a factory object for creating analysis objects.
|
||||
aa::AnalysisFactory factory = aa::AnalysisFactory(reanalyse);
|
||||
|
||||
for(; it != end; ++it) {
|
||||
unique_ptr<analysis> a = factory.create(aa::analysis_index_from_string(*it));
|
||||
a->create_analysis();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int open(const int &mode, const int &format, const int &channels, const int &samplerate)
|
||||
{
|
||||
switch(mode){
|
||||
case SFM_READ:
|
||||
file = SndfileHandle(filepath.string());
|
||||
break;
|
||||
case SFM_WRITE:
|
||||
file = SndfileHandle(filepath.string(), SFM_WRITE, format, channels, samplerate);
|
||||
break;
|
||||
case SFM_RDWR:
|
||||
file = SndfileHandle(filepath.string(), SFM_RDWR, format, channels, samplerate);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int open()
|
||||
{
|
||||
file = SndfileHandle(filepath.string());
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string name()
|
||||
{
|
||||
return filepath.stem().string();
|
||||
}
|
||||
|
||||
private:
|
||||
SndfileHandle file;
|
||||
fs::path filepath;
|
||||
H5::Group filegroup;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef ANALYSIS_H
|
||||
#define ANALYSIS_H
|
||||
|
||||
#include "analysis_base.h"
|
||||
#include "rms.h"
|
||||
#include "f0.h"
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace AudioAnalysis {
|
||||
enum analyses {
|
||||
RMS,
|
||||
F0,
|
||||
};
|
||||
|
||||
static inline analyses analysis_index_from_string(const string& s) {
|
||||
static map<string, analyses> analysis_map = { {"RMS", RMS}, {"F0", F0} };
|
||||
return analysis_map[s];
|
||||
}
|
||||
|
||||
class AnalysisFactory
|
||||
{
|
||||
public:
|
||||
AnalysisFactory(const bool& reanalyse) : reanalyse(reanalyse) {}
|
||||
unique_ptr<analysis> create(analyses analysis_type)
|
||||
{
|
||||
switch(analysis_type)
|
||||
{
|
||||
case RMS:
|
||||
return make_unique<rms>();
|
||||
case F0:
|
||||
return make_unique<f0>();
|
||||
}
|
||||
}
|
||||
private:
|
||||
bool reanalyse;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef ANALYSIS_BASE_H
|
||||
#define ANALYSIS_BASE_H
|
||||
|
||||
class analysis
|
||||
{
|
||||
public:
|
||||
virtual ~analysis() {};
|
||||
virtual void create_analysis() = 0;
|
||||
private:
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef F0_H
|
||||
#define F0_H
|
||||
#include "analysis.h"
|
||||
#include "logger.h"
|
||||
|
||||
class f0 : public analysis
|
||||
{
|
||||
public:
|
||||
void create_analysis() {LOGDEBUG << "Creating F0 analysis (WARNING: currently not implemented)";};
|
||||
private:
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef RMS_H
|
||||
#define RMS_H
|
||||
#include "analysis.h"
|
||||
#include "logger.h"
|
||||
|
||||
class rms : public analysis
|
||||
{
|
||||
public:
|
||||
void create_analysis() {LOGDEBUG << "Creating RMS analysis (WARNING: currently not implemented)";};
|
||||
private:
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "H5Cpp.h"
|
||||
|
||||
namespace hdf5helper {
|
||||
template <typename T>
|
||||
bool groupExists(T group, std::string name)
|
||||
{
|
||||
try {
|
||||
group.openGroup(name);
|
||||
return true;
|
||||
}
|
||||
catch(H5::GroupIException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-32
@@ -1,36 +1,20 @@
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/log/sinks.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <boost/log/sources/record_ostream.hpp>
|
||||
#include <boost/log/utility/formatting_ostream.hpp>
|
||||
#pragma once
|
||||
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/sources/global_logger_storage.hpp>
|
||||
#include <boost/log/support/date_time.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/utility/setup.hpp>
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
Logger();
|
||||
~Logger();
|
||||
void trace(std::string str);
|
||||
void debug(std::string str);
|
||||
void info(std::string str);
|
||||
void warning(std::string str);
|
||||
void error(std::string str);
|
||||
void fatal(std::string str);
|
||||
#define LOGTRACE BOOST_LOG_SEV(logger::get(), boost::log::trivial::trace)
|
||||
#define LOGDEBUG BOOST_LOG_SEV(logger::get(), boost::log::trivial::debug)
|
||||
#define LOGINFO BOOST_LOG_SEV(logger::get(), boost::log::trivial::info)
|
||||
#define LOGWARN BOOST_LOG_SEV(logger::get(), boost::log::trivial::warning)
|
||||
#define LOGERROR BOOST_LOG_SEV(logger::get(), boost::log::trivial::error)
|
||||
#define LOGFATAL BOOST_LOG_SEV(logger::get(), boost::log::trivial::fatal)
|
||||
|
||||
private:
|
||||
//Narrow-char thread-safe logger.
|
||||
typedef boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger_t;
|
||||
|
||||
static void log_formatter(boost::log::record_view const& rec, boost::log::formatting_ostream& strm);
|
||||
|
||||
// Define types for logging backends
|
||||
typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend> console_backend;
|
||||
typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend> file_backend;
|
||||
|
||||
// Define a sink for console output and for log file output
|
||||
boost::shared_ptr<console_backend> console_sink;
|
||||
boost::shared_ptr<file_backend> file_sink;
|
||||
|
||||
//Define a logger
|
||||
boost::log::sources::severity_logger< boost::log::trivial::severity_level > lg;
|
||||
};
|
||||
#endif
|
||||
//declares a global logger with a custom initialization
|
||||
BOOST_LOG_GLOBAL_LOGGER(logger, logger_t)
|
||||
|
||||
+67
-11
@@ -1,22 +1,48 @@
|
||||
#include "ArgumentParser.h"
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
ArgumentParser::ArgumentParser() : desc("Allowed options") {
|
||||
namespace fs = boost::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
ArgumentParser::ArgumentParser() : generic("Command line options"), config("Configuration") {
|
||||
// Add positional arguments to specify source, target and output database locations.
|
||||
positionalOptions.add("source", 1);
|
||||
positionalOptions.add("target", 1);
|
||||
positionalOptions.add("output", 1);
|
||||
|
||||
// Add optional arguments to allow control over application settings from the command line.
|
||||
desc.add_options()
|
||||
generic.add_options()
|
||||
("help,h", "produce help message")
|
||||
("source", po::value<string>(), "Source location")
|
||||
("target", po::value<string>(), "Target location")
|
||||
("output", po::value<string>(), "Output location")
|
||||
("active_analyses,a", po::value<vector<string>>()->multitoken(), "Analysis "
|
||||
"strings specifying analyses to use for database comparison.")
|
||||
("src_audio", po::value<string>(), "Specifies the "
|
||||
"directory to create the source database and store analyses in. If "
|
||||
"not specified then the " "source directory will be used directly.")
|
||||
("tar_audio", po::value<string>(), "Specifies the "
|
||||
"directory to create the target database and store analyses in. If "
|
||||
"not specified then the target directory will be used directly.")
|
||||
("config,c", po::value<string>()->default_value("config.ini"),
|
||||
"Specifies the location of a config file to be used for configuring "
|
||||
"the program. If no config is specified, the default ./config.ini "
|
||||
"file found in the concatenator project directory, will be used.")
|
||||
;
|
||||
|
||||
config.add_options()
|
||||
("source", po::value<string>()->required(), "Source location")
|
||||
("target", po::value<string>()->required(), "Target location")
|
||||
("output", po::value<string>()->required(), "Output location")
|
||||
("analyses,a", po::value<vector<string>>()->multitoken(), "Analysis "
|
||||
("active_analyses", po::value<vector<string>>()->multitoken(), "Analysis "
|
||||
"strings specifying analyses to use for database comparison.")
|
||||
("src_audio", po::value<string>(), "Specifies the "
|
||||
"directory to create the source database and store analyses in. If "
|
||||
@@ -25,22 +51,34 @@ ArgumentParser::ArgumentParser() : desc("Allowed options") {
|
||||
"directory to create the target database and store analyses in. If "
|
||||
"not specified then the target directory will be used directly.")
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
int ArgumentParser::parseargs(int argc, char** argv) {
|
||||
po::store(po::command_line_parser(argc, argv).options(desc).positional(positionalOptions).run(), vm);
|
||||
|
||||
po::options_description cmdline_options;
|
||||
cmdline_options.add(generic).add(config);
|
||||
|
||||
po::options_description config_file_options;
|
||||
config_file_options.add(config);
|
||||
|
||||
po::store(po::command_line_parser(argc, argv).options(generic).positional(positionalOptions).run(), vm);;
|
||||
po::notify(vm);
|
||||
|
||||
std::ifstream settings_file(vm["config"].as<string>());
|
||||
if(!settings_file) {
|
||||
throw runtime_error("The configuration file could not be found: " + vm["config"].as<string>());
|
||||
}
|
||||
|
||||
po::store(po::parse_config_file(settings_file, config), vm);
|
||||
po::notify(vm);
|
||||
|
||||
// If help option is specified then output help message
|
||||
if (vm.count("help")) {
|
||||
cout << desc << "\n";
|
||||
return 1;
|
||||
cout << generic << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
po::notify(vm);
|
||||
|
||||
if (vm["analyses"].empty()) {
|
||||
throw runtime_error("No analysis strings provided as arguments.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -51,3 +89,21 @@ const po::variable_value& ArgumentParser::operator [](char const *b) const {
|
||||
po::variables_map::size_type ArgumentParser::count(char const *ref) {
|
||||
return vm.count(ref);
|
||||
}
|
||||
/*
|
||||
void split(const string &s, char delim, vector<string> &elems) {
|
||||
stringstream ss(s);
|
||||
string item;
|
||||
while (getline(ss, item, delim)) {
|
||||
elems.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vector<string> split(const string &s, char delim=' ') {
|
||||
vector<string> elems;
|
||||
split(s, delim, elems);
|
||||
return elems;
|
||||
}
|
||||
|
||||
vector<string> ConcatenatorArgParse::get_analyses() { return split((*this)["active_analyses"].as<string>()); }
|
||||
*/
|
||||
|
||||
+71
-32
@@ -1,33 +1,43 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include "AudioDatabase.h"
|
||||
#include "AudioFile.h"
|
||||
#include <stdexcept>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include "H5Cpp.h"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
using namespace std;
|
||||
using namespace H5;
|
||||
using namespace AudioFile;
|
||||
|
||||
AudioDatabase::AudioDatabase(
|
||||
const string database_dir,
|
||||
vector<string>& analyses,
|
||||
Logger* log
|
||||
)
|
||||
vector<string> analyses
|
||||
) : analyses(analyses)
|
||||
{
|
||||
this->log = log;
|
||||
|
||||
log->info("Database directory: " + database_dir);
|
||||
LOGINFO << "Database directory: " << database_dir;
|
||||
|
||||
// Remove duplicate strings from vector of analyses.
|
||||
std::vector<string>::iterator it;
|
||||
it = std::unique (analyses.begin(), analyses.end());
|
||||
analyses.resize(std::distance(analyses.begin(),it));
|
||||
it = std::unique (this->analyses.begin(), this->analyses.end());
|
||||
analyses.resize(std::distance(this->analyses.begin(),it));
|
||||
|
||||
validate_analysis_list(this->analyses);
|
||||
|
||||
database_dirs.insert({"root", fs::path(database_dir)});
|
||||
this->audio_dir = fs::path(audio_dir);
|
||||
|
||||
}
|
||||
|
||||
void AudioDatabase::validate_analysis_list(vector<string>& analyses)
|
||||
{
|
||||
// Check that all analysis strings supplied refer to valid analyses.
|
||||
list<string> invalid = check_analyses_valid(analyses.begin(), analyses.end());
|
||||
if(!invalid.empty()) {
|
||||
@@ -35,27 +45,20 @@ AudioDatabase::AudioDatabase(
|
||||
string invalid_strings = boost::algorithm::join(invalid, " ");
|
||||
throw std::runtime_error(err + invalid_strings);
|
||||
}
|
||||
|
||||
database_dirs.insert({"root", fs::path(database_dir)});
|
||||
this->audio_dir = fs::path(audio_dir);
|
||||
}
|
||||
|
||||
void AudioDatabase::validate_analysis_list()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioDatabase::load_database(fs::path source_dir, bool reanalyse)
|
||||
void AudioDatabase::load_database(fs::path source_dir)
|
||||
{
|
||||
// Make sure the database root directory exists.
|
||||
try
|
||||
{
|
||||
if(create_directory(database_dirs["root"]))
|
||||
{
|
||||
log->debug("Database directory created: " + database_dir.string());
|
||||
LOGDEBUG << "Database directory created: " << database_dir.string();
|
||||
}
|
||||
else if(exists(database_dirs["root"]))
|
||||
{
|
||||
log->debug("Database directory already exists: " + database_dir.string());
|
||||
LOGDEBUG << "Database directory already exists: " << database_dir.string();
|
||||
}
|
||||
}
|
||||
catch(boost::filesystem::filesystem_error &e)
|
||||
@@ -69,7 +72,7 @@ void AudioDatabase::load_database(fs::path source_dir, bool reanalyse)
|
||||
|
||||
if(source_dir.empty()) {
|
||||
source_dir = database_dirs["audio"];
|
||||
log->debug("Source directory not provided. Setting to:" + source_dir.string());
|
||||
LOGDEBUG << "Source directory not provided. Setting to:" << source_dir.string();
|
||||
}
|
||||
|
||||
if(!exists(source_dir)) {
|
||||
@@ -85,11 +88,47 @@ void AudioDatabase::load_database(fs::path source_dir, bool reanalyse)
|
||||
// Find all audio in the database and store references for use later...
|
||||
register_audio();
|
||||
|
||||
//Find/create HDF5 file for storage of analysis data.
|
||||
register_data();
|
||||
|
||||
}
|
||||
|
||||
void AudioDatabase::analyse_database(const bool& reanalyse)
|
||||
{
|
||||
for(auto afile_path : audio_files)
|
||||
{
|
||||
AnalysedAudioFile afile = AnalysedAudioFile(afile_path);
|
||||
afile.open_data(data_file);
|
||||
afile.analyse(analyses.begin(), analyses.end(), reanalyse);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDatabase::register_data()
|
||||
{
|
||||
fs::path data_path = database_dirs["data"]/fs::path("data.hdf5");
|
||||
try
|
||||
{
|
||||
data_file = H5File(data_path.string(), H5F_ACC_RDWR);
|
||||
LOGINFO << "Reading database data from: " << (database_dirs["data"]/fs::path("data.hdf5")).string();
|
||||
}
|
||||
catch(FileIException &e)
|
||||
{
|
||||
if(!fs::exists(data_path.string()))
|
||||
{
|
||||
data_file = H5File(data_path.string(), H5F_ACC_TRUNC);
|
||||
LOGINFO << "Creating new database file at: " << (database_dirs["data"]/fs::path("data.hdf5")).string();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGINFO << "Data file exists but cannot be read: " << data_path.string();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDatabase::create_subdirs()
|
||||
{
|
||||
array<fs::path, 2> directory_names = {{
|
||||
static array<fs::path, 2> directory_names = {{
|
||||
fs::path("audio"),
|
||||
fs::path("data")
|
||||
}};
|
||||
@@ -99,11 +138,11 @@ void AudioDatabase::create_subdirs()
|
||||
try
|
||||
{
|
||||
if(create_directory(subdir)) {
|
||||
log->info("Subdirectory created: " + subdir.string());
|
||||
LOGINFO << "Subdirectory created: " << subdir.string();
|
||||
}
|
||||
else if(exists(database_dirs["root"]))
|
||||
{
|
||||
log->info("Subdirectory already exists: " + subdir.string());
|
||||
LOGINFO << "Subdirectory already exists: " << subdir.string();
|
||||
}
|
||||
}
|
||||
catch(boost::filesystem::filesystem_error &e)
|
||||
@@ -138,7 +177,7 @@ bool AudioDatabase::validate_filetype(const fs::path& filepath)
|
||||
void AudioDatabase::organise_audio(fs::path source_dir, bool symlink)
|
||||
{
|
||||
|
||||
log->info("Organising audio directory at: " + database_dirs["audio"].string());
|
||||
LOGINFO << "Organising audio directory at: " << database_dirs["audio"].string();
|
||||
// Define the destination for copying/linking all valid audio files found.
|
||||
for(fs::recursive_directory_iterator iter(source_dir), end; iter != end; ++iter)
|
||||
{
|
||||
@@ -149,7 +188,7 @@ void AudioDatabase::organise_audio(fs::path source_dir, bool symlink)
|
||||
}
|
||||
|
||||
if(!validate_filetype(iter->path())) {
|
||||
log->debug("File: " + iter->path().string() + " isn't a supported audiofile. Skipping...");
|
||||
LOGINFO << "File: " << iter->path().string() << " isn't a supported audiofile. Skipping...";
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -160,17 +199,17 @@ void AudioDatabase::organise_audio(fs::path source_dir, bool symlink)
|
||||
// Try to symlink the file to the audio directory of the database.
|
||||
try {
|
||||
fs::create_symlink(iter->path(), destination_file);
|
||||
log->debug("Linked: " + iter->path().string() + " to: " + destination_file.string());
|
||||
LOGINFO << "Linked: " << iter->path().string() << " to: " << destination_file.string();
|
||||
}
|
||||
catch(boost::filesystem::filesystem_error &e){
|
||||
// If symbolic linking fails then the file probably already exists at the location.
|
||||
log->debug("Failed to link: " + iter->path().string() + " to " + destination_file.string() + " File may already exists.");
|
||||
LOGINFO << "Failed to link: " << iter->path().string() << " to " << destination_file.string() << " File may already exists.";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If it is in the database as a symlink, but a full copy is required
|
||||
if(fs::exists(destination_file) && !fs::is_symlink(destination_file)) {
|
||||
log->debug("File already exists: " + iter->path().string());
|
||||
LOGINFO << "File already exists: " << iter->path().string();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -178,11 +217,11 @@ void AudioDatabase::organise_audio(fs::path source_dir, bool symlink)
|
||||
try {
|
||||
fs::remove(destination_file);
|
||||
fs::copy_file(iter->path(), destination_file, fs::copy_option::overwrite_if_exists);
|
||||
log->debug("Copied: " + iter->path().string() + " to: " + destination_file.string());
|
||||
LOGDEBUG << "Copied: " << iter->path().string() << " to: " << destination_file.string();
|
||||
}
|
||||
catch(boost::filesystem::filesystem_error &e){
|
||||
// If symbolic linking fails then the file probably already exists at the location.
|
||||
log->debug("Failed to copy source file to: " + destination_file.string() + " File may already exists.");
|
||||
LOGDEBUG << "Failed to copy source file to: " << destination_file.string() << " File may already exists.";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -191,12 +230,12 @@ void AudioDatabase::organise_audio(fs::path source_dir, bool symlink)
|
||||
void AudioDatabase::register_audio()
|
||||
{
|
||||
// Clear any previous entries from set.
|
||||
audio_file_set.clear();
|
||||
audio_files.clear();
|
||||
for(auto& entry : boost::make_iterator_range(fs::directory_iterator(database_dirs["audio"]), {}))
|
||||
{
|
||||
if(validate_filetype(entry.path())) {
|
||||
log->info("Registered audio file: " + entry.path().string());
|
||||
audio_file_set.insert(entry.path());
|
||||
LOGINFO << "Registered audio file: " << entry.path().string();
|
||||
audio_files.insert(entry.path());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#include "AudioFile.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
AudioFile::AudioFile(const char * &name, const int &mode, const int &format, const int &channels, const int &samplerate)
|
||||
{
|
||||
this->name = name;
|
||||
open(mode, format, channels, samplerate);
|
||||
}
|
||||
|
||||
int AudioFile::open(const int &mode, const int &format, const int &channels, const int &samplerate)
|
||||
{
|
||||
switch(mode){
|
||||
case SFM_READ: file = SndfileHandle(name);
|
||||
case SFM_WRITE: file = SndfileHandle(name, SFM_WRITE, format, channels, samplerate);
|
||||
case SFM_RDWR: file = SndfileHandle(name, SFM_RDWR, format, channels, samplerate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+16
-22
@@ -1,12 +1,16 @@
|
||||
#include <iostream>
|
||||
#include "logger.h"
|
||||
#include "Logger.h"
|
||||
#include "ArgumentParser.h"
|
||||
#include "AudioDatabase.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include "H5Cpp.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
namespace
|
||||
{
|
||||
const size_t ERROR_IN_COMMAND_LINE = 1;
|
||||
@@ -16,14 +20,9 @@ namespace
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// Initialize a logger object to be used for message handeling throughout
|
||||
// the program
|
||||
Logger log = Logger();
|
||||
/*
|
||||
try
|
||||
{
|
||||
*/
|
||||
|
||||
// Prevent HDF5 library from printing errors that are handeled in try/catch blocks.
|
||||
H5::Exception::dontPrint();
|
||||
//
|
||||
// Initialize object to parse arguments supplied by user from command
|
||||
// line
|
||||
ConcatenatorArgParse argparse = ConcatenatorArgParse();
|
||||
@@ -32,16 +31,20 @@ int main(int argc, char** argv) {
|
||||
if(argparse.parseargs(argc, argv)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
fs::path config_filepath = argparse.get_config_path();
|
||||
if(config_filepath.empty()) {
|
||||
config_filepath = fs::path("./config.json");
|
||||
}
|
||||
vector<string> analyses = argparse.get_analyses();
|
||||
|
||||
// Initialize the source audio database object with arguments provided from the command line.
|
||||
AudioDatabase source_db = AudioDatabase(
|
||||
argparse.get_source_db(),
|
||||
analyses,
|
||||
&log
|
||||
analyses
|
||||
);
|
||||
source_db.load_database(argparse.get_src_audio_dir());
|
||||
source_db.analyse_database();
|
||||
|
||||
/*
|
||||
// Initialize the target audio database object with arguments provided from the command line.
|
||||
@@ -51,18 +54,9 @@ int main(int argc, char** argv) {
|
||||
&log
|
||||
);
|
||||
target_db.load_database(argparse.get_tar_audio_dir());
|
||||
*/
|
||||
|
||||
/*
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
string error("Unhandled Exception reached the top of main:\n");
|
||||
error.append(e.what());
|
||||
|
||||
log.error(error);
|
||||
throw;
|
||||
}
|
||||
*/
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
+30
-91
@@ -1,102 +1,41 @@
|
||||
#include <boost/log/common.hpp>
|
||||
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||
#include <boost/log/sinks.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/utility/setup/file.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/support/date_time.hpp>
|
||||
#include <boost/core/null_deleter.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <ostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "Logger.h"
|
||||
|
||||
namespace attrs = boost::log::attributes;
|
||||
namespace expr = boost::log::expressions;
|
||||
namespace logging = boost::log;
|
||||
namespace src = boost::log::sources;
|
||||
namespace expr = boost::log::expressions;
|
||||
namespace keywords = boost::log::keywords;
|
||||
|
||||
//BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", int)
|
||||
|
||||
Logger::Logger() {
|
||||
|
||||
boost::log::register_simple_formatter_factory< boost::log::trivial::severity_level, char >("Severity");
|
||||
Logger::console_sink = boost::make_shared<console_backend>();
|
||||
|
||||
Logger::file_sink =
|
||||
boost::make_shared<file_backend>(
|
||||
keywords::file_name = "concatenator_log_%N.log",
|
||||
keywords::rotation_size = 5 * 1024 * 1024
|
||||
);
|
||||
|
||||
|
||||
Logger::file_sink->set_formatter(
|
||||
expr::stream <<
|
||||
"[" <<
|
||||
expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S") <<
|
||||
"] [" <<
|
||||
logging::trivial::severity <<
|
||||
"] --- " <<
|
||||
expr::smessage
|
||||
);
|
||||
|
||||
Logger::console_sink->set_formatter(
|
||||
expr::stream <<
|
||||
"[" <<
|
||||
expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S") <<
|
||||
"] [" <<
|
||||
logging::trivial::severity <<
|
||||
"] --- " <<
|
||||
expr::smessage
|
||||
);
|
||||
|
||||
boost::shared_ptr<std::ostream> stdout_stream{&std::clog, boost::null_deleter{}};
|
||||
Logger::console_sink->locked_backend()->add_stream(stdout_stream);
|
||||
|
||||
Logger::console_sink->locked_backend()->auto_flush(true);
|
||||
Logger::file_sink->locked_backend()->auto_flush(true);
|
||||
|
||||
//Logger::sink->set_filter(severity > 0);
|
||||
|
||||
logging::core::get()->add_sink(Logger::file_sink);
|
||||
logging::core::get()->add_sink(Logger::console_sink);
|
||||
//Defines a global logger initialization routine
|
||||
//Defines a global logger initialization routine
|
||||
BOOST_LOG_GLOBAL_LOGGER_INIT(logger, logger_t)
|
||||
{
|
||||
logger_t lg;
|
||||
|
||||
logging::add_common_attributes();
|
||||
|
||||
};
|
||||
logging::add_file_log(
|
||||
boost::log::keywords::file_name = "concatenator_log_%N.log",
|
||||
boost::log::keywords::format = (
|
||||
expr::stream << "[" << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
|
||||
<< "] [" << expr::attr< boost::log::trivial::severity_level >("Severity") << "] --- "
|
||||
<< expr::smessage
|
||||
)
|
||||
);
|
||||
|
||||
Logger::~Logger() {
|
||||
Logger::file_sink->flush();
|
||||
Logger::console_sink->flush();
|
||||
}
|
||||
void Logger::trace(std::string str) {
|
||||
BOOST_LOG_SEV(lg, logging::trivial::trace) << str;
|
||||
}
|
||||
logging::add_console_log(
|
||||
std::cout,
|
||||
boost::log::keywords::format = (
|
||||
expr::stream << "[" << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
|
||||
<< "] [" << expr::attr< boost::log::trivial::severity_level >("Severity") << "] --- "
|
||||
<< expr::smessage
|
||||
)
|
||||
);
|
||||
|
||||
void Logger::debug(std::string str) {
|
||||
BOOST_LOG_SEV(lg, logging::trivial::debug) << str;
|
||||
}
|
||||
/*
|
||||
logging::core::get()->set_filter
|
||||
(
|
||||
logging::trivial::severity >= logging::trivial::info
|
||||
);
|
||||
*/
|
||||
|
||||
void Logger::info(std::string str) {
|
||||
BOOST_LOG_SEV(lg, logging::trivial::info) << str;
|
||||
}
|
||||
|
||||
void Logger::warning(std::string str) {
|
||||
BOOST_LOG_SEV(lg, logging::trivial::warning) << str;
|
||||
}
|
||||
|
||||
void Logger::error(std::string str) {
|
||||
BOOST_LOG_SEV(lg, logging::trivial::error) << str;
|
||||
Logger::file_sink->flush();
|
||||
Logger::console_sink->flush();
|
||||
}
|
||||
|
||||
void Logger::fatal(std::string str) {
|
||||
BOOST_LOG_SEV(lg, logging::trivial::fatal) << str;
|
||||
Logger::file_sink->flush();
|
||||
Logger::console_sink->flush();
|
||||
return lg;
|
||||
}
|
||||
|
||||
@@ -1 +1,39 @@
|
||||
#include "catch.hpp"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "H5Cpp.h"
|
||||
#include "hdf5helper.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include "AudioFile.h"
|
||||
namespace fs = boost::filesystem;
|
||||
using namespace H5;
|
||||
using namespace AudioFile;
|
||||
|
||||
SCENARIO("HDF5 groups are handled correctly in the AnalysedAudioFile class", "[HDF5][AnalysedAudioFile]") {
|
||||
GIVEN("An AnalysedAudioFile and a HDF5 file") {
|
||||
H5File data_file = H5File("./.test_data.hdf5", H5F_ACC_TRUNC);
|
||||
AnalysedAudioFile test_audio = AnalysedAudioFile(fs::path(".test_audio.wav"));
|
||||
|
||||
WHEN("open_data is called using a H5File object") {
|
||||
test_audio.open_data(data_file);
|
||||
|
||||
THEN("a group is created using the name of the audio file") {
|
||||
REQUIRE(hdf5helper::groupExists(data_file, test_audio.name()));
|
||||
|
||||
AND_WHEN("open_data is called again to read a group that now already exists") {
|
||||
test_audio.open_data(data_file);
|
||||
THEN("The group should be loaded without error")
|
||||
{
|
||||
//TODO: Add check that group still contains data created in previous test.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(fs::exists("./.test_data.hdf5")) {
|
||||
fs::remove("./.test_data.hdf5");
|
||||
}
|
||||
if(fs::exists(".test_audio.wav")) {
|
||||
fs::remove(".test_audio.wav");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
|
||||
#include <catch.hpp>
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include "catch.hpp"
|
||||
#include "H5Cpp.h"
|
||||
|
||||
using namespace H5;
|
||||
|
||||
int main( int argc, char* const argv[] )
|
||||
{
|
||||
// Global setup goes here...
|
||||
// Prevent HDF5 library from printing errors that are handeled in try/catch blocks.
|
||||
Exception::dontPrint();
|
||||
|
||||
int result = Catch::Session().run( argc, argv );
|
||||
|
||||
// global clean-up goes here...
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user