tomwalters@296: // Copyright 2008-2010, Thomas Walters tomwalters@296: // tomwalters@296: // AIM-C: A C++ implementation of the Auditory Image Model tomwalters@296: // http://www.acousticscale.org/AIMC tomwalters@296: // tomwalters@318: // Licensed under the Apache License, Version 2.0 (the "License"); tomwalters@318: // you may not use this file except in compliance with the License. tomwalters@318: // You may obtain a copy of the License at tomwalters@296: // tomwalters@318: // http://www.apache.org/licenses/LICENSE-2.0 tomwalters@296: // tomwalters@318: // Unless required by applicable law or agreed to in writing, software tomwalters@318: // distributed under the License is distributed on an "AS IS" BASIS, tomwalters@318: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. tomwalters@318: // See the License for the specific language governing permissions and tomwalters@318: // limitations under the License. tomwalters@296: tomwalters@296: /*! tomwalters@296: * \file AIMCopy.cpp tomwalters@296: * \brief AIM-C replacement for HTK's HCopy tomwalters@296: * tomwalters@296: * The following subset of the command-line flags tomwalters@296: * should be implemented from HCopy: tomwalters@296: * -A Print command line arguments off tomwalters@296: * -C cf Set config file to cf default tomwalters@296: * (should be able to take multiple config files) tomwalters@296: * -S f Set script file to f none tomwalters@296: * //! \todo -T N Set trace flags to N 0 tomwalters@296: * -V Print version information off tomwalters@296: * -D of Write configuration data to of none tomwalters@296: * tomwalters@296: * \author Thomas Walters tomwalters@296: * \date created 2008/05/08 tomwalters@296: * \version \$Id$ tomwalters@296: */ tomwalters@296: tomwalters@296: #include tomwalters@296: #include tomwalters@296: #include tomwalters@296: #include tomwalters@296: #include tomwalters@296: tomwalters@296: #include tomwalters@297: #include tomwalters@296: tomwalters@296: #include "Support/Common.h" tomwalters@296: #include "Support/FileList.h" tomwalters@402: #include "Support/ModuleTree.h" tomwalters@296: #include "Support/Parameters.h" tomwalters@296: tomwalters@402: namespace aimc { tomwalters@296: using std::ofstream; tomwalters@296: using std::pair; tomwalters@296: using std::vector; tomwalters@296: using std::string; tomwalters@402: class AIMCopy { tomwalters@402: public: tomwalters@402: AIMCopy(); tomwalters@402: tomwalters@402: bool Initialize(string script_filename, tomwalters@402: string config_filename); tomwalters@402: tomwalters@402: bool WriteConfig(string config_dump_filename, tomwalters@402: string config_graph_filename); tomwalters@402: tomwalters@402: bool Process(); tomwalters@402: tomwalters@402: private: tomwalters@402: bool initialized_; tomwalters@402: Parameters global_parameters_; tomwalters@402: ModuleTree tree_; tomwalters@402: vector > script_; tomwalters@402: }; tomwalters@402: tomwalters@402: tomwalters@402: AIMCopy::AIMCopy() : initialized_(false) { tomwalters@402: tomwalters@402: } tomwalters@402: tomwalters@402: bool AIMCopy::Initialize(string script_filename, tomwalters@402: string config_filename) { tomwalters@402: tomwalters@402: LOG_INFO("AIMCopy: Loading script"); tomwalters@402: script_ = FileList::Load(script_filename); tomwalters@402: if (script_.size() == 0) { tomwalters@402: LOG_ERROR("No data read from script file %s", script_filename.c_str()); tomwalters@402: return false; tomwalters@402: } tomwalters@402: tomwalters@402: LOG_INFO("AIMCopy: Loading configuration"); tomwalters@402: if (!tree_.LoadConfigFile(config_filename)) { tomwalters@402: LOG_ERROR(_T("Failed to load configuration file")); tomwalters@402: return false; tomwalters@402: } tomwalters@402: LOG_INFO("AIMCopy: Successfully loaded configuration"); tomwalters@402: initialized_ = true; tomwalters@402: return true; tomwalters@402: } tomwalters@402: tomwalters@402: bool AIMCopy::WriteConfig(string config_dump_filename, tomwalters@402: string config_graph_filename) { tomwalters@402: if (!initialized_) { tomwalters@402: return false; tomwalters@402: } tomwalters@402: tomwalters@402: if (script_.size() > 0) { tomwalters@402: global_parameters_.SetString("input_filename", script_[0].first.c_str()); tomwalters@402: global_parameters_.SetString("output_filename_base", script_[0].second.c_str()); tomwalters@402: LOG_INFO("AIMCopy: Initializing tree for initial parameter write."); tomwalters@402: if (!tree_.Initialize(&global_parameters_)) { tomwalters@402: LOG_ERROR(_T("Failed to initialize tree.")); tomwalters@402: return false; tomwalters@402: } tomwalters@411: tree_.Reset(); tomwalters@402: } else { tomwalters@402: LOG_ERROR(_T("No input files in script.")); tomwalters@402: return false; tomwalters@402: } tomwalters@402: tomwalters@402: if (!config_dump_filename.empty()) { tomwalters@402: LOG_INFO("AIMCopy: Dumping configuration."); tomwalters@402: ofstream output_stream; tomwalters@402: output_stream.open(config_dump_filename.c_str()); tomwalters@402: if (output_stream.fail()) { tomwalters@402: LOG_ERROR(_T("Failed to open configuration file %s for writing."), tomwalters@402: config_dump_filename.c_str()); tomwalters@402: return false; tomwalters@402: } tomwalters@402: tomwalters@402: time_t rawtime; tomwalters@402: struct tm * timeinfo; tomwalters@402: time(&rawtime); tomwalters@402: timeinfo = localtime(&rawtime); tomwalters@402: output_stream << "# AIM-C AIMCopy\n"; tomwalters@402: output_stream << "# Run at: " << asctime(timeinfo); tomwalters@402: char * descr = getenv("USER"); tomwalters@402: if (descr) { tomwalters@402: output_stream << "# By user: " << descr <<"\n"; tomwalters@402: } tomwalters@402: tree_.PrintConfiguration(output_stream); tomwalters@402: output_stream.close(); tomwalters@402: } tomwalters@402: tomwalters@402: if (!config_graph_filename.empty()) { tomwalters@402: ofstream output_stream; tomwalters@402: output_stream.open(config_graph_filename.c_str()); tomwalters@402: if (output_stream.fail()) { tomwalters@402: LOG_ERROR(_T("Failed to open graph file %s for writing."), tomwalters@402: config_graph_filename.c_str()); tomwalters@402: return false; tomwalters@402: } tomwalters@402: tree_.MakeDotGraph(output_stream); tomwalters@402: output_stream.close(); tomwalters@402: } tomwalters@402: return true; tomwalters@402: } tomwalters@402: tomwalters@402: bool AIMCopy::Process() { tomwalters@402: if (!initialized_) { tomwalters@402: return false; tomwalters@402: } tomwalters@418: bool tree_initialized = false; tomwalters@402: for (unsigned int i = 0; i < script_.size(); ++i) { tomwalters@402: global_parameters_.SetString("input_filename", script_[i].first.c_str()); tomwalters@402: global_parameters_.SetString("output_filename_base", script_[i].second.c_str()); tomwalters@418: if (!tree_initialized) { tomwalters@418: if (!tree_.Initialize(&global_parameters_)) { tomwalters@418: return false; tomwalters@418: } tomwalters@418: tree_initialized = true; tomwalters@418: } else { tomwalters@418: tree_.Reset(); tomwalters@402: } tomwalters@402: aimc::LOG_INFO(_T("%s -> %s"), tomwalters@402: script_[i].first.c_str(), tomwalters@402: script_[i].second.c_str()); tomwalters@411: tree_.Process(); tomwalters@402: } tomwalters@418: // A final call to Reset() is required to close any open files. tomwalters@418: global_parameters_.SetString("input_filename", ""); tomwalters@418: global_parameters_.SetString("output_filename_base", ""); tomwalters@418: tree_.Reset(); tomwalters@402: return true; tomwalters@402: } tomwalters@402: tomwalters@402: } // namespace aimc tomwalters@402: tomwalters@296: int main(int argc, char* argv[]) { tomwalters@402: std::string data_file; tomwalters@402: std::string dot_file; tomwalters@402: std::string config_file; tomwalters@402: std::string script_file; tomwalters@296: tomwalters@402: const std::string version_string( tomwalters@296: " AIM-C AIMCopy\n" tomwalters@296: " (c) 2006-2010, Thomas Walters and Willem van Engen\n" tomwalters@296: " http://www.acoustiscale.org/AIMC/\n" tomwalters@402: "\n"); tomwalters@402: tomwalters@402: const std::string usage_string( tomwalters@402: "AIMCopy is intended as a drop-in replacement for HTK's HCopy\n" tomwalters@402: "command. It is used for making features from audio files for\n" tomwalters@402: "use with HTK.\n" tomwalters@402: "Usage: \n" tomwalters@402: " \n" tomwalters@402: " -A Print command line arguments off\n" tomwalters@402: " -C cf Set config file to cf none\n" tomwalters@402: " -S f Set script file to f none\n" tomwalters@402: " -V Print version information off\n" tomwalters@402: " -D d Write complete parameter set to file d none\n" tomwalters@402: " -G g Write graph to file g none\n"); tomwalters@296: tomwalters@296: if (argc < 2) { tomwalters@402: std::cout << version_string.c_str(); tomwalters@402: std::cout << usage_string.c_str(); tomwalters@296: return -1; tomwalters@296: } tomwalters@296: tomwalters@296: // Parse command-line arguments tomwalters@296: for (int i = 1; i < argc; i++) { tomwalters@296: if (strcmp(argv[i],"-A") == 0) { tomwalters@296: for (int j = 0; j < argc; j++) tomwalters@296: printf("%s ",argv[j]); tomwalters@296: printf("\n"); tomwalters@296: fflush(stdout); tomwalters@296: continue; tomwalters@296: } tomwalters@296: if (strcmp(argv[i],"-C") == 0) { tomwalters@296: if (++i >= argc) { tomwalters@296: aimc::LOG_ERROR(_T("Configuration file name expected after -C")); tomwalters@296: return(-1); tomwalters@296: } tomwalters@296: config_file = argv[i]; tomwalters@296: continue; tomwalters@296: } tomwalters@296: if (strcmp(argv[i],"-S") == 0) { tomwalters@296: if (++i >= argc) { tomwalters@296: aimc::LOG_ERROR(_T("Script file name expected after -S")); tomwalters@296: return(-1); tomwalters@296: } tomwalters@296: script_file = argv[i]; tomwalters@296: continue; tomwalters@296: } tomwalters@296: if (strcmp(argv[i],"-D") == 0) { tomwalters@296: if (++i >= argc) { tomwalters@296: aimc::LOG_ERROR(_T("Data file name expected after -D")); tomwalters@296: return(-1); tomwalters@296: } tomwalters@296: data_file = argv[i]; tomwalters@296: continue; tomwalters@296: } tomwalters@402: if (strcmp(argv[i],"-G") == 0) { tomwalters@402: if (++i >= argc) { tomwalters@402: aimc::LOG_ERROR(_T("Graph file name expected after -D")); tomwalters@402: return(-1); tomwalters@402: } tomwalters@402: dot_file = argv[i]; tomwalters@402: continue; tomwalters@402: } tomwalters@402: if (strcmp(argv[i],"-V") == 0) { tomwalters@402: std::cout << version_string; tomwalters@296: continue; tomwalters@296: } tomwalters@296: aimc::LOG_ERROR(_T("Unrecognized command-line argument: %s"), argv[i]); tomwalters@296: } tomwalters@296: tomwalters@402: std::cout << "Configuration file: " << config_file << std::endl; tomwalters@402: std::cout << "Script file: " << script_file << std::endl; tomwalters@402: std::cout << "Data file: " << data_file << std::endl; tomwalters@402: std::cout << "Graph file: " << dot_file << std::endl; tomwalters@402: tomwalters@402: aimc::AIMCopy processor; tomwalters@402: aimc::LOG_INFO("main: Initializing..."); tomwalters@402: if (!processor.Initialize(script_file, config_file)) { tomwalters@296: return -1; tomwalters@296: } tomwalters@402: tomwalters@402: aimc::LOG_INFO("main: Writing confg..."); tomwalters@402: if (!processor.WriteConfig(data_file, dot_file)) { tomwalters@296: return -1; tomwalters@296: } tomwalters@402: tomwalters@402: aimc::LOG_INFO("main: Processing..."); tomwalters@402: if (!processor.Process()) { tomwalters@402: return -1; tomwalters@296: } tomwalters@296: tomwalters@296: return 0; tomwalters@296: }