Cabbage Logo
Back to Cabbage Site

Solution for user-made presets?

Until now, I was happy with using the standard (“snaps”) preset manager built into Cabbage. Now, I am working on an instrument which requires saving a table together with the presets. So I wanted to use the approach by @Retornz with the combobox. I found that the combobox does not ‘populate’. So I dug out an example which I think was working some months ago: PresetManager2 (combobox).csd (2.8 KB) The same there: The combobox always shows ‘(no choices)’ even after creating new .pres files in the subdirectory presets and restarting the instrument.

The combo-box is populating fine here, although the latest file name doesn’t automatically appear. It won’t until you set it to. In this code here, after we save a preset, I send the name of the preset to the combobox. In this case I’m just ending “preset2”. In practice you will need to parse the file name and remove the extension and path. It’s a bit awkward because on Windows paths will made up with \\ while on other systems you’ll be parsing for /.

<Cabbage>
form caption("Presets") size(370, 280), guiMode("queue") colour(58, 110, 182), pluginId("MPre")
rslider bounds(12, 8, 85, 79), channel("att"), range(0, 1, 0.01), text("Att.")
rslider bounds(98, 8, 85, 79), channel("dec"), range(0, 1, 0.4), text("Dec.")
rslider bounds(184, 8, 85, 79), channel("sus"), range(0, 1, 0.7), text("Sus.")
rslider bounds(270, 8, 85, 79), channel("rel"), range(0, 1, 0.8), text("Rel.")

filebutton bounds(12, 190, 60, 28), channel("saveFile"), text("Save"), populate("*.pres","presets"), mode("save")
filebutton bounds(74, 190, 60, 28), channel("openFile") text("Open"), populate("*.pres"), mode("file")

combobox bounds(170, 126, 180, 15) populate("*.pres", "pres") channel("box") channelType("string")
label bounds(14, 108, 336, 11) text("<No Preset>")
button bounds(74, 220, 60, 28), channel("reload") text("reload")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1
gSFileName init 0

;always on and listening for preset updates..
instr 1000
    SSaveFile, kSaveTrigger cabbageGetValue "saveFile"
    if kSaveTrigger == 1 then
        event "i", 1003, 0, .1
    endif
endin

;================================================
instr 1003 ;save presets
    SFile, kFileTrigger cabbageGet "saveFile"

    if strrindex(SFile, ".pres") == -1 then
        SFile strcat SFile, ".pres"
    endif

    fprints SFile, "%f %f %f %f", chnget:i("att"), chnget:i("dec"), chnget:i("sus"), chnget:i("rel")
    ficlose SFile
    
    cabbageSet "box", "value(\"preset3\")"
    
endin

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

P.S. I updated this to use the new guiMode("queue") system…

Thank you for the quick response! I tried your code and it showed the empty combobox again. First, I thought I were under some kind of “spell of irreproducible errors”. But then I saw that in your code files are written to the directory presets but read by the combobox from pres. So if you already have some presets in pres it works but not for me not even having the directory pres and writing new presets into presets.

I will look for my code now and whether it is a similar error.

I got my code running. I added ,"Mpresets" to all populate commands. Anyway, it is better not to clutter the main directory. Just for fun I deleted these additions after creating a couple of presets. Surprisingly it works too. combobox populate searchs recursively?

I believe it might, although it’s probably not a good idea! I think I might add a few simple opcodes for dealing with filenames. It’s a pain to parse filenames in Csound, and the fact that different platforms use different slashes makes it pretty awkward. An opcode that could return just the file name, or just the path, or just the extension would be quite useful I think.

Something like this might be quite useful. We just pass the filename, and we can then retrieve what parts of it we want.

1 Like

How about everything Rory?
I am observing that combobox and listbox when used outside of preconfigured snaps code like the (PresetNamed) example, they again need moving audio to be able to store and read presets. The moment a channel is assigned to it for example and populate is changed to another name, it works fine, but it needs that audio moving.
Respecting the PresetNamed code, it does obey the read and write changes, even if the audio is stopped.
I am using guiMode (“queue”).

It would be great if combobox and listbox could respond with the audio at rest :wink:

Yes, I agree. I’ll look into it. My time is restricted at the moment because we welcomed a new baby girl into our family last week :wink: I’ll let you know when I get around to this :+1:

1 Like

Congratulations! And to enjoy the baby. My best wishes :hugs:

1 Like

Hi @Gerbo, I’m just getting around to this now.

Do you have an example? Do you mean when using the old way of saving generic presets, as shown in this example?

It is to work with combobox or listbox, without running audio and without .snaps. With .snaps if it responds correctly as usual. Using it for example as a playlist for any other use, you need that audio to be active.

I can recreate this here. Leave it with me. Thanks.

You can see, that with the traditional method “.snaps” it is active :+1:, but the combobox with individual presets does not respond if it is inactive.

These tests are carried out with the latest version of Cabbage 2.8.17

Thanks @gerbo, is there any chance you could send me the two instrument .csd files you use above? I think that would help. Right now I’m still a little confused :laughing:

The thrill of being a dad again :wink: How’s everything going @rory?
The tests are done with the examples: Presets and PresetsChannels
TestCombobox-pre-snaps.zip (6.3 KB)

Exactly. everything is confusing to me these days :laughing:

Thanks for this, I am able to recreate it :+1:

So I can’t run Garageband through the XCode debugger :rage:

In summary, I can’t use the Apple development tools to debug a plugin written using an Apple SDK, in a host that is produced by Apple. Wow. They never fails to amaze!

I’ll have to download a trial version of Logic as I don’t have it this machine…

Wow! these from Apple … :upside_down_face:
If you have Cubase, you can recreate it too. It does the same as in Logic.

Thanks, I’ll try Cubase :+1: