tomwalters@284
|
1 // Copyright 2010, Thomas Walters
|
tomwalters@284
|
2 //
|
tomwalters@284
|
3 // AIM-C: A C++ implementation of the Auditory Image Model
|
tomwalters@284
|
4 // http://www.acousticscale.org/AIMC
|
tomwalters@284
|
5 //
|
tomwalters@318
|
6 // Licensed under the Apache License, Version 2.0 (the "License");
|
tomwalters@318
|
7 // you may not use this file except in compliance with the License.
|
tomwalters@318
|
8 // You may obtain a copy of the License at
|
tomwalters@284
|
9 //
|
tomwalters@318
|
10 // http://www.apache.org/licenses/LICENSE-2.0
|
tomwalters@284
|
11 //
|
tomwalters@318
|
12 // Unless required by applicable law or agreed to in writing, software
|
tomwalters@318
|
13 // distributed under the License is distributed on an "AS IS" BASIS,
|
tomwalters@318
|
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
tomwalters@318
|
15 // See the License for the specific language governing permissions and
|
tomwalters@318
|
16 // limitations under the License.
|
tomwalters@284
|
17
|
tomwalters@284
|
18 /*!
|
tomwalters@284
|
19 * \author Thomas Walters <tom@acousticscale.org>
|
tomwalters@284
|
20 * \date created 2010/02/19
|
tomwalters@284
|
21 * \version \$Id$
|
tomwalters@284
|
22 */
|
tomwalters@284
|
23
|
tomwalters@284
|
24 #include "Modules/Profile/ModuleSlice.h"
|
tomwalters@284
|
25
|
tomwalters@284
|
26 namespace aimc {
|
tomwalters@284
|
27 ModuleSlice::ModuleSlice(Parameters *params) : Module(params) {
|
tomwalters@284
|
28 module_description_ = "Temporal or spectral slice of a 2D image";
|
tomwalters@284
|
29 module_identifier_ = "slice";
|
tomwalters@284
|
30 module_type_ = "profile";
|
tomwalters@284
|
31 module_version_ = "$Id$";
|
tomwalters@284
|
32
|
tomwalters@284
|
33 // This module will compute the spectral profile unless told otherwise here
|
tomwalters@284
|
34 temporal_profile_ = parameters_->DefaultBool("slice.temporal", false);
|
tomwalters@284
|
35 // Set slice.all to true to take the profile of the entire image
|
tomwalters@284
|
36 take_all_ = parameters_->DefaultBool("slice.all", true);
|
tomwalters@284
|
37 // If not taking all, then these give the lower and upper indices of the
|
tomwalters@284
|
38 // section to take. They are bounds-checked.
|
tomwalters@284
|
39 lower_limit_ = parameters_->DefaultInt("slice.lower_index", 0);
|
tomwalters@284
|
40 upper_limit_ = parameters_->DefaultInt("slice.upper_index", 1000);
|
tomwalters@284
|
41 // Set to true to normalize the slice taken (ie take the mean value)
|
tomwalters@284
|
42 normalize_slice_ = parameters_->DefaultBool("slice.normalize", false);
|
tomwalters@284
|
43 }
|
tomwalters@284
|
44
|
tomwalters@284
|
45 ModuleSlice::~ModuleSlice() {
|
tomwalters@284
|
46 }
|
tomwalters@284
|
47
|
tomwalters@284
|
48 bool ModuleSlice::InitializeInternal(const SignalBank &input) {
|
tomwalters@284
|
49 // Copy the parameters of the input signal bank into internal variables, so
|
tomwalters@284
|
50 // that they can be checked later.
|
tomwalters@284
|
51 sample_rate_ = input.sample_rate();
|
tomwalters@284
|
52 buffer_length_ = input.buffer_length();
|
tomwalters@284
|
53 channel_count_ = input.channel_count();
|
tomwalters@284
|
54
|
tomwalters@305
|
55 if (lower_limit_ < 0 || take_all_) {
|
tomwalters@284
|
56 lower_limit_ = 0;
|
tomwalters@284
|
57 }
|
tomwalters@284
|
58
|
tomwalters@284
|
59 if (upper_limit_ < 0) {
|
tomwalters@284
|
60 upper_limit_ = 0;
|
tomwalters@284
|
61 }
|
tomwalters@284
|
62
|
tomwalters@284
|
63 if (temporal_profile_) {
|
tomwalters@305
|
64 if (upper_limit_ > channel_count_ || take_all_) {
|
tomwalters@284
|
65 upper_limit_ = channel_count_;
|
tomwalters@284
|
66 }
|
tomwalters@284
|
67 if (lower_limit_ > channel_count_) {
|
tomwalters@284
|
68 lower_limit_ = channel_count_;
|
tomwalters@284
|
69 }
|
tomwalters@284
|
70 } else {
|
tomwalters@305
|
71 if (upper_limit_ > buffer_length_ || take_all_) {
|
tomwalters@284
|
72 upper_limit_ = buffer_length_;
|
tomwalters@284
|
73 }
|
tomwalters@284
|
74 if (lower_limit_ > buffer_length_) {
|
tomwalters@284
|
75 lower_limit_ = buffer_length_;
|
tomwalters@284
|
76 }
|
tomwalters@284
|
77 }
|
tomwalters@284
|
78
|
tomwalters@284
|
79 slice_length_ = upper_limit_ - lower_limit_;
|
tomwalters@284
|
80 if (slice_length_ < 1) {
|
tomwalters@284
|
81 slice_length_ = 1;
|
tomwalters@284
|
82 }
|
tomwalters@284
|
83
|
tomwalters@284
|
84 if (temporal_profile_) {
|
tomwalters@284
|
85 output_.Initialize(1, buffer_length_, sample_rate_);
|
tomwalters@284
|
86 } else {
|
tomwalters@284
|
87 output_.Initialize(channel_count_, 1, sample_rate_);
|
tomwalters@284
|
88 }
|
tomwalters@284
|
89 return true;
|
tomwalters@284
|
90 }
|
tomwalters@284
|
91
|
tomwalters@284
|
92 void ModuleSlice::ResetInternal() {
|
tomwalters@284
|
93 }
|
tomwalters@284
|
94
|
tomwalters@284
|
95 void ModuleSlice::Process(const SignalBank &input) {
|
tomwalters@284
|
96 // Check to see if the module has been initialized. If not, processing
|
tomwalters@284
|
97 // should not continue.
|
tomwalters@284
|
98 if (!initialized_) {
|
tomwalters@284
|
99 LOG_ERROR(_T("Module %s not initialized."), module_identifier_.c_str());
|
tomwalters@284
|
100 return;
|
tomwalters@284
|
101 }
|
tomwalters@284
|
102
|
tomwalters@284
|
103 // Check that ths input this time is the same as the input passed to
|
tomwalters@284
|
104 // Initialize()
|
tomwalters@284
|
105 if (buffer_length_ != input.buffer_length()
|
tomwalters@284
|
106 || channel_count_ != input.channel_count()) {
|
tomwalters@284
|
107 LOG_ERROR(_T("Mismatch between input to Initialize() and input to "
|
tomwalters@284
|
108 "Process() in module %s."), module_identifier_.c_str());
|
tomwalters@284
|
109 return;
|
tomwalters@284
|
110 }
|
tomwalters@284
|
111
|
tomwalters@287
|
112 output_.set_start_time(input.start_time());
|
tomwalters@287
|
113
|
tomwalters@284
|
114 if (temporal_profile_) {
|
tomwalters@284
|
115 for (int i = 0; i < input.buffer_length(); ++i) {
|
tomwalters@284
|
116 float val = 0.0f;
|
tomwalters@284
|
117 for (int ch = lower_limit_; ch < upper_limit_; ++ch) {
|
tomwalters@284
|
118 val += input.sample(ch, i);
|
tomwalters@284
|
119 }
|
tomwalters@284
|
120 if (normalize_slice_) {
|
tomwalters@284
|
121 val /= static_cast<float>(slice_length_);
|
tomwalters@284
|
122 }
|
tomwalters@284
|
123 output_.set_sample(0, i, val);
|
tomwalters@284
|
124 }
|
tomwalters@284
|
125 } else {
|
tomwalters@284
|
126 for (int ch = 0; ch < input.channel_count(); ++ch) {
|
tomwalters@292
|
127 output_.set_centre_frequency(ch, input.centre_frequency(ch));
|
tomwalters@284
|
128 float val = 0.0f;
|
tomwalters@284
|
129 for (int i = lower_limit_; i < upper_limit_; ++i) {
|
tomwalters@284
|
130 val += input.sample(ch, i);
|
tomwalters@284
|
131 }
|
tomwalters@284
|
132 if (normalize_slice_) {
|
tomwalters@284
|
133 val /= static_cast<float>(slice_length_);
|
tomwalters@284
|
134 }
|
tomwalters@284
|
135 output_.set_sample(ch, 0, val);
|
tomwalters@284
|
136 }
|
tomwalters@284
|
137 }
|
tomwalters@284
|
138 PushOutput();
|
tomwalters@284
|
139 }
|
tomwalters@284
|
140 } // namespace aimc
|
tomwalters@284
|
141
|