Cabbage Logo
Back to Cabbage Site

Some beginners questions

[EDIT] I’m moving this user question by @Eddiz to a relevant thread…

Hey Rory,

I was looking for possibilities of creating own VST (Juce ect.) and found your amazing Cabbage!
First i want to notice, i am not a coder, but i did some Kontakt instruments and i am familiar to NI Ksd (i am seeing some similarities with Cabbage)

I have been studied your Docs/Videos/Forum for a couple of days and have some questions.

I am looking for ways to make commercial (or maybe at first non-commercial) VST and i have a couple ideas:

  1. Sampler similar to Kontakt (or some kind of rompler)

  2. Simplified version of Cthulhu VST (example: i play one note and on midi out there are a 5 note chord)

  3. I saw you were talking about Cabbage Pro licence or something for commercial releases. Can you explain on this.

Can you guide me where to start? Maybe there are examples of these or something…

I checked a lot of examples but did’t find something similar.

Thanks a lot!
Edgar

Should be doable, you’ll need to work with file formats supported by the libsndilfe library. Btw, if you particularly interested in creating samplers, you might look at HISE. It looks like a nice project for building samples.

This is quite simple to do. Check out this MIDI out example.

The pro version of Cabbage allows you to encrypt your .csd files so end users can’t read them. Apart from that it’s the same as the public version. One license covers you for as many plugins as you want. PM me for details on the cost.

Note that any Cabbage user can sell their plugins without buying any pro license or making any contribution to the project. But the plugin will have to be GPL, which means the Csound code will need to be shared too. My advise for now would be to simply build your plugin. If it gets to a stage where you think you might want to sell it without, sharing your Csound source code, you can come and talk about a Pro license.

Thanks Rory,

I will start with easier one (MIDI Cthulhu type plugin).

I checked MIDIArpSimple example and some others and tried to make something.

<Cabbage>
form caption("MIDI Out"), size(400,120), pluginid("Mout")
keyboard bounds(0,0,400,80)
combobox channel("heythere"), bounds(100, 20, 50, 20), items("1", "2", "3", "4")

</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-dm0 -n -+rtmidi=NULL -M0 -Q0 --midi-key=4 --midi-velocity=5
</CsOptions>
<CsInstruments>
sr 	= 	44100
ksmps 	= 	16
nchnls 	= 	2
0dbfs	=	1

instr	1

; Combox(presets).

kCombo chnget "heythere"

if (kCombo = 2) then

printk2 kCombo

endif

if (kCombo = 3) then

printk2 kCombo

endif

; MIDI chords2.

iNum notnum
   print iNum  
     
if (iNum == 2 && kCombo == 2) then


kNoteIndex  = p4
kNoteIndex2 = p4+3
kNoteIndex3 = p4+5

   
        midion 1,kNoteIndex, p5
        midion 1,kNoteIndex2, p5
        midion 1,kNoteIndex3, p5
        
      printk2 kNoteIndex
      printk2 kNoteIndex2 
      printk2 kNoteIndex3 
        


; MIDI chords3.

elseif (iNum == 3 && kCombo == 3) then


kNoteIndex  = p4+10
kNoteIndex2 = p4+13
kNoteIndex3 = p4+15

   
        midion 1,kNoteIndex, p5
        midion 1,kNoteIndex2, p5
        midion 1,kNoteIndex3, p5
        
      printk2 kNoteIndex
      printk2 kNoteIndex2 
      printk2 kNoteIndex3 
        
endif      
       
endin

</CsInstruments>

<CsScore>
#define SCORELEN #86400#
i 101 0 $SCORELEN
f0 z
</CsScore>

My goal is to made VST plugin with these functions:

  1. One note tigers a chord (there are 20 notes per preset). Also only one active MIDI note at once.
  2. There must be 40 presets
  3. All notes form the chord must be highlighted on the keyboard
  4. User should see played chord name
    5)There must be an additional transpose combobox.

And i have several questions:

  1. Am i going in the right direction in general? Or there is an easier way to do this … Or maybe there are some stupid thing in my code…

  2. What is the practical difference between midion and midion2

  3. Do i need to use changed opcode with if statements? If yes, why?

  4. In DAW sometimes the MIDI signal is not killed when pressing another note.

  5. What is the meaning of CsScore?

    #define SCORELEN #86400# i 101 0 $SCORELEN f0 z

I managed it to work but can’t find what it means…

6.Any thoughts on how to easier implement 3), 4) and 5)

Yeah…i know there are a lot of questions!

Hope you can help me with these…

Thanks

Edgar

It looks like you’re trying to run before you can walk here! I’d recommend you start with a very simple task such as number one on your list:

Did you get this much to work?

I think midion2 waits for a trigger signal before it outputs a MIDI note?

Only if you want to test is something has changed. If not you can do a straight test with k-variables, i.e,

if kVal == 1 then

You have to be sure that you kill each note, but it should be done automatically. In the past when I had issues with this I was able to simply send a delay note-off messages to kill it.

The section of the .csd file starts the performance going. You can read more about it here.

Try the first task again and let us know if you are having any problems with it. Good luck!

Thanks for the answer,

I think i already made 1) and 2). And it seems it is working.Only with less presets. And maybe the code could be more effective. It uses 7% of i3 CPU.

if (iNum == 2 && kCombo == 2) then


