comparison src/Modules/SSI/ModuleSSI.cc @ 15:b4cafba48e9d

-<math.h> replaced wit <cmath> where possible -SSI support added but not yet tested
author tomwalters
date Fri, 19 Feb 2010 15:19:27 +0000
parents 88fe02836a6b
children f4e712d41321
comparison
equal deleted inserted replaced
14:ba2f7596d1a2 15:b4cafba48e9d
20 * \author Thomas Walters <tom@acousticscale.org> 20 * \author Thomas Walters <tom@acousticscale.org>
21 * \date created 2010/02/19 21 * \date created 2010/02/19
22 * \version \$Id$ 22 * \version \$Id$
23 */ 23 */
24 24
25 #include <cmath>
26
25 #include "Modules/SSI/ModuleSSI.h" 27 #include "Modules/SSI/ModuleSSI.h"
26 28
27 namespace aimc { 29 namespace aimc {
28 ModuleSSI::ModuleSSI(Parameters *params) : Module(params) { 30 ModuleSSI::ModuleSSI(Parameters *params) : Module(params) {
29 module_description_ = "Size-shape image (aka the 'sscAI')"; 31 module_description_ = "Size-shape image (aka the 'sscAI')";
30 module_identifier_ = "ssi"; 32 module_identifier_ = "ssi";
31 module_type_ = "ssi"; 33 module_type_ = "ssi";
32 module_version_ = "$Id$"; 34 module_version_ = "$Id$";
33 35
34 do_pitch_cutoff_ = parameters_->DefaultBool("ssi.pitch_cutoff", false); 36 //do_pitch_cutoff_ = parameters_->DefaultBool("ssi.pitch_cutoff", false);
37 ssi_width_cycles_ = parameters_->DefaultFloat("ssi.width_cycles", 20.0f);
35 } 38 }
36 39
37 ModuleSSI::~ModuleSSI() { 40 ModuleSSI::~ModuleSSI() {
38 } 41 }
39 42
42 // that they can be checked later. 45 // that they can be checked later.
43 sample_rate_ = input.sample_rate(); 46 sample_rate_ = input.sample_rate();
44 buffer_length_ = input.buffer_length(); 47 buffer_length_ = input.buffer_length();
45 channel_count_ = input.channel_count(); 48 channel_count_ = input.channel_count();
46 49
47 // If this module produces any output, then the output signal bank needs to 50 float lowest_cf = input.centre_frequency(0);
48 // be initialized here. 51 ssi_width_samples_ = sample_rate_ * ssi_width_cycles_ / lowest_cf;
49 // Example: 52 if (ssi_width_samples_ > buffer_length_) {
50 // output_.Initialize(channel_count, buffer_length, sample_rate); 53 ssi_width_samples_ = buffer_length_;
54 float cycles = ssi_width_samples_ * lowest_cf / sample_rate_;
55 LOG_INFO(_T("Requested SSI width of %f cycles is too long for the "
56 "input buffer length of %d samples. The SSI will be "
57 "truncated at %d samples wide. This corresponds to a width "
58 "of %f cycles."), ssi_width_cycles_, buffer_length_,
59 ssi_width_samples_, cycles);
60 ssi_width_cycles_ = cycles;
61 }
62 output_.Initialize(channel_count_, ssi_width_samples_, sample_rate_);
51 return true; 63 return true;
52 } 64 }
53 65
54 void ModuleSSI::ResetInternal() { 66 void ModuleSSI::ResetInternal() {
55 // Reset any internal state variables to their default values here. After a
56 // call to ResetInternal(), the module should be in the same state as it is
57 // just after a call to InitializeInternal().
58 } 67 }
59 68
60 void ModuleSSI::Process(const SignalBank &input) { 69 void ModuleSSI::Process(const SignalBank &input) {
61 // Check to see if the module has been initialized. If not, processing 70 // Check to see if the module has been initialized. If not, processing
62 // should not continue. 71 // should not continue.
72 LOG_ERROR(_T("Mismatch between input to Initialize() and input to " 81 LOG_ERROR(_T("Mismatch between input to Initialize() and input to "
73 "Process() in module %s."), module_identifier_.c_str()); 82 "Process() in module %s."), module_identifier_.c_str());
74 return; 83 return;
75 } 84 }
76 85
77 // Input is read from the input signal bank using calls like 86 output_.set_start_time(input.start_time());
78 // float value = input_.sample(channel_number, sample_index);
79 87
80 // Output is fed into the output signal bank (assuming that it was 88 for (int ch = 0; ch < channel_count_; ++ch) {
81 // initialized during the call to InitializeInternal()) like this: 89 // Copy the buffer from input to output, addressing by h-value
82 // output_.set_sample(channel_number, sample_index, sample_value); 90 for (int i = 0; i < ssi_width_samples_; ++i) {
91 float h = static_cast<float>(i) * ssi_width_cycles_
92 / static_cast<float>(ssi_width_samples_);
93 float cycle_samples = sample_rate_ / input.centre_frequency(ch);
83 94
95 // The index into the input array is a floating-point number, which is
96 // split into a whole part and a fractional part. The whole part and
97 // fractional part are found, and are used to linearly interpolate
98 // between input samples to yield an output sample.
99 double whole_part;
100 float frac_part = modf(h * cycle_samples, &whole_part);
101 int sample = static_cast<int>(whole_part);
102
103 float val;
104 if (sample < buffer_length_ - 1) {
105 float curr_sample = input.sample(ch, sample);
106 float next_sample = input.sample(ch, sample + 1);
107 val = curr_sample + frac_part * (next_sample - curr_sample);
108 } else {
109 val = 0.0f;
110 }
111 output_.set_sample(ch, i, val);
112 }
113 }
84 PushOutput(); 114 PushOutput();
85 } 115 }
86 } // namespace aimc 116 } // namespace aimc
87 117