Marsyas
0.6.0-alpha
|
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 }