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(
00101 const SpectralPeakArray& inPeaks,
00102 const Fundamental& inFund,
00103 const Spectrum& inSpectrum,
00104 SpectralPeakArray& outPeaks,
00105 Fundamental& outFund,
00106 Spectrum& outSpectrum
00107 )
00108 {
00109 outPeaks = inPeaks;
00110 outFund = inFund;
00111 outSpectrum = inSpectrum;
00112
00113 TData gain0 = mInputVoiceGain.GetLastValue();
00114 SendFloatToInControl(mSinusoidalGain,"Gain",gain0);
00115 mSinusoidalGain.Do(outPeaks,outPeaks);
00116
00117
00118 SpectralPeakArray mtmpPeaks;
00119 Fundamental mtmpFund;
00120 Spectrum mtmpSpectrum;
00121
00122 for (int i=0; i < mVoicesPitch.Size(); i++)
00123 {
00124 TData gain = mVoicesGain[i].GetLastValue();
00125 if (gain<0.01)
00126 continue;
00127
00128 TData amount = mVoicesPitch[i].GetLastValue() + frand()*mVoicesDetuningAmount[i].GetLastValue();
00129 amount = CLAM_pow( 2., amount/12. );
00130
00131 SendFloatToInControl(mPitchShift,"PitchSteps",amount);
00132 mPitchShift.Do( inPeaks,
00133 inFund,
00134 inSpectrum,
00135 mtmpPeaks,
00136 mtmpFund,
00137 mtmpSpectrum);
00138
00139 SendFloatToInControl(mSinusoidalGain,"Gain",gain);
00140 mSinusoidalGain.Do(mtmpPeaks,mtmpPeaks);
00141
00142 TData delay = mVoicesDelay[i].GetLastValue();
00143 if (delay>0.)
00144 {
00145 SendFloatToInControl(mPeaksDelay,"Delay Control",delay);
00146 mPeaksDelay.Do(mtmpPeaks, mtmpPeaks);
00147 }
00148
00149 outPeaks = outPeaks + mtmpPeaks;
00150
00151 if (!mIgnoreResidual)
00152 mSpectrumAdder.Do(outSpectrum, mtmpSpectrum, outSpectrum);
00153 }
00154 return true;
00155 }
00156
00157 }