tomwalters@12: // Copyright 2010, Thomas Walters tomwalters@12: // tomwalters@12: // AIM-C: A C++ implementation of the Auditory Image Model tomwalters@12: // http://www.acousticscale.org/AIMC tomwalters@12: // tomwalters@45: // Licensed under the Apache License, Version 2.0 (the "License"); tomwalters@45: // you may not use this file except in compliance with the License. tomwalters@45: // You may obtain a copy of the License at tomwalters@12: // tomwalters@45: // http://www.apache.org/licenses/LICENSE-2.0 tomwalters@12: // tomwalters@45: // Unless required by applicable law or agreed to in writing, software tomwalters@45: // distributed under the License is distributed on an "AS IS" BASIS, tomwalters@45: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. tomwalters@45: // See the License for the specific language governing permissions and tomwalters@45: // limitations under the License. tomwalters@12: tomwalters@12: /*! tomwalters@12: * \author Thomas Walters tomwalters@12: * \date created 2010/02/19 tomwalters@12: * \version \$Id$ tomwalters@12: */ tomwalters@12: tomwalters@12: #include "Modules/Profile/ModuleSlice.h" tomwalters@12: tomwalters@12: namespace aimc { tomwalters@12: ModuleSlice::ModuleSlice(Parameters *params) : Module(params) { tomwalters@12: module_description_ = "Temporal or spectral slice of a 2D image"; tomwalters@12: module_identifier_ = "slice"; tomwalters@12: module_type_ = "profile"; tomwalters@12: module_version_ = "$Id$"; tomwalters@12: tomwalters@12: // This module will compute the spectral profile unless told otherwise here tomwalters@12: temporal_profile_ = parameters_->DefaultBool("slice.temporal", false); tomwalters@12: // Set slice.all to true to take the profile of the entire image tomwalters@12: take_all_ = parameters_->DefaultBool("slice.all", true); tomwalters@12: // If not taking all, then these give the lower and upper indices of the tomwalters@12: // section to take. They are bounds-checked. tomwalters@12: lower_limit_ = parameters_->DefaultInt("slice.lower_index", 0); tomwalters@12: upper_limit_ = parameters_->DefaultInt("slice.upper_index", 1000); tomwalters@12: // Set to true to normalize the slice taken (ie take the mean value) tomwalters@12: normalize_slice_ = parameters_->DefaultBool("slice.normalize", false); tomwalters@12: } tomwalters@12: tomwalters@12: ModuleSlice::~ModuleSlice() { tomwalters@12: } tomwalters@12: tomwalters@12: bool ModuleSlice::InitializeInternal(const SignalBank &input) { tomwalters@12: // Copy the parameters of the input signal bank into internal variables, so tomwalters@12: // that they can be checked later. tomwalters@12: sample_rate_ = input.sample_rate(); tomwalters@12: buffer_length_ = input.buffer_length(); tomwalters@12: channel_count_ = input.channel_count(); tomwalters@12: tomwalters@32: if (lower_limit_ < 0 || take_all_) { tomwalters@12: lower_limit_ = 0; tomwalters@12: } tomwalters@12: tomwalters@12: if (upper_limit_ < 0) { tomwalters@12: upper_limit_ = 0; tomwalters@12: } tomwalters@12: tomwalters@12: if (temporal_profile_) { tomwalters@32: if (upper_limit_ > channel_count_ || take_all_) { tomwalters@12: upper_limit_ = channel_count_; tomwalters@12: } tomwalters@12: if (lower_limit_ > channel_count_) { tomwalters@12: lower_limit_ = channel_count_; tomwalters@12: } tomwalters@12: } else { tomwalters@32: if (upper_limit_ > buffer_length_ || take_all_) { tomwalters@12: upper_limit_ = buffer_length_; tomwalters@12: } tomwalters@12: if (lower_limit_ > buffer_length_) { tomwalters@12: lower_limit_ = buffer_length_; tomwalters@12: } tomwalters@12: } tomwalters@12: tomwalters@12: slice_length_ = upper_limit_ - lower_limit_; tomwalters@12: if (slice_length_ < 1) { tomwalters@12: slice_length_ = 1; tomwalters@12: } tomwalters@12: tomwalters@12: if (temporal_profile_) { tomwalters@12: output_.Initialize(1, buffer_length_, sample_rate_); tomwalters@12: } else { tomwalters@12: output_.Initialize(channel_count_, 1, sample_rate_); tomwalters@12: } tomwalters@12: return true; tomwalters@12: } tomwalters@12: tomwalters@12: void ModuleSlice::ResetInternal() { tomwalters@12: } tomwalters@12: tomwalters@12: void ModuleSlice::Process(const SignalBank &input) { tomwalters@12: // Check to see if the module has been initialized. If not, processing tomwalters@12: // should not continue. tomwalters@12: if (!initialized_) { tomwalters@12: LOG_ERROR(_T("Module %s not initialized."), module_identifier_.c_str()); tomwalters@12: return; tomwalters@12: } tomwalters@12: tomwalters@12: // Check that ths input this time is the same as the input passed to tomwalters@12: // Initialize() tomwalters@12: if (buffer_length_ != input.buffer_length() tomwalters@12: || channel_count_ != input.channel_count()) { tomwalters@12: LOG_ERROR(_T("Mismatch between input to Initialize() and input to " tomwalters@12: "Process() in module %s."), module_identifier_.c_str()); tomwalters@12: return; tomwalters@12: } tomwalters@12: tomwalters@15: output_.set_start_time(input.start_time()); tomwalters@15: tomwalters@12: if (temporal_profile_) { tomwalters@12: for (int i = 0; i < input.buffer_length(); ++i) { tomwalters@12: float val = 0.0f; tomwalters@12: for (int ch = lower_limit_; ch < upper_limit_; ++ch) { tomwalters@12: val += input.sample(ch, i); tomwalters@12: } tomwalters@12: if (normalize_slice_) { tomwalters@12: val /= static_cast(slice_length_); tomwalters@12: } tomwalters@12: output_.set_sample(0, i, val); tomwalters@12: } tomwalters@12: } else { tomwalters@12: for (int ch = 0; ch < input.channel_count(); ++ch) { tomwalters@20: output_.set_centre_frequency(ch, input.centre_frequency(ch)); tomwalters@12: float val = 0.0f; tomwalters@12: for (int i = lower_limit_; i < upper_limit_; ++i) { tomwalters@12: val += input.sample(ch, i); tomwalters@12: } tomwalters@12: if (normalize_slice_) { tomwalters@12: val /= static_cast(slice_length_); tomwalters@12: } tomwalters@12: output_.set_sample(ch, 0, val); tomwalters@12: } tomwalters@12: } tomwalters@12: PushOutput(); tomwalters@12: } tomwalters@12: } // namespace aimc tomwalters@12: