AudioResearchBlog

Covering all audio related stuff with special focus on programming and digital signal processing

SMS Harmonizer part1

Posted by hordia on July 31st, 2007

I’ll start talking a bit about this effect which is mainly used for vocal harmonizing. Given an input voice (or whatever) as output you obtain (how many as you want) automatic harmonic related voices (a minor/major third, a fifth, a sixth or any musical interval you want).

This implementation, is mainly based on many SMS pitch-shiftings (one for each voice) and a control gain for each one. Pitch controls are based on equal-tempered scale semitones, following fund*2^{\frac{p_c}{12}} relation for each voice.

 
This was my first version of the network:

SMSHarmonizer-basic-network

 
 
Testing it, my voice never sounded so musical, hehehe… but still awful, so I was thinking in your ears health and demos are with Elvis one ;-)

Disclaimer: all audio demos are early testing versions (still with artifacts and clicks that should be removed soon)

Elvis harmonized demo: elvis-harmonized.ogg (to hear the online/streaming version go here)

 
Prototype:

harmonizer prototype

 
 
Configuration:
SMSHarmonizer config

Note: demos were done without residual processing because adding residual does not improve results much and adds a lot of overhead.

 
 
Then, following xamat’s suggestions I also added a detunning effect (and delay, but this one isn’t working properly yet)

SMSHarmonizer detuning delay

 
 
Elvis harmonized (detunned version) demo: elvis-harmonized-detunned.ogg (to hear the online/streaming version go here)

 
but wait! a lot of graphics and this is also a ‘coding’ blog!!! here you have some code… and btw you can see that programming under CLAM could be very easy once you get the basics…

bool SMSHarmonizer::Do( const SpectralPeakArray& inPeaks, 
			const Fundamental& inFund,
			const Spectrum& inSpectrum, 
			SpectralPeakArray& outPeaks,
			Fundamental& outFund,
			Spectrum& outSpectrum
		      )
{
	outPeaks = inPeaks;
	outFund = inFund;
	outSpectrum = inSpectrum;
 
	TData gain0 = mInputVoiceGain.GetLastValue();
	mSinusoidalGain.GetInControl("Gain").DoControl(gain0);
	mSinusoidalGain.Do(outPeaks,outPeaks);
 
	SpectralPeakArray mtmpPeaks;
	Fundamental mtmpFund;
	Spectrum mtmpSpectrum;
 
	for (int i=0; i < mVoicesPitch.Size(); i++)
	{
		TData gain = mVoicesGain[i].GetLastValue();
		if (gain&lt;0.01) //means voice OFF
			continue;
		
		TData amount = mVoicesPitch[i].GetLastValue() + frand()*mVoicesDetuningAmount[i].GetLastValue(); //detuning
		amount = CLAM_pow( 2., amount/12. ); //adjust to equal-tempered scale semitones
 
		mPitchShift.GetInControl("PitchSteps").DoControl(amount);
		mPitchShift.Do( inPeaks,
				inFund, 
				inSpectrum,
				mtmpPeaks, 
				mtmpFund,
				mtmpSpectrum);
	
		mSinusoidalGain.GetInControl("Gain").DoControl(gain);
		mSinusoidalGain.Do(mtmpPeaks,mtmpPeaks);
 
		TData delay = mVoicesDelay[i].GetLastValue();
		if (delay>0.)
		{
			mPeaksDelay.GetInControl("Delay Control").DoControl(delay);
			mPeaksDelay.Do(mtmpPeaks, mtmpPeaks);
		}
 
		outPeaks = outPeaks + mtmpPeaks;
		
		if (!mIgnoreResidual)
			mSpectrumAdder.Do(outSpectrum, mtmpSpectrum, outSpectrum);
	}
	return true;
}

The plan includes add MIDI control for each voice pitch (then will be easy to control them for example by a keyboard by the same singing person)

Next post: SMSMorph.


, , , , , , , , , , , ,


WordPress database error: [Incorrect file format 'wp_comments']
SELECT * FROM wp_comments WHERE comment_post_ID = '124' AND comment_approved = '1' ORDER BY comment_date

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

 
Cerrar
Enviar por Correo