Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2011 George Tzanetakis <gtzan@cs.uvic.ca> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #include "SpectralTransformations.h" 00020 #include "../common_source.h" 00021 00022 using std::ostringstream; 00023 using namespace Marsyas; 00024 00025 SpectralTransformations::SpectralTransformations(mrs_string name):MarSystem("SpectralTransformations", name) 00026 { 00027 addControls(); 00028 } 00029 00030 SpectralTransformations::SpectralTransformations(const SpectralTransformations& a) : MarSystem(a) 00031 { 00032 ctrl_gain_ = getctrl("mrs_real/gain"); 00033 ctrl_mode_ = getctrl("mrs_string/mode"); 00034 } 00035 00036 00037 SpectralTransformations::~SpectralTransformations() 00038 { 00039 } 00040 00041 MarSystem* 00042 SpectralTransformations::clone() const 00043 { 00044 return new SpectralTransformations(*this); 00045 } 00046 00047 void 00048 SpectralTransformations::addControls() 00049 { 00050 addctrl("mrs_real/gain", 1.0, ctrl_gain_); 00051 addctrl("mrs_string/mode", "singlebin", ctrl_mode_); 00052 } 00053 00054 void 00055 SpectralTransformations::myUpdate(MarControlPtr sender) 00056 { 00057 MRSDIAG("SpectralTransformations.cpp - SpectralTransformations:myUpdate"); 00058 00059 //Spectrum outputs N values, corresponding to N/2+1 00060 //complex and unique spectrum points - see Spectrum.h documentation 00061 N2_ = ctrl_inObservations_->to<mrs_natural>()/2 + 1; 00062 00063 00064 MarSystem::myUpdate(sender); 00065 } 00066 00067 00068 void 00069 SpectralTransformations::phaseRandomize(realvec& in, realvec& out) 00070 { 00071 mrs_natural t,o; 00072 for(t=0; t < inSamples_; ++t) 00073 for (o=0; o < N2_; o++) 00074 { 00075 if (o==0) //DC bin (i.e. 0) 00076 { 00077 re_ = in(0,t); 00078 im_ = 0.0; 00079 } 00080 else if (o == N2_-1) //Nyquist bin (i.e. N/2) 00081 { 00082 re_ = in(1,t); 00083 im_ = 0.0; 00084 } 00085 else //all other bins 00086 { 00087 re_ = in(2*o, t); 00088 // randomize phase 00089 im_ = in(2*o+1,t); 00090 } 00091 00092 mag_ = sqrt(re_ * re_ + im_ * im_); 00093 // phs_ = -atan2(im_, re_); 00094 phs_ = ((mrs_real)rand() / (mrs_real)(RAND_MAX)) * TWOPI; 00095 phs_ -= PI; 00096 00097 if (o < N2_-1) 00098 { 00099 out(2*o,t) = mag_ * cos(phs_); 00100 out(2*o+1,t) = mag_ * sin(phs_); 00101 } 00102 00103 } 00104 } 00105 00106 00107 00108 void 00109 SpectralTransformations::compress_magnitude(realvec& in, realvec& out) 00110 { 00111 mrs_natural t,o; 00112 for(t=0; t < inSamples_; ++t) 00113 for (o=0; o < N2_; o++) 00114 { 00115 if (o==0) //DC bin (i.e. 0) 00116 { 00117 re_ = in(0,t); 00118 im_ = 0.0; 00119 } 00120 else if (o == N2_-1) //Nyquist bin (i.e. N/2) 00121 { 00122 re_ = in(1,t); 00123 im_ = 0.0; 00124 } 00125 else //all other bins 00126 { 00127 re_ = in(2*o, t); 00128 im_ = in(2*o+1,t); 00129 } 00130 00131 mag_ = sqrt(re_ * re_ + im_ * im_); 00132 phs_ = -atan2(im_, re_); 00133 00134 if (o < N2_-1) 00135 { 00136 out(2*o,t) = log(1+1000.0 * mag_) * cos(phs_); 00137 out(2*o+1,t) = log(1+1000.0 * mag_) * sin(phs_); 00138 00139 // out(2*o,t) = sqrt(mag_) * cos(phs_); 00140 // out(2*o+1,t) = sqrt(mag_) * sin(phs_); 00141 } 00142 00143 } 00144 00145 00146 } 00147 00148 00149 00150 void 00151 SpectralTransformations::three_peaks(realvec& in, realvec& out) 00152 { 00153 mrs_natural t,o; 00154 mrs_real max_mag = 0.0; 00155 mrs_real second_max_mag = 0.0; 00156 mrs_real third_max_mag = 0.0; 00157 mrs_natural max_o = 0; 00158 mrs_natural second_max_o = 0 ; 00159 mrs_natural third_max_o = 0; 00160 00161 00162 00163 00164 00165 for(t=0; t < inSamples_; ++t) 00166 for (o=0; o < N2_; o++) 00167 { 00168 if (o==0) //DC bin (i.e. 0) 00169 { 00170 re_ = in(0,t); 00171 im_ = 0.0; 00172 } 00173 else if (o == N2_-1) //Nyquist bin (i.e. N/2) 00174 { 00175 re_ = in(1,t); 00176 im_ = 0.0; 00177 } 00178 else //all other bins 00179 { 00180 re_ = in(2*o, t); 00181 im_ = in(2*o+1,t); 00182 } 00183 00184 mag_ = sqrt(re_ * re_ + im_ * im_); 00185 00186 00187 00188 if ((mag_ > max_mag) && (o > 2)) 00189 { 00190 max_mag = mag_; 00191 max_o = o; 00192 } 00193 if ((mag_ < max_mag) && (mag_ > second_max_mag) && (o > 2)) 00194 { 00195 second_max_mag = mag_; 00196 second_max_o = o; 00197 } 00198 00199 00200 if ((mag_ < max_mag) && (mag_ < second_max_mag) && (mag_ > third_max_mag) && (o > 2)) 00201 { 00202 third_max_mag = mag_; 00203 third_max_o = o; 00204 } 00205 00206 00207 phs_ = -atan2(im_, re_); 00208 00209 } 00210 00211 00212 00213 00214 for(t=0; t < inSamples_; ++t) 00215 for (o=0; o < N2_; o++) 00216 { 00217 if (o==0) //DC bin (i.e. 0) 00218 { 00219 re_ = in(0,t); 00220 im_ = 0.0; 00221 } 00222 else if (o == N2_-1) //Nyquist bin (i.e. N/2) 00223 { 00224 re_ = in(1,t); 00225 im_ = 0.0; 00226 } 00227 else //all other bins 00228 { 00229 re_ = in(2*o, t); 00230 im_ = in(2*o+1,t); 00231 } 00232 00233 mag_ = sqrt(re_ * re_ + im_ * im_); 00234 phs_ = -atan2(im_, re_); 00235 00236 if (o < N2_-1) 00237 { 00238 if ((o == max_o) || (o == second_max_o) || (o == third_max_o)) 00239 { 00240 out(2*o,t) = 2.0 * mag_ * cos(phs_); 00241 out(2*o+1,t) = 2.0 * mag_ * sin(phs_); 00242 } 00243 else { 00244 out(2*o,t) = 0 * cos(phs_); 00245 out(2*o+1,t) = 0 * sin(phs_); 00246 } 00247 } 00248 00249 } 00250 00251 00252 } 00253 00254 00255 00256 00257 void 00258 SpectralTransformations::singlebin(realvec& in, realvec& out) 00259 { 00260 mrs_natural t,o; 00261 for(t=0; t < inSamples_; ++t) 00262 for (o=0; o < N2_; o++) 00263 { 00264 if (o==4) //DC bin (i.e. 0) 00265 { 00266 re_ = in(0,t); 00267 im_ = 0.0; 00268 } 00269 else if (o == N2_-1) //Nyquist bin (i.e. N/2) 00270 { 00271 re_ = in(1,t); 00272 im_ = 0.0; 00273 } 00274 else //all other bins 00275 { 00276 00277 // if (o ==3) 00278 if (o == 5) 00279 { 00280 re_ = 0.5; 00281 im_ = 0.0; 00282 } 00283 else 00284 { 00285 re_ = 0.0; 00286 im_ = 0.0; 00287 } 00288 00289 } 00290 00291 00292 mag_ = sqrt(re_ * re_ + im_ * im_); 00293 phs_ = -atan2(im_, re_); 00294 // phs_ = ((mrs_real)rand() / (mrs_real)(RAND_MAX)) * TWOPI; 00295 // phs_ -= PI; 00296 00297 if (o < N2_-1) 00298 { 00299 out(2*o,t) = mag_ * cos(phs_); 00300 out(2*o+1,t) = mag_ * sin(phs_); 00301 } 00302 00303 } 00304 } 00305 00306 00307 00308 void 00309 SpectralTransformations::myProcess(realvec& in, realvec& out) 00310 { 00311 00312 if (ctrl_mode_->to<mrs_string>() == "PhaseRandomize") 00313 { 00314 MRSMSG("PhaseRandomize"); 00315 phaseRandomize(in, out); 00316 } 00317 else if (ctrl_mode_->to<mrs_string>() == "singlebin") 00318 { 00319 MRSMSG("SingleBin"); 00320 singlebin(in, out); 00321 } 00322 00323 00324 if (ctrl_mode_->to<mrs_string>() == "three_peaks") 00325 { 00326 three_peaks(in,out); 00327 } 00328 00329 00330 if (ctrl_mode_->to<mrs_string>() == "compress_magnitude") 00331 { 00332 compress_magnitude(in,out); 00333 } 00334 00335 00336 00337 }