Cabbage Logo
Back to Cabbage Site

Linking gentable displays

Ok, I’ve got data that has two dimensions and as such, I would like to be able to link two gentables together, such that they share the same magnification and scrolling. Essentially, this would create two tables that share the same attributes as well as scroll bars and magnification buttons.

I was also thinking it would be nice that when the mouse is over the data that it could display the y-index along with the x-data at that location in the file.

Thanks, this is a lot of fun!

You can overlay table on top of each other. Would that work?

I’m going to looking into that. Just set one waveform to another color. It would also make it easier to see how the data lines up.

Also, because these tables are quite large, I can only zoom in so close, and I think the most I could enlarge, you still have a hard time seeing individual points. Can I use samplerange to view just a portion, and then update the view with little or no noticable shifting? How might you signal to the CSound code to trigger this update?

How large? Larger tables are better handled using the soundfiler widget, which can actually load gen tables too. The don’t look at nice, but they are much faster.

Yes, this should work. @Stefan has been working with something similar lately. He’s being loading lots of soundfilers and using sample range to zoom in and out rather than the inbuilt controls. Let’s ping him and see what he thinks :wink:

I’m generating data on the fly, so I’m not sure if soundfiler is an option. I do eventually plan to allow loading external data files, but currently is just random and fractal data.

I’m trying to create a tool for sonification techniques, and would like to include data analysis tools to determine points in the data that might be related (fractal data can be repeatative, but those repetitions have their own variations). In effect, it will be a realtime version of CMask.

And how large will the data be? Dynamically changing the size of a gentable might be a little slow. But I guess there is only one way to find out :rofl:

I’ve created some tables that are 65K, but I was thinking about trying some larger. While I’m not using the data to directly generate audio, it is used to generate control data for the audio. Eventually I’d like to be able to control granular synth instruments in real time, but currently all it does is generate midi and control for an internal CSound instrument.

1 Like

Thanks again, Rory. I didn’t realize that you could put more than one wavetable into the gentable. Very useful. I’m also thinking of using another gentable with a much smaller size for a sort of magnifying glass into the table.

OK, Here goes… What I’ve got so far on these tests…

<Cabbage>
form caption("Untitled") size(600, 400), colour(58, 110, 182), pluginid("def1")

gentable bounds(28, 16, 500, 136) tablenumber(1, 2) amprange(-20, 20, 1, 1) tablecolour:1(255, 0, 0, 255) tablecolour:2(0, 255, 0, 255)
gentable bounds(28, 200, 500, 136) tablenumber(1, 2) amprange(-20, 20, 1, 1) samplerange(0, 127) tablecolour:1(255, 0, 0, 255) tablecolour:2(0, 255, 0, 255) identchannel("magnifyer")

nslider bounds(28, 350, 60, 24) channel("vieworigin") range(0, 8192, 0, 1, 1)
nslider bounds(88, 350, 60, 24) channel("viewsize") range(0, 8192, 255, 1, 1)
button bounds(150, 352, 20, 20) channel("viewlock") latched(1) text("") colour:0(64, 64, 64, 255) colour:1(200, 40, 255, 255)

</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d 
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

giLatoo[] fillarray -0.966918, 2.87988, 0.756145, 0.744728, 0.1, 0.1

opcode latoo2, ii, i
    ix xin
    iA = giLatoo[0]
    iB = giLatoo[1]
    iC = giLatoo[2]
    iD = giLatoo[3]
    iX = giLatoo[4]
    iY = giLatoo[5]
    iNx = sin(iY * iB) + (iC * sin(iX * iB))
    iNy = sin(iX * iA) + (iD * sin(iY * iA))
    giLatoo[4] = iNx
    giLatoo[5] = iNy
    xout iNx, iNy
endop

;; this is the root instr for controlling the gui
instr 1
    iLen1 = ftlen(1)
    iLen2 = ftlen(2)
    iCount = 0
    prints "iLen1: %f iLen2: %f\n", iLen1, iLen2
    until iCount > iLen1 do
        iX, iY latoo2 1
        tableiw iX, iCount, 1
        tableiw iY, iCount, 2
        ; prints "iX: %f iY: %f\n", iX, iY
        iCount = iCount + 1
    od
endin

instr 3
    kVsize chnget "viewsize"
    kVorigin chnget "vieworigin"
    kVlocked chnget "viewlock"
    
    kTrig metro 1
    if kTrig == 1 then
        printks "kVsize: %d kVorigin: %d kVlocked: %d\n", 0, kVsize, kVorigin, kVlocked
    endif
    if changed(kVsize, kVorigin) == 1 then
        if changed(kVlocked) == 1 then
            if kVlocked == 0 then
                chnset kVorigin + 255, "viewsize"
            endif
        endif
        if kVlocked == 1 then
            kVsize = kVorigin + 255
            chnset kVsize, "viewsize"
        endif
        Smessage sprintfk "samplerange(%d, %d)", kVorigin, kVsize
        printks "%s\n", 0, Smessage
        chnset Smessage, "magnifyer"
    endif
endin

</CsInstruments>
<CsScore>
f1 0 8192 -10 0
f2 0 8192 -10 0

i1 0 z
i3 0 z

</CsScore>
</CsoundSynthesizer>

Just a quick rundown. The top gentable displays the whole waveform. The bottom gentable displays a portion of the waveform as selected by the bottom two number sliders. If the button next to them is turned on, it locks the size of the function displayed in the bottom window to 255 samples, thus scrolling through the whole function table with a constant size.

And does this work Ok? I didn’t have time to check it here. Btw, you might want to consider using guiMode(“queue”) and the new cabbage opcodes widget. There are faster, and probably a little cleaner. With them you no longer need to define identchannel. More info here

So far so good. Everything seems to do what I hoped it could do. Now it’s just a matter of working these things into the real program.

1 Like

Hey Rory, thanks for connecting.
I was off for some days looking into different stuff.
Hi mjmogo,
Seems like you’re working it out. Don’t know how much I could be of help here anyway. The only thing I’m seeing here, that would concern me from my experience with gentables, is that you mentioned a size of 65k. I had to switch to soundfilers because somehow I wasn’t able to load tables larger that 44.1k into a gentable. But that didn’t work for me, because I’m working with audio samples, that might as well be hundreds of times larger. If you can manage to keep your ctrl data below that threshold you might be better off with gentables. Even though I must say that I’m pleased with soundfilers and how smoothly they react to my self coded zoom functions even without the new guiMode, in terms of updating the actual content gentables seem much better from my experience.

1 Like

Thanks, Stefan! I guess I was under the impression that a soundfiler object could only display from a file, but now that I look at it, it seems to be able to display any function table. So I’m going to look into this tonight.