Cabbage Logo
Back to Cabbage Site

New synth beta : Morpheur


Here is a beta version of my new cabbage synth. I would be very very grateful if any of you could try it and provide feed back. Bug report is welcome.

This synth only works with CABBAGE 2. The GUI will be messed up with cabbage 1.

This synth aims mainly at making pads / ambient sounds but thanks to FM it can also bring interesting spooky sounds.

Characteristics :

  • Single morphing Osc with sub-Osc . FM and Ring modulation also possible.
  • Envelope
  • Filters with envelope and LFOs. Filtered audio can benefit of its own audio envelope.allowing effects.
  • Reverb, Echo, Chorus and Flanger
  • Preset saving function

How does it works ?
You need to load 3 single cycle waveshapes (.wav files). A lot of them can be found there : (many thanks to the author of these).

In order to use the presets included in the zip file, Adventure Kid Wavshapes must be installed in a directory named “WaveShapes” in the directory containing the Morpheur.csd as follow :

---|  Morpheur.csd

If your installation is different, you have to manually edit the snaps files and modify the path to the waveshapes.

These wav shapes can be all the same or different. The two first one are using for morphing sound from the first one to the second one. The third one is used to FM the the pitch of the two first ones. In order to not use FM, put the encoder Freq Mod to 0.

How can you help?
If you find a bug or find a better way to do the things (CPU saving or better way implementing the functions)
If you find nice sound using the adventure kid wavshape, please share the preset.
If you play keyboard, please share a little audio demo.

Known bug
Among other things there is something weird with the midi : from time to time a note plays for ever. There is a way to stop it playing : etiher click on Panic button or if playing with real keyboard, play the note pressing slowly the key (trying to have a velocity almost 0 and release it also very slowly)

Special thanks to @iainmccurdy and to @rorywalsh who have helped me a lot with their advices, teaching, tutorials and who always have shown a great patience. If this synth is worth it, then it is dedicated to both of them.
Special thanks to @t_grey and @gsenna for reporting bugs.

update :
09/28/17 : fixed mixing audio /filter bug
10/05/2017 : implemented Host sync for morphing frequence, rei-mplemented Echo and Reverb for decreasing CPU usage. Also uploaded some presets. Some controller knobs message can be received (at least from alesis keyboards)
10/14/2017 : Minor bugs corrected. Binaural opcode implemented. Initial wavforms loadd at start.
You’ll need to copy "hrtf-44100-left.dat" and "hrtf-44100-right.dat" from your Csound example (\Csound6_x64\doc\manual\examples).
Provided that the wavshapes are stored in a directory called WaveForms under the directory hosting the morpheur synth, it will automatically load 3 initial wavforms.
10/17/2017 : Minor bug in table order corrected

11/08/17 : NEW Release. This is the final version (even if it is still beta). What is new :
A lot of improvements in the code (clearer, cleaner).
Some controls (N°20 : Morphing frequence, 21 and 22: FM and 31:Main Gain) work if your keyboard has some programmable knobs
Also if your keyboard allows it, you can play with aftertouch. (I did it with a Roland A-49 thanks to control knob)
Everything is in a zip file. Unzip it somewhere, and open it with Cabbage.
You can export it as a VST, if so do not forget to copy in the VST directory the others files (binaural files, snapshot, and wavshapes) in order to retrieve your presets.

( Note: you need the very latest cabbage from github as previous version had troubles with pathname, see this post for compiling it)
At start, the Morpheur loads automatically 3 wavshapes so you can play.

11/19/17 : Final version of Morpheur is released ! Thanks to the great help of @rorywalsh, there is no memory leak anymore.
As it is possible to use the waveshape for Adventure kid, Morpheur is available on github now. Simply clone or download the zip file. Extract the zip containing the waveshape in the same directory and you are good to go…

Here the link :

1 Like

Thanks for sharing this Karamel, but at the moment, with Cabbage 2, my GUI looks like this:

Hello Iain,

Very strange. Did you install the very last version ?
Rory has uploaded it but I don’t know where…
Here is a link to the package I prepared:
Please could you tell me it it works better ?

Hummm I have the feeling that you are under linux… Should it be the reason ? Here is how it looks under windows.

Built & tested on Fedora 21, works fine in Bitwig 2.1.1, no trouble with the GUI or anything else so far.

Thank you @davephillips !
Please tell me if you encounter audio playing for ever, even if the note is off. I have it under windows and I am not able to see where this comes from.

With an old Cabbage 2 version I get the same in Ubuntu Studio as Iain. If I connect my keyboard to it and press a note I have ton of errors in the Csound console, which ends with “note deleted. instr 1 had 16 init errors”.

I’ll rebuilt Cabbage next week and see if I can help you debug it.


Indeed, you get errors when there is no wavshape loaded.
First thing to do is to load 3 wavshape into the 3 soundfilers.
I built the git version of cabbage on linux mnt (debian based distro) today. The GUI of Morpheur works like a charm. But I could not test the sound I would need to install all pain_in_the_neck Jack and subsequent configuration.

On the more recent build for MacOS it looks fine. Sounds good too!

Thank you @iainmccurdy !
Should you have little time to play with it and design a sound with it… I would be very happy to hear it.
Also, do you see “anything” missing or somthing which could be better implemented ? I am really keen on learning from the master :slight_smile:
Found a bug in the mixing the filtered / non-filtered signal. I just updated the first post of this thread with new version fixing this.

One thing that might prove useful would be loading 3 default sound files on startup. It might prevent some confusion.

Hello Rory,
Indeed that would be great. I’ll try to implement it.
So far, all my trials did not succeed.
If I create a simple instrument called only once at init time i "initFIle" 0 0 which aims at initiating the gSfilePath variables, it indeed loads the 3 files into soundfilers… but afterwards, the preset combobox becomes unresponsive…

All the rest I tried did not work.
I may come to a very simple csd to discuss this further on and find a clean solution.

Sounds like a good idea.

Hello Rory,
it seems that there is something weird with path and \ symbol in last build I made. The console does not show these symbol.

I also attach a simple csd for showing the trouble with combo preset / soundfiler and init phase.

In order to show the trouble :

  • change the code to init the string with valid file name to populate the soundfiler in the following instrument

    instr InitWav
    chnset “AKWF_0212.wav”,“filenameOscA”

Start the instrument. It shows the init wav file
then load another file into soundfiler and save the preset, you can make a few preset.

Stop and Quit the instrument.
Restart it, there should be an init file loaded and few preset available.

Try to load one of the preset : the preset are not loaded, only the init file is present.
Maybe I do something wrong but I don’t see what.

cabbage_soundfiler.csd (3.2 KB)


Thanks, I also see the issue. It will be next week before I get a chance to look into this. I would like to know if this actually ever worked? I don’t have time now, but perhaps you could try building an earlier version and see if it ever worked? I fear it may never have actually worked…

Hello Rory,
Do you have any idea the date of the version I should try to rebuild ? I will do it.
Also, I will open a new thread to list bugs as of the last package I built.

I don’t. Do you think this ever worked?

I don’t think so.

In that case you needn’t bother looking back in time :wink: I hope to get a chance to look at this tomorrow.

I can’t figure out why your code doesn’t work. I wonder if Csound is somehow preventing the string channel from updating. The few things I did try have led me to segfaults in the Csound source code. I did find a workaround. I’ve posted the relevant bits below. Be sure to update your file path. Basically what I did was replace the INIT instrument you had, and simply called the “LoadSoundFile” instrument on startup, passing the initial soundfile as a p-field. I also updated the subsequent calls to that instrument whenever event is used.

I’ll have to dig deeper into the reason it’s not working but I think it may have something to do with the fact that all strings in Csound are technically i-rate, which is why one needs to use special opcodes to update them. Otherwise we could just use the assignment operator ‘=’. Somewhere in my head is the answer I think. I just need to spend some time there searching for it :joy:

gSfilepathOscA init ""

instr	LoadSoundFile	; load sound file
SFilePath strcpy p5
    if p4 == 1 then
   ;     Sfile strcpy gSfilepathOscA
        if filevalid(SFilePath) ==1 then
             gitableOscA	ftgen	901,0,0,1,SFilePath,0,0,0		; load sound file into a GEN 01 function table 
             gichansOscA	filenchnls	SFilePath			; derive the number of channels (mono=1,stereo=2) in the sound file
             giReadyOscA 	=	1					; if no string has yet been loaded giReady will be zero
             gkTabLenOscA	init		ftlen(gitableOscA)/gichansOscA		; table length in sample frames         	
             Smessage sprintfk "file(%s)", SFilePath			; print sound file to viewer
             prints Smessage
             chnset Smessage, "filerOscA"
            printks "File no valid \n",0

instr 2 
;- Region: Load soundfile 
 if changed:k(chnget:S("filenameOscA"))==1 then 
     gSfilepathOscA	    chnget	"filenameOscA"
  kNewFileTrg1  changed	gSfilepathOscA	    ; if a new file is loaded generate a trigger
  if kNewFileTrg1 == 1 then		; if user has requested a preset or new file...	
    String  sprintfk {{i "LoadSoundFile" 0 0 1 "%s" }}, gSfilepathOscA
    scoreline String, 1     
  if changed:k(chnget:k("PresetCombo"))==1 then
    SfilepathOscA	    chnget	"filenameOscA"
    String  sprintfk {{i "LoadSoundFile" 0 0 1 "%s" }}, gSfilepathOscA
    scoreline String, 1  

;causes Csound to run for about 7000 years...
i "LoadSoundFile" 0 0 1 "/home/rory/Desktop/shortSample.wav"
i 2 0.01 z

That is indeed a work around !!! :grin: Thank you !
It is difficult to understand. Please tell me if I am wrong.
What is done is to write force loading the soundfile as a score line whenever this is appropriate, exactly as it would happen at the init time… Right or Wrong ?