Cabbage Logo
Back to Cabbage Site

CSOUND makes no sound

ok so even though instr 4 should make sound it does not , what am I doing wrong here ?
I tested this with just instr 4 in a new csd file and it makes sound fine but inside my synth it cannot , what am I missing here ?

<Cabbage>
form caption("Lazer Hawk v0.1") size(800, 800), colour(100, 100, 182), pluginid("def1")
keyboard bounds(0, 700, 800, 100)
image bounds(2, 0, 800, 100), colour(153, 153, 255, 255) outlinecolour(192, 18, 18, 255){
label      bounds(0, 5, 200, 20), text("LazerHawk v0.01"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
}
image bounds(2, 106, 800, 185) colour(61, 106, 73, 255) , plant("layer1"){

label      bounds(0, 5, 200, 20), text("Sound Generator 1"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
combobox   bounds(0, 25, 100, 25),items("sine" , "saw", "square", "triangle"), channel("SG1 Wav"),colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(100, 25, 50, 50), trackerinsideradius(0.6), text("PWM"), channel("SG1 PWM"), range(0.01, 0.99, .01, 1, 0.001), textcolour(0,0,0)
rslider    bounds(150, 25, 50, 50), trackerinsideradius(0.6), text("Phase"), channel("SG1 Phase"), range(0.01, 0.99, .01, 1, 0.001), textcolour(0,0,0)

label      bounds(0, 100, 190, 20), text("Amp Envelope"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(0, 125, 50, 50), trackerinsideradius(0.6), text("A"), channel("SG1 Env Amp A"), range(0.01, 12, .01, 1, 0.001), textcolour(0,0,0)
rslider    bounds(50, 125, 50, 50), trackerinsideradius(0.6), text("D"), channel("SG1 Env Amp D"), range(0.01, 12, 2, 1, 0.001), textcolour(0,0,0)
rslider    bounds(100, 125, 50, 50), trackerinsideradius(0.6), text("S"), channel("SG1 Env Amp S"), range(0.01, 1, 1, 1, 0.001), textcolour(0,0,0)
rslider    bounds(150, 125, 50, 50), trackerinsideradius(0.6), text("R"), channel("SG1 Env Amp R"), range(0.01, 12, .01, 1, 0.001), textcolour(0,0,0)

label      bounds(310, 5, 90, 20), text("Filter LP"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(300, 25, 50, 50), trackerinsideradius(0.6), text("Freq"), channel("SG1 Low Pass Frequency"), range(100, 16000, 16000, 1, 0.001), textcolour(0,0,0)
rslider    bounds(350, 25, 50, 50), trackerinsideradius(0.6), text("Reas"), channel("SG1 Low Pass Reasonance"), range(0.01, 2, 0, 1, 0.001), textcolour(0,0,0)

label      bounds(210, 5, 90, 20), text("Filter HP"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(200, 25, 50, 50), trackerinsideradius(0.6), text("Freq"), channel("SG1 High Pass Frequency"), range(100, 16000, 100, 1, 0.001), textcolour(0,0,0)
rslider    bounds(250, 25, 50, 50), trackerinsideradius(0.6), text("Reas"), channel("SG1 High Pass Reasonance"), range(1, 200, 1, 1, 0.001), textcolour(0,0,0)

label      bounds(200, 100, 190, 20), text("Filter Envelope"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(200, 125, 50, 50), trackerinsideradius(0.6), text("A"), channel("SG1 Env Filters A"), range(0.01, 12, .01, 1, 0.001), textcolour(0,0,0)
rslider    bounds(250, 125, 50, 50), trackerinsideradius(0.6), text("D"), channel("SG1 Env Filters D"), range(0.01, 12, 2, 1, 0.001), textcolour(0,0,0)
rslider    bounds(300, 125, 50, 50), trackerinsideradius(0.6), text("S"), channel("SG1 Env Filters S"), range(0.01, 1, 1, 1, 0.001), textcolour(0,0,0)
rslider    bounds(350, 125, 50, 50), trackerinsideradius(0.6), text("R"), channel("SG1 Env Filters R"), range(0.01, 12, .01, 1, 0.001), textcolour(0,0,0)


} 
image bounds(0, 298, 800, 197) colour(108, 63, 91, 255){

label      bounds(0, 5, 200, 20), text("Sound Generator 2"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
combobox   bounds(0, 25, 100, 25),items("sine" , "saw", "square", "triangle"), channel("SG2 Wav"),colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(100, 25, 50, 50), trackerinsideradius(0.6), text("PWM"), channel("SG2 PWM"), range(0.01, 0.99, .01, 1, 0.001), textcolour(0,0,0)
rslider    bounds(150, 25, 50, 50), trackerinsideradius(0.6), text("Phase"), channel("SG2 Phase"), range(0.01, 0.99, .01, 1, 0.001), textcolour(0,0,0)

label      bounds(0, 100, 190, 20), text("Amp Envelope"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(0, 125, 50, 50), trackerinsideradius(0.6), text("A"), channel("SG2 Env Amp A"), range(0.01, 12, .01, 1, 0.001), textcolour(0,0,0)
rslider    bounds(50, 125, 50, 50), trackerinsideradius(0.6), text("D"), channel("SG2 Env Amp D"), range(0.01, 12, 2, 1, 0.001), textcolour(0,0,0)
rslider    bounds(100, 125, 50, 50), trackerinsideradius(0.6), text("S"), channel("SG2 Env Amp S"), range(0.01, 1, 1, 1, 0.001), textcolour(0,0,0)
rslider    bounds(150, 125, 50, 50), trackerinsideradius(0.6), text("R"), channel("SG2 Env Amp R"), range(0.01, 12, .01, 1, 0.001), textcolour(0,0,0)

label      bounds(310, 5, 90, 20), text("Filter LP"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(300, 25, 50, 50), trackerinsideradius(0.6), text("Freq"), channel("SG2 Low Pass Frequency"), range(100, 16000, 16000, 1, 0.001), textcolour(0,0,0)
rslider    bounds(350, 25, 50, 50), trackerinsideradius(0.6), text("Reas"), channel("SG2 Low Pass Reasonance"), range(0.01, 2, 0, 1, 0.001), textcolour(0,0,0)

label      bounds(210, 5, 90, 20), text("Filter HP"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(200, 25, 50, 50), trackerinsideradius(0.6), text("Freq"), channel("SG2 High Pass Frequency"), range(100, 16000, 100, 1, 0.001), textcolour(0,0,0)
rslider    bounds(250, 25, 50, 50), trackerinsideradius(0.6), text("Reas"), channel("SG2 High Pass Reasonance"), range(1, 200, 1, 1, 0.001), textcolour(0,0,0)

label      bounds(200, 100, 190, 20), text("Filter Envelope"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(200, 125, 50, 50), trackerinsideradius(0.6), text("A"), channel("SG2 Env Filters A"), range(0.01, 12, .01, 1, 0.001), textcolour(0,0,0)
rslider    bounds(250, 125, 50, 50), trackerinsideradius(0.6), text("D"), channel("SG2 Env Filters D"), range(0.01, 12, 2, 1, 0.001), textcolour(0,0,0)
rslider    bounds(300, 125, 50, 50), trackerinsideradius(0.6), text("S"), channel("SG2 Env Filters S"), range(0.01, 1, 1, 1, 0.001), textcolour(0,0,0)
rslider    bounds(350, 125, 50, 50), trackerinsideradius(0.6), text("R"), channel("SG2 Env Filters R"), range(0.01, 12, .01, 1, 0.001), textcolour(0,0,0)


} 
image bounds(0, 500, 800, 200) colour(120, 69, 69, 255){
label      bounds(0, 0, 190, 20), text("General"), colour(60, 60, 120, 122), fontcolour(0, 0, 0, 255)
rslider    bounds(0, 25, 50, 50), trackerinsideradius(0.6), text("SG1"), channel("SG1 Amp"), range(0.0, .5, .2, 1, 0.001), textcolour(0,0,0)
rslider    bounds(50, 25, 50, 50), trackerinsideradius(0.6), text("SG2"), channel("SG2 Amp"), range(0.0, .5, .2, 1, 0.001), textcolour(0,0,0)
}
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables.
ksmps = 32
nchnls = 2
0dbfs = 1



;instrument will be triggered by keyboard widget
; SOUND GENERATOR 1
instr 1

  ; Waveform
  iSG1wavStr chnget "SG1 Wav"
  if iSG1wavStr == 1 then      ;sine
    iSG1wav = 0
  elseif iSG1wavStr == 2 then  ;saw
    iSG1wav = 0
  elseif iSG1wavStr == 3 then  ;square
    iSG1wav = 2
  elseif iSG1wavStr == 4 then  ;triangle
    iSG1wav = 4
  endif
  ; PWM
  kSG1PWM chnget "SG1 PWM"
  ; Phase
  kSG1Phase chnget "SG1 Phase"
  ; Amp Envelope
  iSG1EnvAmpAttack chnget "SG1 Env Amp A"
  iSG1EnvAmpDecay chnget "SG1 Env Amp D"
  iSG1EnvAmpSustain chnget "SG1 Env Amp S"
  iSG1EnvAmpRelease chnget "SG1 Env Amp R"
  ; Low Pass
  kSG1FilterLpF chnget "SG1 Low Pass Frequency"
  kSG1FilterLpR chnget "SG1 Low Pass Reasonance"
  ; High Pass
  kSG1FilterHpF chnget "SG1 High Pass Frequency"
  kSG1FilterHpR chnget "SG1 High Pass Reasonance"
  ; Filter Envelope
  iSG1EnvFilterAttack chnget "SG1 Env Filters A"
  iSG1EnvFilterDecay chnget "SG1 Env Filters D"
  iSG1EnvFilterSustain chnget "SG1 Env Filters S"
  iSG1EnvFilterRelease chnget "SG1 Env Filters R"
  
  
  kSG1EnvAmp madsr iSG1EnvAmpAttack, iSG1EnvAmpDecay, iSG1EnvAmpSustain, iSG1EnvAmpRelease
  kSG1EnvFilter madsr iSG1EnvFilterAttack, iSG1EnvFilterDecay, iSG1EnvFilterSustain, iSG1EnvFilterRelease
  aSG1 vco2 p5*kSG1EnvAmp, p4, iSG1wav, kSG1PWM, kSG1Phase
  aSG1FLp moogladder aSG1,kSG1FilterLpF * kSG1EnvFilter,kSG1FilterLpR
  aSG1FHp bqrez aSG1FLp, kSG1FilterHpF * kSG1EnvFilter, kSG1FilterHpR, 1
  ;outs aSG1FHp * 0.1, aSG1FHp * 0.1
  aSG1Output = aSG1FHp
  chnset aSG1Output, "SG1Output"
    
endin

; SOUND GENERATOR 2
instr 2
  
  ; Waveform
  iSG2wavStr chnget "SG2 Wav"
  if iSG2wavStr == 1 then      ;sine
    iSG2wav = 0
  elseif iSG2wavStr == 2 then  ;saw
    iSG2wav = 0
  elseif iSG2wavStr == 3 then  ;square
    iSG2wav = 2
  elseif iSG2wavStr == 4 then  ;triangle
    iSG2wav = 4
  endif
  ; PWM
  kSG2PWM chnget "SG2 PWM"
  ; Phase
  kSG2Phase chnget "SG2 Phase"
  ; Amp Envelope
  iSG2EnvAmpAttack chnget "SG2 Env Amp A"
  iSG2EnvAmpDecay chnget "SG2 Env Amp D"
  iSG2EnvAmpSustain chnget "SG2 Env Amp S"
  iSG2EnvAmpRelease chnget "SG2 Env Amp R"
  ; Low Pass
  kSG2FilterLpF chnget "SG2 Low Pass Frequency"
  kSG2FilterLpR chnget "SG2 Low Pass Reasonance"
  ; High Pass
  kSG2FilterHpF chnget "SG2 High Pass Frequency"
  kSG2FilterHpR chnget "SG2 High Pass Reasonance"
  ; Filter Envelope
  iSG2EnvFilterAttack chnget "SG2 Env Filters A"
  iSG2EnvFilterDecay chnget "SG2 Env Filters D"
  iSG2EnvFilterSustain chnget "SG2 Env Filters S"
  iSG2EnvFilterRelease chnget "SG2 Env Filters R"
  
  
  kSG2EnvAmp madsr iSG2EnvAmpAttack, iSG2EnvAmpDecay, iSG2EnvAmpSustain, iSG2EnvAmpRelease
  kSG2EnvFilter madsr iSG2EnvFilterAttack, iSG2EnvFilterDecay, iSG2EnvFilterSustain, iSG2EnvFilterRelease
  aSG2 vco2 p5*kSG2EnvAmp, p4, iSG2wav, kSG2PWM, kSG2Phase
  aSG2FLp moogladder aSG2,kSG2FilterLpF * kSG2EnvFilter,kSG2FilterLpR
  aSG2FHp bqrez aSG2FLp, kSG2FilterHpF * kSG2EnvFilter, kSG2FilterHpR, 1
  
  ;outs aSG2FHp * 0.1, aSG2FHp * 0.1
  aSG2Output = aSG2FHp
  chnset aSG2Output, "SG2Output"  
endin

instr 3
  ; General
  kSG1Amp chnget "SG1 Amp"
  kSG2Amp chnget "SG2 Amp" 

  ; Get input from Layer 1 and 2 
  aSG1Out chnget "SG1Output"
  aSG2Out chnget "SG2Output"
  ; display kSG1Amp, .1, 3
  outs (aSG1Out * kSG1Amp) + (aSG2Out * kSG2Amp) ,(aSG1Out * kSG1Amp) + (aSG2Out * kSG2Amp)
endin

instr 4
;kEnv madsr .1, .2, .6, .4
aOut vco2 p5, p4
outs aOut, aOut
endin
</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
i4 z
</CsScore>
</CsoundSynthesizer>

found it , apparently CSOUND assigns diffirent midi channels to diffirent instr by default this problem can be solved using in this case massign opcode so

massign 1, 4

advice: add the -v option at the command line arguments section in your csd files it make it easier to debug such issues by making the output far more useful and verbose

You are not triggering it correctly from the score. i4 z doesn’t make any sense in this context. i-statements are used to trigger instrument, but you need to pass at least 3 fields,

  • 1: instrument number / name
  • 2: start time
  • 3: duration

In your case you also need to pass it a p4 and p5 value as the instrument is expecting them. The following should work:

i4 0 5 1 220

no idea what you are talking about, what you gave me is a score that playes a specific note, which I do not want. I want both instruments, instr 1, instr 2, to trigger from midi channel 1 and instr 3 I use to mix the output of 1 and 2 and will also use it for generate effects.

instr 4 was just an example, to test why I was hearing no sound.

You asked why instr 4 was not making any sound, I gave you the answer. No instrument can make sound unless it is activated.

but it did make a sound, assign it to midi channels 1 and with score i4 z did make a sound

In the example you posted at the start of the thread it doesn’t make sound. I replied as you were replying with your update, so we got our wires crossed…

one sec, you basically said that the reason why it did not make any sound it was because I had left empty on the score the rest of the parameters of the instrument. Correct ?

however if you test it you will see that indeed it does not require to be passed any other parameters , my assumption here is that because is real time it takes the midi signal as is. If that was not realtime then in that case yes it would not have many any sound because of the lack of arguments.

This happens because in real time CSOUND assigns one channel per instr 1 so instr 1 takes the first channels which is usually the default on, channel 2 goes to instr 2 etc.

Have not solved yet because apparently it can set only 1 instr per midi channel. Which is weird limitation. I found a post in CSOUND mailing list which advise to use event_i from instr 1 to trigger other instruments.

This solution works unfortunately that does not pass the note offs which means each note is pressed and then released it will be released for instr 1 only , taking from midi channel 1 directly but the other instruments triggered by event_i do not stop because I am not passing them a note off. Problem is I dont know how

Time for a new thread ? :smiley:

In your original example instrument 4 was not being activated at all. Sure, if you send MIDI data on channel 4, it will trigger instrument 4, but it has nothing to do with the i4 z in the score. I’m surprised it doesn’t result in an error given z is not a valid start time. Anyway, let’s park it :+1: :rofl:

If you want midi channel 1 to trigger several instruments, why not just roll all the instruments into one? Sure, it’s not as tidy, but it’s not really a major issue either or?

A solution to the event_i thing that you mentioned is to use subinstr which will call a different instrument but then also turn it off when the caller instrument turns off. You can send all MIDI to instr 1 using massign 0, 1 and then test the MIDI channel using midichn. Here’s an example:

<CsoundSynthesizer>
<CsOptions>
-odac -d
</CsOptions>
<CsInstruments>

sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

massign 0 ,1

instr 1
iCPS cpsmidi
iChn midichn
print iChn
kChn init iChn
if iChn==1 then
a1,a2 subinstr 2, iCPS
elseif iChn==2 then
a1,a2 subinstr 3, iCPS
else
a1 = 0
a2 = 0
endif
    outs   a1, a2
endin

instr 2 ; sine
aSig poscil  0.2, p4
outs aSig,aSig
endin

instr 3 ; sawtooth
aSig vco2  0.2, p4
outs aSig,aSig
endin


</CsInstruments>
<CsScore>

</CsScore>
</CsoundSynthesizer>

You can also do the same thing replacing subinstr with a call to a UDO and the sub-instruments with UDOs.

1 Like

damn that is a coincidence I was about to write that subinstr solved that problem for me , was just viewing its documentation

Thank you for the reply :slight_smile:

My inner coder cringes at the idea of stuffing everything inside a single unit , with so many things to add I would rather avoid one massive instr 1 with thousands and thousands of lines of code. At some point will break this up to several csd files but for now its small

In any case subinstr did the trick , thank you guys :slight_smile:

I hear you about wanting to keep things modular, but I’ve found subinstr to be a real cpu drain. UDOs are far more efficient. But you might get away with it so it’s worth exploring at least .

1 Like

oh oh

Well so far Task Manager reports Cabbage from 0.2%-4% usually bellow 1%, general CPU usage also seems to confirm that. So far so good. I am using 2 subinstr from instr 4 which acts as my master for collecting all audio sources and doing the effects and general processing.

It is not about being modular , its about organization and code readability. Plus I do like a well designed code.

UDOs is on my list the only challenge is that I depend on so many parameters although to be fair I could always rely on chnset and chnget. I am a fan of OOP so I try to find a similar workflow with CSOUND.

I will have to test python opcodes at some point, hopefully CSOUND is not affected by the slowness of Python. So many things to learn, so little time. But is fun fun fun :slight_smile: