Cabbage Logo
Back to Cabbage Site

Handpan synth - Ever-increasing CPU usage

Hi everyone,

I’ve been tinkering with Csound for a few months, trying to learn by hacking, but finally decided to ask for help here :slight_smile:

I’ve been working on a handpan synth to play with a pad controller. I found a great patch through this linuxmusicians thread (hosted on http://juliencoder.de/sound/index.html). After trying to reproduce it in languages that I know better (mostly Pure data) and failing to reach the same sound quality, I am now building a VST plugin with Cabbage to use this synth in a DAW, ideally with presets for each scale (the initial patch requires editing/commenting out the giNotes variable definitions).

Here is what I have so far: handpan_cabbage_test.csd (12.6 KB)

However, even before trying to switch scales, I’m noticing that the CPU usage increases slightly with each MIDI note I play, eventually causing performance issues and dropouts. This happens both in CsoundQt and in Cabbage.
Following advice from this form thread, I’ve implemented an always-on instrument which is confirming that kinstr is increasing with every MIDI note played (and never decreasing), so one instrument seems to be running forever while also being re-triggered for every note.

As far as I could see from various csound tutorials and manuals, the instrument setup for this handpan is not really following the standard way of defining an instrument. The way I understand it:

  • When the patch starts, the "Setup" instrument is triggered with a duration of 0.1s
  • Setup reads the number of notes in giNotes[] and creates one (always-on?) Tine instrument and one Resonator for each iNote.
  • upon MIDI input, a Strike instrument is created for the note, which again uses the corresponding Tine and Resonator instrument instances.

I have added printf() commands at the end of each instrument to visualize when they stop running, and it looks like Tine and Resonator finish right after being set up by Setup, while each Strike starts and stops upon a MIDI note input. So I can’t figure out how Tines and Resonators actually run, and which instrument(s) are counted with kactive active kinstr - but I feel like there is something basic I don’t grasp in how Csound instruments work, although it may be trivial for someone knowing csound a bit better, hence my question here :slight_smile:

I hope someone can help me understand how this actually works and guide me to improve the performance! Thanks in advance :grin:

(spoiler: next questions in other threads will be on how to actually change the scale as selected in the UI dropdown, how to store the scale as a preset that can be stored in a DAW between sessions, and how to show feedback on the UI - but first things first!)

Hello Zig,
It works fine here.
(In Cabbage and Cubase 5 / Win 7)
No increase in CPU performance unless I press the sustain pedal.
Then the triggered notes are held until the sustain is released.
Maybe you could switch off the voice with ‘turnoff’ when the sound has finished?
Have you checked with a midi monitor whether a NoteOff is sent for every NoteOn event?
best regards
jockel

Aaaah but indeed, thanks a lot @jockel!!
I’m actually routing the controller’s MIDI input through a small program I wrote 2 months ago (to map the pads to the handpan scale’s notes and light them up with the corresponding colors) and you are right, it does not route NoteOff events through! :man_facepalming: - which also explains why I didn’t notice this issue when I first tried the csd patch last year.
I’ll fix that this evening, and then I’ll move on to the other questions!

That said, are you able to confirm (or not) my understanding of how the patch works, especially with regards to the Tine and Resonator always-on instruments?

…just skimmed the code, seems to be some kind of physical modeling where the instrument ‘strike’ only delivers a short impulse and thereby stimulates ‘tine’ & ‘resonator’ to vibrate (like a stick hitting the drum)
I’m not sure, but I could imagine that tine and resonator would run constantly and strike only for a short time.
So ‘tine’ would perhaps describe a specific note on the hang drum and ‘resonator’ the whole drum.
Therefore you would probably have to change the scale not in the instrument ‘strike’ but in ‘tine’ & ‘resonator’

oh wait - that’s what instr ‘Setup’ already does :thinking: (changing the scale)
You could propably change the scales in your (always running) ‘instr 2’
maybe somehow like this:

> instr 2
kinstr init 1 
kactive active kinstr 
printk2 kactive 

    Sarr[] fillarray "scale_selection"; 
    Stest, kTrig cabbageChanged Sarr; another scale selected ?
    if kTrig == 1 then
        knew cabbageGetValue "scale_selection"
        event("i","Setup",0,.1,knew)
    endif 

endin

So, once I fixed the NoteOff issue (interestingly, if the NoteOff comes less than ~50ms after the NoteOn, I get some high-frequency harmonic ring, I’ll have to look into it to understand better), it turned out that the scale selection that I implemented (in a very similar way as you propose) in “Strike” does work :slight_smile: although it is probably nicer to have it run in a separate instrument like “instr 2” and to use cabbageChanged rather than change the scale once the new MIDI note comes in, I’ll try that.
Thanks!