Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/Chroma.cpp
Go to the documentation of this file.
00001 /*
00002  *  Chroma.cpp
00003  *  testChroma
00004  *
00005  *  Created by tsunoo on 09/05/03.
00006  *  Copyright 2009 Emiru Tsunoo. All rights reserved.
00007  *
00008  */
00009 
00010 #include "Chroma.h"
00011 
00012 using std::ostringstream;
00013 using namespace Marsyas;
00014 
00015 Chroma::Chroma(mrs_string name): MarSystem("Chroma", name)
00016 {
00017   addControls();
00018 }
00019 
00020 Chroma::Chroma(const Chroma& a): MarSystem(a)
00021 {
00022   ctrl_samplingFreq_ = getctrl("mrs_real/samplingFreq");
00023   ctrl_lowOctNum_ = getctrl("mrs_natural/lowOctNum");
00024   ctrl_highOctNum_ = getctrl("mrs_natural/highOctNum");
00025 }
00026 
00027 Chroma::~Chroma()
00028 {
00029 }
00030 
00031 MarSystem*
00032 Chroma::clone() const
00033 {
00034   return new Chroma(*this);
00035 }
00036 
00037 void
00038 Chroma::addControls()
00039 {
00040   addControl("mrs_real/samplingFreq", 44100.0, ctrl_samplingFreq_);
00041   addControl("mrs_natural/lowOctNum", 0, ctrl_lowOctNum_);
00042   addControl("mrs_natural/highOctNum", 8, ctrl_highOctNum_);
00043 }
00044 
00045 void
00046 Chroma::myUpdate(MarControlPtr sender)
00047 {
00048   (void) sender;  //suppress warning of unused parameter(s)
00049   ctrl_onObservations_->setValue(12, NOUPDATE);
00050   ctrl_onSamples_->setValue(inSamples_, NOUPDATE);
00051   ctrl_osrate_->setValue(ctrl_samplingFreq_->to<mrs_real>(), NOUPDATE);
00052   ostringstream oss;
00053   mrs_natural i, j, k;
00054   mrs_real tmpreal;
00055   for(mrs_natural o=0; o<ctrl_onObservations_->to<mrs_natural>(); o++) {
00056     oss << "Chroma_" << o << ",";
00057   }
00058   ctrl_onObsNames_->setValue(oss.str(), NOUPDATE);
00059 
00060   lowNum_ = ctrl_lowOctNum_->to<mrs_natural>();
00061   if(lowNum_ < 0) {
00062     lowNum_ = 0;
00063   }
00064   highNum_ = ctrl_highOctNum_->to<mrs_natural>();
00065   if(highNum_ > 8) {
00066     highNum_ = 8;
00067   }
00068 
00069   // memory allocation and initialization
00070   m_.create(9);
00071   freq_.create(inObservations_);
00072   filter_.create(14, inObservations_);
00073   chord_.create(14);
00074   chord_(1) = 261.625565; // C4
00075   chord_(2) = 277.182630; // C♯/D♭4
00076   chord_(3) = 293.664747; // D4
00077   chord_(4) = 311.126983; // D♯/E♭4
00078   chord_(5) = 329.627556; // E4
00079   chord_(6) = 349.228231; // F4
00080   chord_(7) = 369.994422; // F♯/G♭4
00081   chord_(8) = 391.995435; // G4
00082   chord_(9) = 415.304697; // G♯/A♭4
00083   chord_(10) = 440.000000; // A4
00084   chord_(11) = 466.163761; // A♯/B♭4
00085   chord_(12) = 493.883301; // B4
00086   chord_(0) = 0.5 * chord_(12);
00087   chord_(13) = 2.0 * chord_(1);
00088 
00089   for(i=0; i<9; ++i) {
00090     m_(i) = pow(2.0, (mrs_real)i-3.0);
00091   }
00092   for(i=0; i<inObservations_; ++i) {
00093     freq_(i) = ctrl_samplingFreq_->to<mrs_real>()*(mrs_real)i / (2.0*(mrs_real)(inObservations_-1));
00094   }
00095 
00096   // create filter
00097   for(i=1; i<13; ++i) {
00098     for(k=0; k<inObservations_-1; k++) {
00099       for(j=lowNum_; j<highNum_+1; j++) {
00100         if(freq_(k) < m_(j)*chord_(i) && freq_(k+1) >= m_(j)*chord_(i)) {
00101           filter_(i,k) += (freq_(k+1)-m_(j)*chord_(i)) / (freq_(k+1)-freq_(k));
00102           filter_(i,k+1) += (m_(j)*chord_(i)-freq_(k)) / (freq_(k+1)-freq_(k));
00103         }
00104         if((m_(j)*chord_(i)+m_(j)*chord_(i-1))/2.0 < freq_(k) && freq_(k) <= (m_(j)*chord_(i+1)+m_(j)*chord_(i))/2.0) {
00105           filter_(i,k) += 1.0;
00106         }
00107       }
00108     }
00109   }
00110   for(k=0; k<inObservations_; k++) {
00111     tmpreal = 0.0;
00112     for(i=1; i<13; ++i) {
00113       tmpreal += filter_(i,k);
00114     }
00115     if(tmpreal > 0) {
00116       for(i=1; i<13; ++i) {
00117         filter_(i,k) /= tmpreal;
00118       }
00119     }
00120   }
00121 
00122 }
00123 
00124 void
00125 Chroma::myProcess(realvec& in, realvec& out)
00126 {
00127   mrs_natural i, j, k;
00128 
00129   if(inSamples_ > 0) {
00130     for(j=0; j<12; j++) {
00131       for(i=0; i<inSamples_; ++i) {
00132         out(j,i) = 0;
00133       }
00134     }
00135     for(i=0; i<inSamples_; ++i) {
00136       for(j=1; j<13; j++) {
00137         for(k=0; k<inObservations_; k++) {
00138           out(j-1, i) += filter_(j,k)*in(k,i);//12.0;
00139         }
00140       }
00141     }
00142   }
00143 
00144 }