00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "Spectrum2Mel.h"
00020
00021 using namespace std;
00022 using namespace Marsyas;
00023
00024 Spectrum2Mel::Spectrum2Mel(mrs_string name):MarSystem("Spectrum2Mel", name)
00025 {
00026 addControls();
00027
00028 pmelBands_ = 0;
00029 pbandWidth_ = 0.0;
00030 pbandLowEdge_ = 0.0;
00031 pbandHighEdge_ = 0.0;
00032 phtkMel_ = false;
00033 pconstAmp_ = false;
00034 }
00035
00036 Spectrum2Mel::Spectrum2Mel(const Spectrum2Mel& a) : MarSystem(a)
00037 {
00038 ctrl_melBands_ = getctrl("mrs_natural/melBands");
00039 ctrl_bandWidth_ = getctrl("mrs_real/bandWidth");
00040 ctrl_bandLowEdge_ = getctrl("mrs_real/bandLowEdge");
00041 ctrl_bandHighEdge_ = getctrl("mrs_real/bandHighEdge");
00042 ctrl_htkMel_ = getctrl("mrs_bool/htkMel");
00043 ctrl_constAmp_ = getctrl("mrs_bool/constAmp");
00044
00045 melMap_ = a.melMap_;
00046 pmelBands_ = a.pmelBands_;
00047 pbandWidth_ = a.pbandWidth_;
00048 pbandLowEdge_ = a.pbandLowEdge_;
00049 pbandHighEdge_ = a.pbandHighEdge_;
00050 phtkMel_ = a.phtkMel_;
00051 pconstAmp_ = a.pconstAmp_;
00052
00053 }
00054
00055 Spectrum2Mel::~Spectrum2Mel()
00056 {
00057 }
00058
00059 MarSystem*
00060 Spectrum2Mel::clone() const
00061 {
00062 return new Spectrum2Mel(*this);
00063 }
00064
00065 void
00066 Spectrum2Mel::addControls()
00067 {
00068 addctrl("mrs_natural/melBands", 40, ctrl_melBands_);
00069 addctrl("mrs_real/bandWidth", 1.0, ctrl_bandWidth_);
00070 addctrl("mrs_real/bandLowEdge", 0.0, ctrl_bandLowEdge_);
00071 addctrl("mrs_real/bandHighEdge", -1.0, ctrl_bandHighEdge_);
00072 addctrl("mrs_bool/htkMel", false, ctrl_htkMel_);
00073 addctrl("mrs_bool/constAmp", false, ctrl_constAmp_);
00074
00075 ctrl_melBands_->setState(true);
00076 ctrl_bandWidth_->setState(true);
00077 ctrl_bandLowEdge_->setState(true);
00078 ctrl_bandHighEdge_->setState(true);
00079 ctrl_htkMel_->setState(true);
00080 ctrl_constAmp_->setState(true);
00081 }
00082
00083 void
00084 Spectrum2Mel::myUpdate(MarControlPtr sender)
00085 {
00086 mrs_natural t,o;
00087 (void) sender;
00088
00089 ctrl_onSamples_->setValue(ctrl_inSamples_, NOUPDATE);
00090 ctrl_onObservations_->setValue(ctrl_melBands_, NOUPDATE);
00091 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE);
00092
00093 if (pmelBands_ != ctrl_melBands_->to<mrs_natural>())
00094 {
00095 pmelBands_ = ctrl_melBands_->to<mrs_natural>();
00096 ostringstream oss;
00097 for (mrs_natural n=0; n < pmelBands_; n++)
00098 {
00099 oss << "MelBand_" << n << ",";
00100 }
00101 ctrl_onObsNames_->setValue(oss.str(), NOUPDATE);
00102 }
00103
00105
00106
00107
00109 if(tinObservations_ != inObservations_ ||
00110 tonObservations_ != onObservations_ ||
00111 tisrate_ != israte_ ||
00112 pbandWidth_ != ctrl_bandWidth_->to<mrs_real>() ||
00113 pbandLowEdge_ != ctrl_bandLowEdge_->to<mrs_real>() ||
00114 pbandHighEdge_ != ctrl_bandHighEdge_->to<mrs_real>() ||
00115 phtkMel_ != ctrl_htkMel_->to<mrs_bool>() ||
00116 pconstAmp_ != ctrl_constAmp_->to<mrs_bool>())
00117 {
00118 mrs_natural nfilts = ctrl_melBands_->to<mrs_natural>();
00119 bool htkmel = ctrl_htkMel_->to<mrs_bool>();
00120 mrs_natural N2 = inObservations_;
00121 mrs_natural N = (N2-1)*2;
00122
00123
00124 mrs_real srate = israte_*N;
00125
00126 if(ctrl_bandHighEdge_->to<mrs_real>() == -1.0)
00127 ctrl_bandHighEdge_->setValue(srate/2.0, NOUPDATE);
00128
00129 pbandWidth_ = ctrl_bandWidth_->to<mrs_real>();
00130 pbandLowEdge_ = ctrl_bandLowEdge_->to<mrs_real>();
00131 pbandHighEdge_ = ctrl_bandHighEdge_->to<mrs_real>();
00132 phtkMel_ = ctrl_htkMel_->to<mrs_bool>();
00133 pconstAmp_ = ctrl_constAmp_->to<mrs_bool>();
00134
00135
00136 realvec fftfreqs(N2);
00137 for(o=0; o < N2; ++o)
00138 fftfreqs(o) = o / N * srate;
00139
00140
00141 mrs_real minmel = hertz2mel(ctrl_bandLowEdge_->to<mrs_real>(), htkmel);
00142 mrs_real maxmel = hertz2mel(ctrl_bandHighEdge_->to<mrs_real>(), htkmel);
00143 realvec binfrqs(nfilts+2);
00144 realvec binbin(nfilts+2);
00145 for(t=0; t < nfilts+2; ++t)
00146 {
00147 binfrqs(t) = mel2hertz(minmel + t/(nfilts+1.0)*(maxmel-minmel) , htkmel);
00148 binbin(t) = floor(binfrqs(t)/srate*(N-1) + 0.5);
00149 }
00150
00151 realvec fs(3);
00152 mrs_real width = ctrl_bandWidth_->to<mrs_real>();
00153 realvec loslope(N2);
00154 realvec hislope(N2);
00155 for(mrs_natural i=0; i < nfilts; ++i)
00156 {
00157 for(t=0; t<3; ++t)
00158 fs(t) = binfrqs(i+t);
00159
00160
00161 for(t=0; t<3; ++t)
00162 fs(t) = fs(1)+ width*(fs(t) - fs(1));
00163
00164
00165 for(t=0; t < N2; ++t)
00166 {
00167 loslope(t) = (fftfreqs(t) - fs(0)) / (fs(1) - fs(0));
00168 hislope(t) = (fs(2) - fftfreqs(t)) / (fs(2) - fs(1));
00169 }
00170
00171
00172 for(t=0; t < N2; ++t)
00173 melMap_(i,t) = max((mrs_real)0.0, (mrs_real)min(loslope(t), hislope(t)));
00174 }
00175
00176 if(ctrl_constAmp_->to<mrs_bool>() == false)
00177 {
00178
00179 mrs_real diagMatrix;
00180 for(o = 0; o < nfilts; ++t)
00181 {
00182 diagMatrix = 2.0 / (binfrqs(o+2) - binfrqs(o));
00183 for(t=0; t< N2; ++t)
00184 melMap_(o,t) *= diagMatrix;
00185 }
00186 }
00187 }
00188 }
00189
00190 void
00191 Spectrum2Mel::myProcess(realvec& in, realvec& out)
00192 {
00193
00194
00195 mrs_natural o,t;
00196 out.setval(0.0);
00197 for(t=0; t< inSamples_; ++t)
00198 {
00199 for(o=0; o< onObservations_; ++o)
00200 {
00201 for(mrs_natural i=0; i< inObservations_; ++i)
00202 {
00203 out(o,t)+= in(i,t)*melMap_(o,i);
00204 }
00205 }
00206 }
00207 }