Mercurial > hg > aimc
changeset 275:ce2bab04f155
- Imported file input using libsndfile from old AIM-C and updated to the new API
- Modified the Module base class to propogate Reset() calls down the module chain.
- This required changing all Reset() functions in subclasses to ResetInternal()
- Removed some unneeded imports from the Gaussians test
author | tomwalters |
---|---|
date | Tue, 16 Feb 2010 18:00:16 +0000 |
parents | 3640d25b65ab |
children | a57b29e373c7 |
files | trunk/SConstruct trunk/src/Modules/BMM/ModulePZFC.cc trunk/src/Modules/BMM/ModulePZFC.h trunk/src/Modules/Features/ModuleGaussians.cc trunk/src/Modules/Features/ModuleGaussians.h trunk/src/Modules/Features/ModuleGaussians_test.py trunk/src/Modules/Input/ModuleFileInput.cc trunk/src/Modules/Input/ModuleFileInput.h trunk/src/Modules/NAP/ModuleHCL.cc trunk/src/Modules/NAP/ModuleHCL.h trunk/src/Modules/SAI/ModuleSAI.cc trunk/src/Modules/SAI/ModuleSAI.h trunk/src/Support/Module.cc trunk/src/Support/Module.h |
diffstat | 14 files changed, 271 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/trunk/SConstruct Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/SConstruct Tue Feb 16 18:00:16 2010 +0000 @@ -95,7 +95,8 @@ common_sources = ['Support/Common.cc', 'Support/SignalBank.cc', 'Support/Parameters.cc', - 'Support/Module.cc', + 'Support/Module.cc', + 'Modules/Input/ModuleFileInput.cc', 'Modules/BMM/ModulePZFC.cc', 'Modules/NAP/ModuleHCL.cc', #'Modules/SAI/ModuleSAI.cc', @@ -116,7 +117,11 @@ env.Append(CPPPATH = '#src') # Dependencies -deplibs = '' +deplibs = ['sndfile'] + +for depname in deplibs: + env.ParseConfig('pkg-config --cflags --libs ' + depname) + env.AppendUnique(LIBS = deplibs) # Set up the builder to build the program
--- a/trunk/src/Modules/BMM/ModulePZFC.cc Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Modules/BMM/ModulePZFC.cc Tue Feb 16 18:00:16 2010 +0000 @@ -73,12 +73,12 @@ return false; // This initialises all buffers which can be modified by Process() - Reset(); + ResetInternal(); return true; } -void ModulePZFC::Reset() { +void ModulePZFC::ResetInternal() { // These buffers may be actively modified by the algorithm agc_state_.clear(); agc_state_.resize(channel_count_);
--- a/trunk/src/Modules/BMM/ModulePZFC.h Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Modules/BMM/ModulePZFC.h Tue Feb 16 18:00:16 2010 +0000 @@ -43,10 +43,10 @@ //! \brief Process a buffer virtual void Process(const SignalBank &input); - //! \brief Reset all internal state variables to their initial values - virtual void Reset(); + private: + //! \brief Reset all internal state variables to their initial values + virtual void ResetInternal(); - private: //! \brief Prepare the module //! \param input Input SignalBank //! \param output true on success false on failure
--- a/trunk/src/Modules/Features/ModuleGaussians.cc Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Modules/Features/ModuleGaussians.cc Tue Feb 16 18:00:16 2010 +0000 @@ -77,7 +77,7 @@ return true; } -void ModuleGaussians::Reset() { +void ModuleGaussians::ResetInternal() { m_pSpectralProfile.clear(); m_pSpectralProfile.resize(m_iNumChannels, 0.0f); }
--- a/trunk/src/Modules/Features/ModuleGaussians.h Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Modules/Features/ModuleGaussians.h Tue Feb 16 18:00:16 2010 +0000 @@ -48,14 +48,14 @@ //! \brief Process a buffer virtual void Process(const SignalBank &input); + private: //! \brief Reset the internal state of the module - void Reset(); + virtual void ResetInternal(); - private: - /*! \brief Prepare the module - * \param input Input signal - * \param output true on success false on failure - */ + /*! \brief Prepare the module + * \param input Input signal + * \param output true on success false on failure + */ virtual bool InitializeInternal(const SignalBank &input); bool RubberGMMCore(int iNumComponents, bool bDoInit);
--- a/trunk/src/Modules/Features/ModuleGaussians_test.py Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Modules/Features/ModuleGaussians_test.py Tue Feb 16 18:00:16 2010 +0000 @@ -22,13 +22,11 @@ Created by Thomas Walters on 2010-02-15. Copyright 2010 Thomas Walters <tom@acousticscale.org> Test for the Gaussians module. Runs a number of pre-computed SAI profiles -through the module, and tests them against the equivalent output from the +through the module, and tests them against the saved output from the MATLAB rubber_GMM code. """ import aimc -import matplotlib -import pylab from scipy import io def main():
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/src/Modules/Input/ModuleFileInput.cc Tue Feb 16 18:00:16 2010 +0000 @@ -0,0 +1,139 @@ +// Copyright 2006-2010, Willem van Engen, Thomas Walters +// +// AIM-C: A C++ implementation of the Auditory Image Model +// http://www.acousticscale.org/AIMC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +/*! \file + * \brief Audio file input + * + * \author Willem van Engen <cnbh@willem.engen.nl> + * \author Thomas Walters <tom@acousticscale.org> + * \date created 2006/09/21 + * \version \$Id$ + */ + +#include <vector> + +#include "Modules/Input/ModuleFileInput.h" + +namespace aimc { +ModuleFileInput::ModuleFileInput(Parameters *params) : Module(params) { + file_handle_ = NULL; + buffer_length_ = parameters_->DefaultInt("input.buffersize", 1024); + + file_position_samples_ = 0; + file_loaded_ = false; + audio_channels_ = 0; + buffer_length_ = 0; + sample_rate_ = 0.0f; +} + +ModuleFileInput::~ModuleFileInput() { + if (file_handle_) + sf_close(file_handle_); +} + +void ModuleFileInput::ResetInternal() { + output_.Initialize(audio_channels_, buffer_length_, sample_rate_); + output_.set_start_time(0); +} + +bool ModuleFileInput::LoadFile(const char* filename) { + // Open the file + SF_INFO sfinfo; + memset((void*)&sfinfo, 0, sizeof(SF_INFO)); + file_handle_ = sf_open(filename, SFM_READ, &sfinfo); + + if (file_handle_ == NULL) { + //! \todo Also display error reason + LOG_ERROR(_T("Couldn't read audio file '%s'"), filename); + return false; + } + + file_loaded_ = true; + audio_channels_ = sfinfo.channels; + sample_rate_ = sfinfo.samplerate; + file_position_samples_ = 0; + + // A dummy signal bank to be passed to the Initialize() function. + SignalBank s; + s.Initialize(1, 1, 1); + + // Self-initialize by calling Module::Initialize() explicitly. + // The Initialize() call in this subclass is overloaded to prevent it from + // being called drectly. + return Module::Initialize(s); +} + +bool ModuleFileInput::Initialize(const SignalBank& input) { + LOG_ERROR(_T("Do not call Initialize() on ModuleFileInput directly " + "instead call LoadFile() with a filename to load. " + "This will automatically initialize the module.")); + return false; +} + +void ModuleFileInput::Process(const SignalBank& input) { + LOG_ERROR(_T("Call Process() on ModuleFileInput instead of passing in " + "a SignalBank")); +} + +bool ModuleFileInput::InitializeInternal(const SignalBank& input) { + if (!file_loaded_) + return false; + ResetInternal(); + return true; +} + +void ModuleFileInput::Process() { + sf_count_t read; + vector<float> buffer; + buffer.resize(buffer_length_ * audio_channels_); + + while (true) { + // Read buffersize bytes into buffer + read = sf_readf_float(file_handle_, &buffer[0], buffer_length_); + + // Place the contents of the buffer into the signal bank + int counter = 0; + for (int c = 0; c < audio_channels_; ++c) { + for (int i = 0; i < read; ++i) { + output_.set_sample(c, i, buffer[counter]); + ++counter; + } + } + + // If the number of saples read is less than the buffer length, the end + // of the file has been reached. + if (read < buffer_length_) { + // Zero samples at end + for (int c = 0; c < audio_channels_; ++c) { + for (int i = read; i < buffer_length_; ++i) { + output_.set_sample(c, i, 0.0f); + } + } + // When we're past the end of the buffer, stop looping. + if (read == 0) + break; + } + + // Update time + output_.set_start_time(file_position_samples_); + file_position_samples_ += read; + + PushOutput(); + } +} +} // namespace aimc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/src/Modules/Input/ModuleFileInput.h Tue Feb 16 18:00:16 2010 +0000 @@ -0,0 +1,80 @@ +// Copyright 2006-2010, Willem van Engen, Thomas Walters +// +// AIM-C: A C++ implementation of the Auditory Image Model +// http://www.acousticscale.org/AIMC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +/*! \file + * \brief Audio file input + * + * \author Willem van Engen <cnbh@willem.engen.nl> + * \author Thomas Walters <tom@acousticscale.org> + * \date created 2006/09/21 + * \version \$Id$ + */ + +#ifndef _AIMC_MODULES_INPUT_FILE_H_ +#define _AIMC_MODULES_INPUT_FILE_H_ + +#include <sndfile.h> + +#include "Support/Module.h" +#include "Support/Parameters.h" +#include "Support/SignalBank.h" + +namespace aimc { +class ModuleFileInput : public Module { + public: + ModuleFileInput(Parameters *pParam); + virtual ~ModuleFileInput(); + + /*! \brief Initializes this input device using an audio file + * \param sFilename Path of the file to load + * \return true on success, false on error + */ + bool LoadFile(const char *sFilename); + + //! \brief Process the loaded file. + void Process(); + + //! \brief Dummy Initialize function. Call LoadFile instead. + virtual bool Initialize(const SignalBank &input); + + //! \brief Dummy funciton to comply with the Module specification. Gives an + // error message when called. + virtual void Process(const SignalBank &input); + + private: + //! \brief Prepare the module + //! \param input Input SignalBank + //! \param output true on success false on failure + virtual bool InitializeInternal(const SignalBank &input); + + //! \brief Rewind to the start of the file + virtual void ResetInternal(); + + //! \brief File descriptor + SNDFILE *file_handle_; + + //! \brief Current position in time of the file + int file_position_samples_; + bool file_loaded_; + int audio_channels_; + int buffer_length_; + float sample_rate_; +}; +} // namespace aimc + +#endif // _AIMC_MODULES_INPUT_FILE_H_
--- a/trunk/src/Modules/NAP/ModuleHCL.cc Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Modules/NAP/ModuleHCL.cc Tue Feb 16 18:00:16 2010 +0000 @@ -50,11 +50,11 @@ time_constant_ = 1.0f / (2.0f * M_PI * lowpass_cutoff_); channel_count_ = input.channel_count(); output_.Initialize(input); - Reset(); + ResetInternal(); return true; } -void ModuleHCL::Reset() { +void ModuleHCL::ResetInternal() { xn_ = 0.0f; yn_ = 0.0f; yns_.clear();
--- a/trunk/src/Modules/NAP/ModuleHCL.h Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Modules/NAP/ModuleHCL.h Tue Feb 16 18:00:16 2010 +0000 @@ -42,7 +42,6 @@ virtual ~ModuleHCL(); virtual void Process(const SignalBank &input); - virtual void Reset(); private: /*! \brief Prepare the module @@ -51,6 +50,8 @@ */ virtual bool InitializeInternal(const SignalBank &input); + virtual void ResetInternal(); + //! \brief Do lowpass filtering? bool do_lowpass_;
--- a/trunk/src/Modules/SAI/ModuleSAI.cc Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Modules/SAI/ModuleSAI.cc Tue Feb 16 18:00:16 2010 +0000 @@ -111,7 +111,7 @@ return true; } -void ModuleSAI::Reset() { +void ModuleSAI::ResetInternal() { } void ModuleSAI::Process(const SignalBank &input) {
--- a/trunk/src/Modules/SAI/ModuleSAI.h Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Modules/SAI/ModuleSAI.h Tue Feb 16 18:00:16 2010 +0000 @@ -40,7 +40,6 @@ ModuleSAI(Parameters *parameters); virtual ~ModuleSAI(); void Process(const SignalBank &input); - void Reset(); private: /*! \brief Prepare the module @@ -49,6 +48,8 @@ */ bool InitializeInternal(const SignalBank &input); + virtual void ResetInternal(); + //! \brief Temporary buffer for constructing the current SAI frame SignalBank sai_temp_;
--- a/trunk/src/Support/Module.cc Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Support/Module.cc Tue Feb 16 18:00:16 2010 +0000 @@ -78,6 +78,19 @@ return true; } +void Module::Reset() { + if (!initialized_) + return; + + ResetInternal(); + + // Iterate through all the targets of this module, resetting + // them. + set<Module*>::const_iterator it; + for (it = targets_.begin(); it != targets_.end(); ++it) + (*it)->Reset(); +} + bool Module::initialized() const { return initialized_; }
--- a/trunk/src/Support/Module.h Tue Feb 16 13:23:23 2010 +0000 +++ b/trunk/src/Support/Module.h Tue Feb 16 18:00:16 2010 +0000 @@ -72,8 +72,14 @@ * any targets of the module if necessary. * \param input Input SignalBank. * \param output true on success, false on failure. + * + * Note that in most instances when creating a new module, it is better to + * simply implement the pure virtual function InitializeInternal(), rather + * than refining a new Initialize. The only reason that Initialize() is made + * virtual is to deal with the edge case of input modules which do not take + * a SignalBank as input, but rather generate their own input. */ - bool Initialize(const SignalBank &input); + virtual bool Initialize(const SignalBank &input); /*! \brief */ @@ -98,10 +104,10 @@ */ virtual void Process(const SignalBank &input) = 0; - /*! \brief Reset the internal state of the module to that when it was - * initialised + /*! \brief Reset the internal state of this module and all its children to + * their initial state. */ - virtual void Reset() = 0; + void Reset() ; /*! \brief */ @@ -110,6 +116,8 @@ protected: void PushOutput(); + virtual void ResetInternal() = 0; + virtual bool InitializeInternal(const SignalBank &input) = 0; bool initialized_;