modmatrix
Prev | Orchestra Opcodes and Operators | Next

## modmatrix

modmatrix — Modulation matrix opcode with optimizations for sparse matrices.

## Description

The opcode can be used to let a large number of k-rate modulator variables modulate a large number of k-rate parameter variables, with arbitrary scaling of each modulator-to-parameter connection. Csound ftables are used to hold both the input (parameter) variables, the modulator variables, and the scaling coefficients. Output variables are written to another Csound ftable.

## Syntax

    modmatrix iresfn, isrcmodfn, isrcparmfn, imodscale, inum_mod, \\
    inum_parm, kupdate

## Initialization

iresfn -- ftable number for the parameter output variables

isrcmodfn -- ftable number for the modulation source variables

isrcparmfn -- ftable number for the parameter input variables

imodscale -- scaling/routing coefficient matrix. This is also a csound ftable, used as a matrix of inum_mod rows and inum_parm columns.

inum_mod -- number of modulation variables

inum_parm -- number of parmeter (input and output) variables.

The arguments inum_mod and inum_parm do not have to be set to power-of-two values.

## Performance

kupdate -- flag to update the scaling coefficients. When the flag is set to a nonzero value, the scaling coefficients are read directly from the imodscale ftable. When the flag is set to zero, the scaling coefficients are scanned, and an optimized scaling matrix stored internally in the opcode.

For each modulator in isrcmodfn, scale it with the coefficient (in imodscale) determining to what degree it should influence each parameter. Then sum all modulators for each parameter and add the resulting modulator value to the input parameter value read from iscparmfn. Finally, write the output parameter values to table iresfn.

The following tables give insight into the processing performed by the modmatrix opcode, for a simplified example using 3 parameter and 2 modulators. Let’s call the parameters "cps1", "cps2", and "cutoff", and the modulators "lfo1" and "lfo2".

The input variables may at a given point in time have these values:

Table 12.

| cps1 | cps2 | cutoff
--- | --- | --- | ---
isrcparmfn | 400 | 800 | 3

... while the modulator variables have these values:

Table 13.

| lfo1 | lfo2
--- | --- | ---
isrcmodfn | 0.5 | -0.2

The scaling/routing coefficients used:

Table 14.

imodscale | cps1 | cps2 | cutoff
--- | --- | --- | ---
lfo1 | 40 | 0 | -2
lfo2 | -50 | 100 | 3

... and the resulting output values:

Table 15.

| cps1 | cps2 | cutoff
--- | --- | --- | ---
iresfn | 430 | 780 | 1.4
lfo2 | -50 | 100 | 3

The output value for "cps1" is calculated as 400+(0.5*40)+(-0.2*-50), similarly for "cps2" 800+(0.5*0)+(-0.2*100), and for cutoff: 3+(0.5*-2)+(-0.2*3)

The imodscale ftable may be specified in the score like this:

    f1  0  8  -2  200 0 2 50 300 -1.5

Or more conveniently using ftgen in the orchestra:

    gimodscale ftgen 0, 0, 8, -2, 200, 0, 2, 50, 300, -1.5

Obviously, the parameter and modulator variables need not be static values, and similarly, the scaling routing coefficient table may be continuously rewritten using opcodes like tablew.

## Examples

Here is an example of the modmatrix opcode. It uses the file modmatrix.csd.

Example 584. Example of the modmatrix opcode.

See the sections Real-time Audio and Command Line Flags for more information on using command line flags.

    <CsoundSynthesizer>
    <CsOptions>
    ; Select audio flags here according to platform
    ; Audio out   Audio in
    ;-odac           -iadc    ;;;RT audio I/O
    ; For Non-realtime ouput leave only the line below:
     -o modmatrix.wav -W ;;; for file output any platform
    </CsOptions>
    <CsInstruments>

    	sr	=	44100
    	kr	=	441
    	ksmps	=	100
    	nchnls	=	2
    	0dbfs	= 	1

    ; basic waveforms
    giSine	ftgen	0, 0, 65537, 10, 1	; sine wave
    giSaw 	ftgen	0, 0, 4097, 7, 1, 4096, -1	; saw (linear)
    giSoftSaw ftgen	0, 0, 65537, 30, giSaw, 1, 10	; soft saw (only 10 first harmonics)

    ; modmatrix tables
    giMaxNumParam	= 128
    giMaxNumMod	= 32
    giParam_In ftgen 0, 0, giMaxNumParam, 2, 0	; input parameters table
    ; output parameters table (parameter values with added modulators)
    giParam_Out ftgen 0, 0, giMaxNumParam, 2, 0
    giModulators ftgen 0, 0, giMaxNumMod, 2, 0	 ; modulators table
    ; modulation scaling and routing (mod matrix) table, start with empty table
    giModScale ftgen 0, 0, giMaxNumParam*giMaxNumMod, -2, 0

    ;********************************************
    ; generate the modulator signals
    ;********************************************
    	instr 1

    ; LFO1, 1.5 Hz, normalized range (0.0 to 1.0)
    kLFO1	oscil	0.5, 1.5, giSine		; generate LFO signal
    kLFO1	= kLFO1+0.5				; offset

    ; LFO2, 0.4 Hz, normalized range (0.0 to 1.0)
    kLFO2	oscil	0.5, 0.4, giSine		; generate LFO signal
    kLFO2	= kLFO2+0.5				; offset

    ; write modulators to table
    	tablew	kLFO1, 0, giModulators
    	tablew	kLFO2, 1, giModulators

    	endin

    ;********************************************
    ; set parameter values
    ;********************************************
    	instr 2

    ; Here we can set the parameter values
    icps1	= p4
    icps2	= p5
    icutoff	= p6

    ; write parameters to table
    	tableiw	icps1, 0, giParam_In
    	tableiw	icps2, 1, giParam_In
    	tableiw	icutoff, 2, giParam_In

    	endin

    ;********************************************
    ; mod matrix edit
    ;********************************************
    	instr 3

    ; Here we can write to the modmatrix table by using tablew or tableiw

    iLfo1ToCps1	= p4
    iLfo1ToCps2	= p5
    iLfo1ToCutoff	= p6
    iLfo2ToCps1	= p7
    iLfo2ToCps2	= p8
    iLfo2ToCutoff	= p9

    	tableiw	iLfo1ToCps1, 0, giModScale
    	tableiw	iLfo1ToCps2, 1, giModScale
    	tableiw	iLfo1ToCutoff, 2, giModScale
    	tableiw	iLfo2ToCps1, 3, giModScale
    	tableiw	iLfo2ToCps2, 4, giModScale
    	tableiw	iLfo2ToCutoff, 5, giModScale

    ; and set the update flag for modulator matrix
    ; ***(must update to enable changes)
    ktrig	init 1
    	chnset	ktrig, "modulatorUpdateFlag"
    ktrig	= 0

    	endin

    ;********************************************
    ; mod matrix
    ;********************************************
    	instr 4

    ; get the update flag
    kupdate	chnget	"modulatorUpdateFlag"

    ; run the mod matrix
    inum_mod	= 2
    inum_parm	= 3
    	modmatrix giParam_Out, giModulators, giParam_In, \
    	giModScale, inum_mod, inum_parm, kupdate

    ; and reset the update flag
    	chnset	0, "modulatorUpdateFlag"  ; reset the update flag

    	endin

    ;********************************************
    ; audio generator to test values
    ;********************************************
    	instr 5

    ; basic parameters
    	iamp	= ampdbfs(-5)

    ; read modulated parameters from table
    	kcps1	table	0, giParam_Out
    	kcps2	table	1, giParam_Out
    	kcutoff	table	2, giParam_Out

    ; set filter parameters
    	kCF_freq1	= kcps1*kcutoff
    	kCF_freq2	= kcps2*kcutoff
    	kReso		= 0.7
    	kDist		= 0.3

    ; oscillators and filters
    	a1	oscili	iamp, kcps1, giSoftSaw
    	a1	lpf18	a1, kCF_freq1, kReso, kDist

    	a2	oscili	iamp, kcps2, giSoftSaw
    	a2	lpf18	a2, kCF_freq2, kReso, kDist

    		outs 	a1, a2

    	endin

    </CsInstruments>
    <CsScore>

    ;********************************************
    ; set initial parameters
    ;	cps1	cps2	cutoff
    i2 0 1	400	800	3

    ;********************************************
    ; set modmatrix values
    ;	lfo1ToCps1 lfo1ToCps2 lfo1ToCut lfo2ToCps1 lfo2ToCps2 lfo2ToCut
    i3 0 1 	40         0          -2        -50        100        3

    ;********************************************
    ; start "always on" instruments
    #define SCORELEN # 20 #	 ; set length of score

    i1 0 $SCORELEN			; start modulators
    i4 0 $SCORELEN			; start mod matrix
    i5 0 $SCORELEN			; start audio oscillator

    e

    </CsScore>
    </CsoundSynthesizer>

## See Also

Linear Algebra Opcodes, Vectorial Opcodes, tablew.

## Credits

By:

Oeyvind Brandtsegg and Thom Johansen

New in version 5.12

Prev | Up | Next
mode | Home | monitor