basic 4 sine wave oscillator clips

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Basically, I am trying to build a simple 4 sine wave oscillator, but for some reason it clips. I've tried doing noobish attempt of reducing output to 1 (if >1, then outSample = 1), but it didn't work and also changed the sound. any ideas? mGain is value from 0 to 1, just controlling the volume of each wave.



Code: Select all

void VST_Plug_in::processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames)
{
    float* out1 = outputs[0];
    float* out2 = outputs[1];

	float outSample = 0.0;
	float frequency = 0.0;

	for(int i = 0; i < sampleFrames; i++)
    {
		//create the sine wave output
		frequency = m_frequencyTable[m_currentNote];
		mSine1 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain1;
		mSine2 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain2;
		mSine3 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain3;
		mSine4 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain4;

		//multiply the sine by the velocity
		outSample = mSine1 + mSine2 + mSine3 + mSine4;
		outSample = (outSample * m_currentVelocity) ;


		//increment the time
		m_time++;

		// write samples to output buffer 
        out1[i] = outSample;
        out2[i] = outSample;
    }
}

Post

You want your outSample to be < 1. So divide your mGain* by the number of waves

Post

Yes, that does work to an extent, thank you.

Problem right now is that most notes clip when you play them (at the very start, for a few miliseconds you get that clip, and after that its fine). Is this an easily fixable problem?

Post

This

Code: Select all

      mSine1 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain1;
      mSine2 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain2;
      mSine3 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain3;
      mSine4 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain4;

      //multiply the sine by the velocity
      outSample = mSine1 + mSine2 + mSine3 + mSine4;
      outSample = (outSample * m_currentVelocity) ;
is equivalent to

Code: Select all

      mSine = (float)sin(2.0*PI*frequency*m_time/m_sampleRate);
      outSample = mSine * (mGain1 + mGain2 + mGain3 + mGain4) * m_currentVelocity;
.
So just make sure that "(mGain1 + mGain2 + mGain3 + mGain4) * m_currentVelocity" is allways ≤ 1.

Post

Reduce the volume of your synth.

Post

MadBrain wrote:Reduce the volume of your synth.
Indeed, that's usually the right solution. :)

Post

helium wrote:This

Code: Select all

      mSine1 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain1;
      mSine2 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain2;
      mSine3 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain3;
      mSine4 = (float)sin(2.0*PI*frequency*m_time/m_sampleRate) * mGain4;

      //multiply the sine by the velocity
      outSample = mSine1 + mSine2 + mSine3 + mSine4;
      outSample = (outSample * m_currentVelocity) ;
is equivalent to

Code: Select all

      mSine = (float)sin(2.0*PI*frequency*m_time/m_sampleRate);
      outSample = mSine * (mGain1 + mGain2 + mGain3 + mGain4) * m_currentVelocity;
.
So just make sure that "(mGain1 + mGain2 + mGain3 + mGain4) * m_currentVelocity" is allways ≤ 1.
As mentioned the 4 oscillators, since they have the same phase are just like one sine scaled up. You can see what they look like when no gain is applied to any of them.
http://www.wolframalpha.com/input/?i=si ... sin%28x%29
Limiting the output at one would turn this signal into a square wave:

Post

I don't have any big problems with clipping, thank you for your help. I've added some detuning and it sounds great. Afterwards I added a square wave, and now I've tried adding sawtooth, but somethings not working. it just doesn't seem to generate saw wave, just a highpitched sound. Formula is below, seems to like somethings wrong with time/sampleRate thing.

mSawt = 2*frequency*(m_time / m_sampleRate-(float)floor(m_time / m_sampleRate+0.5*frequency)) * (mGain6 / 6);

Post

Your function is for a sawtooth, but it is not within the range -1 to 1 and does not show the intended frequency. One thing that I can see is that you are scaling your result by the waveform's frequency, which will cause an issue. Also, going by your previous question I am assuming your m_time variable is in samples since you scale it down by m_sampleRate in your sine waveform generation. You are missing the division by the waveform's period, or 1 / frequency. See this wikipedia article on sawtooth generation. http://en.wikipedia.org/wiki/Sawtooth_wave

Specifically the formula:
x(t) = 2 * (t / a - floor(1/2 + t/a))

using your variables this translates to:
m_time_in_seconds = m_time / m_sampleRate
x(m_time_in_seconds) = 2 * ((m_time_in_seconds / (1 / frequency)) - floor(1/2 + (m_time_in_seconds/(1 / frequency))))


Here is an example sawtooth generation function in python for reference

Code: Select all

def generate_sawtooth(seconds, sample_rate, frequency, gain):
	total_sample_count = sample_rate * seconds
	time_steps_seconds = [x / sample_rate for x in range(0, total_sample_count)]
	period = 1 / frequency
	samples = [(2 * (x / period - math.floor(0.5 + x / period)) * gain) for x in time_steps_seconds]
	return samples

Post Reply

Return to “DSP and Plugin Development”