GenTable
genTable creates a table widget on screen that can be used to display the contents of a function table or the contents of a file. When selectableRegions is enabled, users can interactively select portions of the waveform by clicking and dragging.
Properties (alphabetical)
Below is the full, alphabetical list of top-level widget properties for genTable.
Active
"active": 0
Will deactivate a control if 0 is passed. Controls which are deactivated can still be updated from Csound.
Bounds
"bounds": {"left":0, "top":0, "width":100, "height":100}
Integer values that set position and size on screen(in pixels).
Channel
```json
## `channel()`
`channel()` is used to define the channels for selectable region output on the genTable widget. It accepts an object with properties for start position and length:
```javascript
channel({ start: "channelName1", length: "channelName2" })
```
- **start**: Channel that receives the starting sample position of the selected region (integer)
- **length**: Channel that receives the length of the selected region in samples (integer)
When a user selects a region on the genTable, the widget sends the start position and length to the specified channels as sample indices. These can be directly used in Csound to access the corresponding portion of the function table.
### Example Usage
```javascript
gentable({
bounds: {left: 10, top: 10, width: 600, height: 200},
channel: {start: "region_start", length: "region_length"},
tableNumber: 1,
selectableRegions: true
})
```
In your Csound code:
```csound
kRegionStart cabbageGetValue "region_start"
kRegionLength cabbageGetValue "region_length"
; Use the sample positions directly
kSample = 0
while kSample < kRegionLength do
kValue table kRegionStart + kSample, giTable1
; Process the sample...
kSample += 1
od
```
```
Defines the channel configuration for the genTable widget:
- **id**: Unique identifier for the genTable widget itself. Use this channel with `cabbageSet` to update any of the genTable's attributes.
- **start**: Channel name for the selection start position (normalized 0-1). This channel is updated when the user selects a region on the waveform (only when `selectableRegions` is enabled)
- **length**: Channel name for the selection length (normalized 0-1). This channel is updated when the user selects a region on the waveform (only when `selectableRegions` is enabled)
The start and length channels are only used when `selectableRegions` is enabled. Values are normalized (0-1) representing positions within the visible range of the table, regardless of the actual sample count. You can read these values in your Csound code using `cabbageGetValue` and convert them to sample positions using the table size.
**Example usage in Csound:**
```csound
kRegionStart cabbageGetValue "region_start"
kRegionLength cabbageGetValue "region_length"
kTableSize = ftlen(giTable1)
kStartSample = kRegionStart * kTableSize
kLengthSamples = kRegionLength * kTableSize
; Process the selected region...
```
File
"file": "filename"
This identifier is used across a number of widgets.
combobox and listbox - will load lines from a file as selectable items.
gentable and soundfiler - will load a sound file to display
image - will load an iamge to display (PNG/JPG/SVG)
infobutton - sets the file to display when the button is clicked This can be a local html file, or a URL.
texteditor - sets the file to load, should be a text file.
If a full file path is not given, file() will search in the current directory, i.e., the directory that contains the csd file that is open. It is best to keep all files in the same directory as your csd file. If you wish to keep them in a separate folder use relative paths, i.e, ../../folder.
Avoid absolute path at all costs. Failure to do so will most likely problems with your instruments as soon as you share them.
Id
"id": "widgetId"
This optional channel can be used to define a top-level line of communication between the instrument’s UI and Csound. It is reserved for UI updates only. If omitted, it defaults to the first id from the channels array. Its primary purpose is to help produce clearer code, especially for widgets with multiple channels.
Label
"label": {
"text": "",
"offsetY": 0
}
Configures the widget label displayed near the control.
- text: string — the label text.
- offsetY: number — vertical offset applied when the label is rendered outside the control (pixels).
Typography (font size, color, family, alignment) is set via style.label.*.
Range
"range": {
"min": -1,
"max": 1
}
Defines the range for the Y axis in a genTable widget.
- min: Minimum value to be displayed (required)
- max: Maximum value to be displayed (required)
Sample Range
"range": {"start":0, "end":-1}
This property sets the visible range of samples in a gentable. You can adjust these properties in real-time to enable zooming.
Selectable Regions
```json
"selectableRegions": true
```
When enabled, users can click and drag on the waveform to select a region of samples. The selected region is highlighted with a semi-transparent overlay.
**Behavior:**
- **Click and drag**: Select a region by clicking on the waveform and dragging to define the selection boundaries
- **Click without drag**: Clicking without dragging (less than 3 pixels of movement) clears the current selection
- **Visual feedback**: Selected regions are shown with a semi-transparent overlay
- **Channel output**: When a region is selected, the start and end sample indices are automatically sent to Csound via the configured channels (see `channelGentable`)
This feature is useful for selecting portions of audio for processing, looping, or analysis.
Table Number
"tableNumber": 1
Sets the function table to be displayed by the genTable widget.
Visible
"visible": 1
A value of 0 will cause the widget to become invisible. Widgets have their visibility set to 1 by default.
Style
"style": {
"opacity": 1,
"borderRadius": 4,
"borderWidth": 1,
"borderColor": "#dddddd",
"fill": "#93d200",
"background": "#00000022"
},
- Background controls the area behind the waveform.
- Colors accept named CSS colors, hex (e.g., #RRGGBB or #RRGGBBAA), or rgb/rgba strings.
- Label typography is configured under
label.*.
Example
<Cabbage>
[
{
"type": "form",
"caption": "Gentable Example",
"size": {"width": 400, "height": 650},
"guiMode": "queue",
"pluginId": "def1"
},
{
"type": "genTable",
"bounds": {"left": 10, "top": 7, "width": 380, "height": 200},
"id": "gentable1",
"tableNumber": 1
},
{
"type": "horizontalSlider",
"bounds": {"left": 14, "top": 212, "width": 368, "height": 14},
"channels": [{"id": "harm1", "range": {"min": 0, "max": 1, "value": 1, "skew": 1, "increment": 0.01}}],
"label": {"text": "Harm1"}
},
{
"type": "horizontalSlider",
"bounds": {"left": 14, "top": 244, "width": 368, "height": 14},
"channels": [{"id": "harm2", "range": {"min": 0, "max": 1, "value": 0, "skew": 1, "increment": 0.01}}],
"label": {"text": "Harm2"}
},
{
"type": "horizontalSlider",
"bounds": {"left": 14, "top": 276, "width": 368, "height": 14},
"channels": [{"id": "harm3", "range": {"min": 0, "max": 1, "value": 0, "skew": 1, "increment": 0.01}}],
"label": {"text": "Harm3"}
},
{
"type": "horizontalSlider",
"bounds": {"left": 14, "top": 308, "width": 368, "height": 14},
"channels": [{"id": "harm4", "range": {"min": 0, "max": 1, "value": 0, "skew": 1, "increment": 0.01}}],
"label": {"text": "Harm4"}
},
{
"type": "horizontalSlider",
"bounds": {"left": 14, "top": 340, "width": 368, "height": 14},
"channels": [{"id": "harm5", "range": {"min": 0, "max": 1, "value": 0, "skew": 1, "increment": 0.01}}],
"label": {"text": "Harm5"}
},
{
"type": "checkBox",
"bounds": {"left": 16, "top": 380, "width": 120, "height": 20},
"channels": [{"id": "normal"}],
"label": {"text": "Normalise"},
"value": 1
},
{
"type": "checkBox",
"bounds": {"left": 140, "top": 380, "width": 120, "height": 20},
"channels": [{"id": "fill"}],
"label": {"text": "Fill Table"},
"value": 1
}
]
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-d -n -m0d
</CsOptions>
<CsInstruments>
;sr is set by the host
ksmps = 32
nchnls = 2
0dbfs = 1
; Rory Walsh 2021
; License: CC0 1.0 Universal
; You can copy, modify, and distribute this file,
; even for commercial purposes, all without asking permission.
sumTable@global:i = ftgen(1, 0, 1024, 10, 1)
//fill table with default values
schedule("UpdateTable", 0, 0, 1, 0, 0, 0, 0, 0)
instr 1
;toggle fill
fill:k, trig:k = cabbageGetValue("fill")
cabbageSet(trig, "gentable1", "fill", fill)
harm1:k = cabbageGetValue("harm1")
harm2:k = cabbageGetValue("harm2")
harm3:k = cabbageGetValue("harm3")
harm4:k = cabbageGetValue("harm4")
harm5:k = cabbageGetValue("harm5")
outSig:a = oscili(.2, 200, 1)
outs(outSig, outSig)
trigger:k = changed(harm1, harm2, harm3, harm4, harm5)
if trigger==1 then
;if a slider changes trigger instrument 2 to update table
event("i", "UpdateTable", 0, .01, harm1, harm2, harm3, harm4, harm5)
endif
endin
instr UpdateTable
normal:i = (cabbageGetValue:i("normal")==0 ? -1 : 1)
sumTable = ftgen(1, 0, 1024, 10*normal, p4, p5, p6, p7, p8)
cabbageSet("gentable1", "tableNumber", 1) ; update table display
endin
</CsInstruments>
<CsScore>
f1 0 1024 10 1
i1 0 [3600*24*7]
</CsScore>
</CsoundSynthesizer>