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