00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "SMSHarmonizer.hxx"
00023 #include "ProcessingFactory.hxx"
00024
00025 namespace CLAM
00026 {
00027
00028 namespace Hidden
00029 {
00030 static const char * metadata[] = {
00031 "key", "SMSHarmonizer",
00032 "category", "SMS Transformations",
00033 "description", "SMSHarmonizer",
00034 0
00035 };
00036 static FactoryRegistrator<ProcessingFactory, SMSHarmonizer> reg = metadata;
00037 }
00038
00039 bool SMSHarmonizer::ConcreteConfigure(const ProcessingConfig& config)
00040 {
00041 CopyAsConcreteConfig( mConfig, config );
00042
00043 if ( mConfig.GetNumberOfVoices()==0 )
00044 {
00045 AddConfigErrorMessage("The provided config object lacked NumberOfVoices value");
00046 return false;
00047 }
00048
00049 mIgnoreResidual = mConfig.GetIgnoreResidual();
00050
00051 mPitchShift.Configure( FrameTransformationConfig() );
00052 SendFloatToInControl(mPitchShift,"IgnoreResidual",mIgnoreResidual);
00053
00054 mInputVoiceGain.SetBounds(-2.,2.);
00055 mInputVoiceGain.SetDefaultValue(0.);
00056 mInputVoiceGain.DoControl(0.);
00057
00058 int n_voices = mConfig.GetNumberOfVoices();
00059
00060 if (n_voices>MAX_AMOUNT_OF_VOICES) n_voices = MAX_AMOUNT_OF_VOICES;
00061
00062 mVoicesPitch.Resize(n_voices, "Pitch", this);
00063 mVoicesGain.Resize(n_voices, "Gain", this);
00064 mVoicesDetuningAmount.Resize(n_voices, "Voice Detuning", this);
00065 mVoicesDelay.Resize(n_voices, "Voice Delay", this);
00066 for (int i=0; i < mVoicesPitch.Size(); i++)
00067 {
00068 mVoicesGain[i].SetBounds(0.,2.);
00069 mVoicesGain[i].SetDefaultValue(0.);
00070 mVoicesGain[i].DoControl(0.);
00071
00072 mVoicesPitch[i].SetBounds(-24.,24.);
00073 mVoicesPitch[i].SetDefaultValue(0.);
00074 mVoicesPitch[i].DoControl(0.);
00075
00076 mVoicesDetuningAmount[i].SetBounds(0.,1.);
00077 mVoicesDetuningAmount[i].SetDefaultValue(0.);
00078 mVoicesDetuningAmount[i].DoControl(0.);
00079
00080 mVoicesDelay[i].SetBounds(0.,1.);
00081 mVoicesDelay[i].SetDefaultValue(0.);
00082 mVoicesDelay[i].DoControl(0.);
00083 }
00084
00085 return true;
00086 }
00087
00088 bool SMSHarmonizer::Do(const Frame& in, Frame& out)
00089 {
00090 return Do( in.GetSpectralPeakArray(),
00091 in.GetFundamental(),
00092 in.GetResidualSpec(),
00093
00094 out.GetSpectralPeakArray(),
00095 out.GetFundamental(),
00096 out.GetResidualSpec()
00097 );
00098 }
00099
00100 bool SMSHarmonizer::Do( const SpectralPeakArray& inPeaks,
00101 const Fundamental& inFund,
00102 const Spectrum& inSpectrum,
00103 SpectralPeakArray& outPeaks,
00104 Fundamental& outFund,
00105 Spectrum& outSpectrum
00106 )
00107 {
00108 outPeaks = inPeaks;
00109 outFund = inFund;
00110 outSpectrum = inSpectrum;
00111
00112 TData gain0 = mInputVoiceGain.GetLastValue();
00113 SendFloatToInControl(mSinusoidalGain,"Gain",gain0);
00114 mSinusoidalGain.Do(outPeaks,outPeaks);
00115
00116
00117 SpectralPeakArray mtmpPeaks;
00118 Fundamental mtmpFund;
00119 Spectrum mtmpSpectrum;
00120
00121 for (int i=0; i < mVoicesPitch.Size(); i++)
00122 {
00123 TData gain = mVoicesGain[i].GetLastValue();
00124 if (gain<0.01)
00125 continue;
00126
00127 TData amount = mVoicesPitch[i].GetLastValue() + frand()*mVoicesDetuningAmount[i].GetLastValue();
00128 amount = CLAM_pow( 2., amount/12. );
00129
00130 SendFloatToInControl(mPitchShift,"PitchSteps",amount);
00131 mPitchShift.Do( inPeaks,
00132 inFund,
00133 inSpectrum,
00134 mtmpPeaks,
00135 mtmpFund,
00136 mtmpSpectrum);
00137
00138 SendFloatToInControl(mSinusoidalGain,"Gain",gain);
00139 mSinusoidalGain.Do(mtmpPeaks,mtmpPeaks);
00140
00141 TData delay = mVoicesDelay[i].GetLastValue();
00142 if (delay>0.)
00143 {
00144 SendFloatToInControl(mPeaksDelay,"Delay Control",delay);
00145 mPeaksDelay.Do(mtmpPeaks, mtmpPeaks);
00146 }
00147
00148 outPeaks = outPeaks + mtmpPeaks;
00149
00150 if (!mIgnoreResidual)
00151 mSpectrumAdder.Do(outSpectrum, mtmpSpectrum, outSpectrum);
00152 }
00153 return true;
00154 }
00155
00156 }