## basic 4 sine wave oscillator clips

quadsas
KVRist

39 posts since 21 Feb, 2011, from Lithuania
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;    }}`
brendano
KVRer

7 posts since 9 Jan, 2014
You want your outSample to be < 1. So divide your mGain* by the number of waves
quadsas
KVRist

39 posts since 21 Feb, 2011, from Lithuania
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?
helium
KVRist

327 posts since 13 Nov, 2002, from Germany, Darmstadt
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.
MadBrain
KVRian

944 posts since 1 Dec, 2004
Reduce the volume of your synth.
mystran
KVRAF

4839 posts since 11 Feb, 2006, from Helsinki, Finland
MadBrain wrote:Reduce the volume of your synth.

Indeed, that's usually the right solution.
<- plugins | forum
Korhaan
KVRer

19 posts since 26 Jun, 2012
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=sin%28x%29+%2B+sin%28x%29+%2B+sin%28x%29+%2B+sin%28x%29
Limiting the output at one would turn this signal into a square wave:
quadsas
KVRist

39 posts since 21 Feb, 2011, from Lithuania
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);
Korhaan
KVRer

19 posts since 26 Jun, 2012
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`

Moderator: Moderators (Main)

Return to DSP and Plug-in Development

Advertisements