Login / Register  0 items | $0.00New @ What is KVR? Submit News Advertise

basic 4 sine wave oscillator clips

DSP, Plug-in and Host development discussion.

Moderator: Moderators (Main)

quadsas
KVRist
 
39 posts since 21 Feb, 2011, from Lithuania

Postby quadsas; Fri Jan 17, 2014 8:09 am basic 4 sine wave oscillator clips

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

Postby brendano; Fri Jan 17, 2014 8:25 am Re: basic 4 sine wave oscillator clips

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

Postby quadsas; Fri Jan 17, 2014 8:36 am Re: basic 4 sine wave oscillator clips

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
 
323 posts since 13 Nov, 2002, from Germany, Darmstadt

Postby helium; Fri Jan 17, 2014 8:48 am Re: basic 4 sine wave oscillator clips

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.
Why is 6 afraid of 7

Because 7 8 9.
MadBrain
KVRian
 
777 posts since 1 Dec, 2004

Postby MadBrain; Fri Jan 17, 2014 9:27 am Re: basic 4 sine wave oscillator clips

Reduce the volume of your synth.
mystran
KVRAF
 
4255 posts since 11 Feb, 2006, from Helsinki, Finland

Postby mystran; Fri Jan 17, 2014 10:06 am Re: basic 4 sine wave oscillator clips

MadBrain wrote:Reduce the volume of your synth.


Indeed, that's usually the right solution. :)
Image <- plugins | forum
Korhaan
KVRer
 
19 posts since 26 Jun, 2012

Postby Korhaan; Fri Jan 17, 2014 11:44 am Re: basic 4 sine wave oscillator clips

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

Postby quadsas; Sun Jan 19, 2014 2:11 pm Re: basic 4 sine wave oscillator clips

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

Postby Korhaan; Mon Jan 20, 2014 11:22 am Re: basic 4 sine wave oscillator clips

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