Cabbage Logo
Back to Cabbage Site

Summing audio signals in while loop causes strange sounds (sounds like FM?)

Hi :slight_smile: ,

I am very new to CSound and Cabbage. Both programms so far have been amazing. I made a few synths that I am starting to be very happy with.
I am trying to build a supersaw synthesiser, and I made an example of the problem I have with a synth I am making. I got two oscilators to detune with the following code:


instr 1
    iFreq = p4
    iGain = p5
    iDetune = 2
    aSig1 vco2 iGain, iFreq + iDetune
    aSig2 vco2 iGain, iFreq - iDetune
    aOut = aSig1 + aSig2
     outs aOut, aOut
endin

But the problem with this snippet is that I don’t want to hardcode the oscilators.
I want to have a slider in my GUI to select the amount voices to use for the supersaw.
So I made a loop that makes an oscilator for every voice.
The problem with the following code snipped is that it does not sound like a detuned saw, but rather a strange digital sound. Can someone explain to me why it makes this sound, and how I should go about generating oscilators?

instr 1
    iFreq = p4
    iGain = p5
    iDetune = 2
    iVoices = chnget("voices") ; =2
    
    aOut = 0 ; maybe the initiation goes wrong?
    kIndx  = 0

    until kIndx == iVoices do 
      aSig vco2 iGain, iFreq + iDetune * kIndx
      aOut += aSig
      kIndx += 1
    od
        
    out aOut, aOut ; strange fm sound?
endin

Thank you very much in advance for the effort.
~ Cheers

Running a loop like this won’t work because Csound does not create a new vco2 each time it runs through the loop. If you have arrived at Csound from any other programming language you will find this quite odd! But there are ways around it. The most common one being a recursive UDO. Here is an example of a SuperWas type thing as a UDO:

giSine ftgen 1, 0, 4096, 10, 1

opcode SuperSaw,a,kkkO 
   iDetune random 0, 1
   kAmp, kFreq, iNum, iCnt xin 
   aSig vco kAmp/iNum,kFreq+iDetune, 1, 0, giSine
   iCount = iCnt+1 
   if iCount < iNum then 
      aVcoBank SuperSaw 1/iNum,kFreq+iDetune,iNum,iCount
   endif 
   xout aSig + aVcoBank
endop 

The UDO calls itself over and over again until it reaches iNum voices. Dynamically modifying the number of voices in realtime might be a little tricky though. I’ve attached. full example that will let users controls the number of voices, but at i-time only. Note too that I am using the vco opcode instead of vco2. vco is more CPU friendly than vco2.

1 Like

Thank you very much for the quick responce. I will try the code out in a few hour when I have time. I think I get the concept behind it.

Here is another version that lets you move through the number of voices at k-rate, but it does involve some if-else tests. I will think about a way to do this recursively using a k-rate counter, but I’m not sure it is possible.

1 Like

This is a super interesting technique but I think you’re missing attachments :wink:

1 Like

:see_no_evil: Thanks!

SuperSaw.csd (1.6 KB) SuperSaw2.csd (1003 Bytes)

2 Likes

Hi, I think i’m missing something . The opcode description states that vco2 is faster but usses more memory than vco since it uses precalculated tables. Why do you say it is faster in this implementation?

This opcode can be faster than vco and also allows better sound quality
The disadvantage is increased memory usage.
https://csound.com/docs/manual/vco2.html

ps. I tried the example you made and the UDO works great for what I wanted to do. :slightly_smiling_face:

Hello rorywalsh, it turns out that when switching the voices arround a few time resonance forms in the oscilator bank.
I have an example sound from my synth, but the same happens when turning up and down the voices on your example a few times.

You’re right about vco2, my apologies. But I’m still not sure it’s the best option for this. Let me check the Csound source code for a moment…

It looks like it is the best way to go after all. It does get a little sluggish when lots are used. You might gain some performance by building your own lightweight version, but if you’re not hitting any real performance issues there is little point.

I am currently running 28 voices on my supersaw. I stress tested it agains simulair software with simulair settings and it seems only slightly slower if not exactly as fast. For optimalisation I will deffinitifly write my own after a while, only if it’s just for fun.

I’ve got more problems with strange sounds still forming in the oscilators unfortunalty. That really kills the synth currently.

That’s great.

Is this only when using vco as opposed to vco2?

The strange resonance sounds happen with both vco and vco2 apparantly. I tried both.

My bad, I should have set aVcoBank to 0 at init time. Working UDO below:

opcode SuperSaw,a,kkiO 
   iDetune random 0, 1
   aVcoBank init 0
   kAmp, kFreq, iNum, iCnt xin 
   aSig vco2 kAmp/iNum,kFreq+iDetune
   iCount = iCnt+1 
   if iCount < iNum then 
      aVcoBank SuperSaw 1/iNum,kFreq+iDetune,iNum,iCount
   endif 
   xout aSig + aVcoBank
endop

Thank you, I will check it out later today.

It seems to have solved the problem. No more strange sounds in the oscilators now (for now):+1:

1 Like