Cabbage Logo
Back to Cabbage Site

Continuous display of audio data

Thanks, I tried it but the issue with this solution is that the triggers need to occur when metro(20) is triggered, right?

For example, if I move quickly the hrange, the label is not updated. But when I hold the mouse and move slowly, I can see the numbers being updated.

EDIT: the bug is still occurring in the broader context of my plugin, maybe because every cabbageSet needs to be edited this way?

I’m not seeing that? The samphold chokes the frequency of the updates, but the changed opcode should ensure the values are sent to the UI. I did it this way so we’re not calling cabbageSet on each k-cycle, or every 20 times a second, even if no changes have occurred. Here’s my simple test in full:

<Cabbage>
;---------- ; container ;----------
form caption("Bug") pluginId("AS14") size(840, 500), guiMode("queue"), colour(200,200,200)

label bounds(35, 288, 178, 22) channel("leftEqValue") text("[eq mode deactivated]") ,fontSize(24), fontColour(0, 0, 0, 255)

hrange bounds(34, 268, 176, 27), channel("FreqMinAttack", "FreqMaxAttack"), _info("Frequency range of the attack transient shaping (uses a bell curve)"), range(1, 25000, 1:400, 0.3, 1) valueTextBox(0) trackerBackgroundColour(0,0,0,0) trackerBackgroundColour(0,0,0,0) colour(20,20,20,0) outlineColour(100,100,100) trackerThickness(2) outlineColour(100,100,100) trackerThickness(2)

gentable bounds(266, 160, 300, 71), tableNumber(1), fill(0), channel("table1"), tableGridColour(152, 0, 0, 0) tableBackgroundColour(15, 15, 15, 0) tableColour:0(255, 255, 255, 255)

</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --displays 
</CsOptions> 
<CsInstruments> 
ksmps  =  64
nchnls =  2
0dbfs  =  1

opcode ScrollTable, 0, aikiS
    setksmps 1
    aSig, iTable, kRate, iScrollPoint, SChannel xin
    kSig = aSig
    kCnt = 0
    kIndex linseg 0, 3.7, ftlen(iTable), 0, ftlen(iTable)
 
    if metro(kRate) == 1 then
        tabw kSig, kIndex, 1
        if kIndex == ftlen(iTable) then
            while kCnt<ftlen(iTable) do
                kSample tab kCnt+1, 1
                tabw kSample, kCnt, 1 
                kCnt+=1
            od
        endif
    endif
    
endop

instr drawGentable
    cabbageSet      "table1", "tableNumber", 1
endin

instr 1

    ; --- values
    kFreqMinAttack, kMinEqAttackTrigger cabbageGetValue "FreqMinAttack"
    kFreqMaxAttack, kMaxEqAttackTrigger cabbageGetValue "FreqMaxAttack"

    StxtEqAttack sprintfk "[%d Hz - %d Hz]", kFreqMinAttack, kFreqMaxAttack
    ; test 1
    kUpdate  = changed:k(samphold:k(max(kFreqMinAttack, kFreqMaxAttack), metro(20)))
    cabbageSet kUpdate, "leftEqValue", "text", StxtEqAttack
    
    if metro(1) == 1 then
        event "i", "drawGentable" , 0, 0.0008
    endif

endin 

</CsInstruments>

<CsScore>
i 1 0 [60 * 60 * 24 * 7] 
f1 0 256 7 0 256 0

</CsScore>

Yes, for sure.

Ok it works for me! I made a mistake and used the trigger instead of the value in this line (kFreqMinAttackTrigger and kFreqMaxAttackTrigger instead of the actual values):

kUpdate = changed:k(samphold:k(max(kFreqMinAttack, kFreqMaxAttack), metro(20))

It works well, thank you so much!

Regarding this issue, do you think I need to add the samplehold trick to every cabbageSet on buttons?

e.g.:

kEQModeAttack, kEQModeAttackTrigger cabbageGetValue "EQModeAttack"
cabbageSet kEQModeAttackTrigger, "leftEqValue", "text", "[eq mode deactivated]"

Where EQModeAttack is a button.

I think it’s not useful since it will be triggered exactly one time but I want to double check with you.

By the way how did you find it was because of cabbageSet? If it’s easy to set up I can maybe try it for the next time I spot an issue.

I’d agree. It’s only really required where there is a chance of users going crazy with the mouse.

Thanks. For my csound knowledge, how would you adapt the code for a button? Also with samphold? I tried to do it but I can’t find an elegant way to do it… With the same approach it looks like it updates the value exactly when metro() and the kTrigger are triggered at the same time.

Sorry for this dumb question but it’s the first time I’m using samphold() so I’m still trying to see how to use it properly.

Sorry, maybe I wasn’t clear, I don’t think you need to use this approach for a button. Your code should be fine, i.e:

kEQModeAttack, kEQModeAttackTrigger cabbageGetValue "EQModeAttack"
cabbageSet kEQModeAttackTrigger, "leftEqValue", "text", "[eq mode deactivated]"

Is there an issue with this approach?

I wanted to use the same approach for this code:

SWidgetName, kTrigger cabbageGet "CURRENT_WIDGET"
SInfo cabbageGet SWidgetName, "_info"
cabbageSet kTrigger, "labelinfo", "text", SInfo

When the mouse is over a widget, I display some information in a text box. Since the user can move the mouse very quickly, it can raise the same errors/issues.

Since this time I’d like to use kTrigger, I was wondering what could be the best way to do it. I think I could increment a global variable everytime kTrigger==1, then use the same code with samphold and changed, but it looks dirty.

Here is my code:

kIncrementWidgetChanged init 0 
SWidgetName, kTrigger cabbageGet "CURRENT_WIDGET"
SInfo cabbageGet SWidgetName, "_info"
kIncrementWidgetChanged = kIncrementWidgetChanged+kTrigger

kUpdateWidgetInfo  = changed:k(samphold:k(kIncrementWidgetChanged, metro(20)))

cabbageSet kUpdateWidgetInfo, "labelinfo", "text", SInfo

EDIT: Even after implementing these changes, there are still some crashes. I’ll reduce the “metro” rate and see if it helps.

EDIT2: Removing the gentable fixes the issue. I left the plugin running for 1hr and no crash.

Thank you