kNoteIndex  = p4
kNoteIndex2 = p4+3
kNoteIndex3 = p4+5

   
        midion 1,kNoteIndex, p5
        midion 1,kNoteIndex2, p5
        midion 1,kNoteIndex3, p5

As for 1) and 2) i am planning to write a lot of combinations:

iNum == 1 && kCombo == 2
iNum == 2 && kCombo == 2
iNum == 3 && kCombo == 2
ect…
Than jump to the next prest

iNum == 1 && kCombo == 3
iNum == 2 && kCombo == 3
iNum == 3 && kCombo == 3
ect…

I doubt of the efficiency, but that are all my ideas for now…

You might be able to reduce the number of if statements but I wouldn’t worry about it too much for now. Does it run 7% of your CPU in Cabbage, or when hosted with a DAW? If you share your full code I can take a look.

(7% of CPU hosted in DAW)
But I tried it on other PC and it seems using only 1%

Full code: MIDItest.csd (1.3 KB)

I removed from score
#define SCORELEN #86400#
i 101 0 $SCORELEN

(i found those in example and thought it is necessary but it seems it’s not)

I want to make working prototype with all functions and only then add all chords, presets and graphics.

So now i am looking how to implement about 3)4)5)

:slight_smile: thanks!!!

I don’t see anything here that would cause any CPU load? Might just be the system. You use the notnum opcode to get the MIDI note number, but you don’t need to. p4 will always be the current MIDI note number. So you want a different outcome depending on the incoming note, or simply the preset? Or both?

Thank You!

Both.

For example:

If I select 2 preset form combobox and press C key - output Cm chord is playing
If I select 2 preset form combobox and press D key - output Em chord is playing
If I select 3 preset form combobox and press C key - output Am chord is playing
If I select 3 preset form combobox and press D key - output Fm chord is playing

And i think my current code is doing that.

The problem is - i need to implement transposing. And if add transposing to previous example

and set it for example to -2 (two semitones)

If I select 3 preset form combobox and press C key - output should be Gm chord = Am chord transposed by 2 semitones

Can’t you simply apply a transposition factor when you are creating your notes?

kTrans = -2
kNoteIndex  = p4+kTrans
kNoteIndex2 = p4+3+kTrans
kNoteIndex3 = p4+5+kTrans

Yeah, i think this should work…thank you

And control kTrans with another combobox…i should invent this myself…

Cool.

Now 3) and 4) left :slight_smile:

  1. All notes form the chord must be highlighted on the keyboard.
    Should i simply add keydowncolour() to keyboard parameters?

  2. User should see played chord name
    Should i use textbox widget? Not quite sure how to implement it…

That will set the colour of the held notes. And they should show as held for as long as you are outputting them. If not, we’ll have to come up with another solution…

You can just use a label. Its text can be set dynamically while your instrument is running. Just use identifier channels. Should be easy to implement.

  1. Didn’t try this with MIDI keyboard, but as i understand now… if i press C key for example, it will set the color for this particular key, but not for all keys within the chord (MIDI output). and i need to change the color for all outputed MIDI notes (chord)…

  2. Tried to figure it out… made something like this:

    label bounds(110, 140, 165, 62) identchannel(“chord”)
    SIdentifier sprintfk “text(”%s")"
    chnset SIdentifier, “chord”

But totally stuck. can find the proper formatting…

Try this example, you were missing a parameter for the sprintfk opcode.

<Cabbage>
form caption("Untitled") size(400, 300), colour(58, 110, 182), pluginid("def1")
keyboard bounds(8, 158, 381, 95)
label bounds(64, 10, 260, 37), identchannel("label1Ident")
</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
instr 1
SIdentifier sprintfk "text(\"%d\")", rnd(100)
chnset SIdentifier, "label1Ident"
endin

</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
</CsScore>
</CsoundSynthesizer>

This may need some work. To be honest, I’m not sure what the current behaviour is. But it’s not a deal breaker. I’m sure we can find a solution.

  1. Yeah, i know i missed, just didn’t know to to enter there…
    as i understand i need to use %s

    Stext strcpyk “Hello, world !”
    SIdentifier sprintfk “text(”%s")", Stext
    chnset SIdentifier, “chord”

I think something like that… but it is not working…

  1. Ok. i will test it with MIDI keyboard

Your code is working fine for me here. Note that you need to actually play a note for the updated text to appear…

Got it. Thanks.
Update on 3) it colors only one (not all notes from the chord :confused:) when sending MIDI signal.

Hmm, Ok. That’s not ideal. Were you hoping to show the pressed notes as an educational aid?

Yeah, as i mentioned i want to make something like Cthulhu (i made a lot of presets for Cthulhu and want to convert them into new VST).
And yes, is is very beneficial for users to actually see all the notes form the chord…

I just checked it out. So here we have an issue in that Cabbage can’t use the same keyboard for input and output. You have two options then.

a) create your own keyboard component that is only used for displaying chord positions. To do this you would use a collection of images, or a picture of a keyboard, with transparent overlays on top. When users trigger a chord these overlays are updated. If all of your chords are voiced relatively closely this option would be fine. But if you have huge internals in your chords, it won’t be possible to scroll up and down the keyboard range without some serious Cabbage wizardry.

b) I can look at adding a new keyboard widget especially for display purposes. It would probably offer more than the solution above, but I can’t say how quickly I can get around to introducing this new widget. It could be a week or two. This widget wouldn’t be connected to any MIDI signals at all. It would just be for displaying notes.