Instr – Instrument Templates#

An Instr is a template used to schedule a concrete instrument at a Session or a Renderer. It must be registered to be used (see registerInstr()) or created via defInstr().

Example

from csoundengine import *

s = Session()

s.defInstr('sine', r'''
    kfreq = p5
    kamp = p6
    a0 = oscili:a(kamp, kfreq)
    outch 1, a0
''')

synth = s.sched('sine', kfreq=440, kamp=0.1)
...
synth.stop()

Named arguments / Inline arguments

An Instr can define named arguments and assign default values to any argument. Named arguments can be created either by using the supported csound syntax, using ivar = p5 or kvar = p5. Default values can be assigned via pset (https://csound.com/manual/pset.html) or through the args argument to Instr or defInstr(). Alternatively inline arguments can be used:

An inline args declaration can set both parameter name and default value:

s = Engine().session()
Instr('sine', r'''
    |iamp=0.1, kfreq=1000|
    a0 = oscili:a(iamp, kfreq)
    outch 1, a0
''').register(s)
synth = s.sched('sine', kfreq=440)
synth.stop()
class csoundengine.instr.Instr(name, body, args=None, init='', numchans=1, preschedCallback=None, doc='', includes=None, aliases=None, maxNamedArgs=0, useDynamicPfields=None)[source]#

An Instr is a template used to schedule a concrete instrument

Instrs are used within a Session (realtime rendering) or a Renderer (offline rendering)

Note

An Instr must be registered at the Session/Renderer before it can be used. See csoundengine.instr.Instr.register() or csoundengine.session.Session.defInstr()

Parameters:
  • name (str) – the name of the instrument

  • body (str) – the body of the instr (the text between ‘instr’ end ‘endin’)

  • args (dict[str, float | str] | None) – if given, a dictionary defining default values for arguments. Can be init-time (‘i’ prefix) or performance time (with ‘k’ prefix).

  • init – code to be initialized at the instr0 level

  • preschedCallback – a function f(synthid, args) -> args, called before a note is scheduled with this instrument. Can be used to allocate a table or a dict and pass the resulting index to the instrument as parg

  • doc – some documentation describing what this instr does

  • includes (list[str] | None) – a list of files which need to be included in order for this instr to work

  • aliases (dict[str, str] | None) – if given, a dict mapping arg names to real argument names. It enables to define named args for an instrument using any kind of name instead of following csound names, or use any kind of name in an instr to avoid possible collisions while exposing a nicer name to the outside as alias

  • useDynamicPfields (bool | None) – if True, use pfields to implement dynamic arguments (arguments given as k-variables). Otherwise dynamic args are implemented as named controls, using a big global table

Example

s = Engine().session()
Instr('sine', r'''
    kfreq = p5
    iamp = p6
    a0 = oscili:a(iamp, kfreq)
    outch 1, a0
''').register(s)
synth = s.sched('sine', kfreq=440, iamp=0.1)
synth.stop()

One can create an Instr and register it at a session in one operation:

s = Engine().session()
s.defInstr('sine', r'''
    kfreq = p5
    kamp = p6
    a0 = oscili:a(kamp, kfreq)
    outch 1, a0
''')

Default Values

An Instr can define default values for any of its parameters and define aliases for its names:

s = Engine().session()
s.defInstr('sine', r'''
    kamp = p5
    kfreq = p6
    a0 = oscili:a(kamp, kfreq)
    outch 1, a0
''', args={'kamp': 0.1, 'kfreq': 1000}, aliases={'frequency': 'kfreq'}
)
# We schedule an event of sine, kamp will take the default (0.1)
synth = s.sched('sine', kfreq=440)
synth.set(frequency=450, delay=1)   # Use alias
synth.stop()

Inline arguments

An inline args declaration can set both parameter name and default value:

s = Engine().session()
Instr('sine', r'''
    |iamp=0.1, kfreq=1000|
    a0 = oscili:a(iamp, kfreq)
    outch 1, a0
''').register(s)
synth = s.sched('sine', kfreq=440)
synth.stop()

The same can be achieved via an associated table:

s = Engine().session()
Instr('sine', r'''
    a0 = oscili:a(kamp, kfreq)
    outch 1, a0
''', tabargs=dict(amp=0.1, freq=1000
).register(s)
synth = s.sched('sine', tabargs=dict(freq=440))
synth.stop()

An inline syntax exists also for tables:

Intr('sine', r'''
    {amp=0.1, freq=1000}
    a0 = oscili:a(kamp, kfreq)
    outch 1, a0
''')

This will create a table and fill it will the given/default values, and generate code to read from the table and free the table after the event is done. Call dump() to see the generated code:

i_params = p4
if ftexists(i_params) == 0 then
    initerror sprintf("params table (%d) does not exist", i_params)
endif
i__paramslen = ftlen(i_params)
if i__paramslen < {maxidx} then
    initerror sprintf("params table is too small (size: %d, needed: {maxidx})", i__paramslen)
endif
kamp tab 0, i_params
kfreq tab 1, i_params
a0 = oscili:a(kamp, kfreq)
outch 1, a0

Offline rendering

An Instr can also be used to define instruments for offline rendering (see Renderer)

from csoundengine import *
renderer = Renderer(sr=44100, nchnls=2)

instrs = [
    Instr('saw', r'''
      kmidi = p5
      outch 1, oscili:a(0.1, mtof:k(kmidi))
    '''),
    Instr('sine', r'''
      |kamp=0.1, kmidi=60|
      asig oscili kamp, mtof:k(kmidi)
      asig *= linsegr:a(0, 0.1, 1, 0.1, 0)
      outch 1, asig
    ''')
]

for instr in instrs:
    instr.register(renderer)

score = [('saw', 0,   2, 60),
         ('sine', 1.5, 4, 67),
         ('saw', 1.5, 4, 67.1)]

events = [renderer.sched(ev[0], delay=ev[1], dur=ev[2], pargs=ev[3:])
          for ev in score]

# Offline events can be modified just like real-time events
renderer.automate(events[0], 'kmidi', pairs=[0, 60, 2, 59])
renderer.set(events[1], 3, 'kmidi', 67.2)
renderer.render("out.wav")

Attributes:

originalBody

original body of the instr (prior to any code generation)

controls

Named controls, mapping name to default value.

name

Name of this instrument

pfields

Dict mapping pfield name to default value

init

Code to be initialized at the instr0 level, excluding include files

includes

List of included files, or None

numchans

Number of audio outputs of this instr

doc

Description of this instr (optional)

id

Unique numeric id of this instr

pfieldIndexToName

Dict mapping pfield index to its name

pfieldNameToIndex

Dict mapping pfield name to its index

pfieldIndexToValue

Dict mapping pfield index to its default value

aliases

Maps alias argument names to their real argument names

Methods:

register(renderer)

Register this Instr at the given session

generateBody([renderer])

Generate the actual body of this instrument

dump()

Returns a string with the generated code of this Instr

unaliasParam(param[, default])

Return the original name for parameter, if exists

controlNames([aliases, aliased])

Set of names of the controls in this instr

dynamicParamNames([aliases, aliased])

Set of all dynamic parameters accepted by this Instr

dynamicPfields([aliases, aliased])

The dynamic pfields in this instr

dynamicPfieldNames()

Set of dynamic pfields defined in this instr

dynamicParams([aliases, aliased])

A dict with all dynamic parameters defined in this instr

paramNames([aliases, aliased])

All parameter names

pfieldNames([aliases, aliased])

The set of named pfields declared in this instrument

paramDefaultValues([aliases, aliased])

A dict mapping named parameters to their default values

distributeNamedParams(params)

Sorts params into pfields and dynamic controls

pfieldName(index[, alias])

Given the pfield index, get the name, if given

numPfields()

The number of pfields in this instrument, starting with p5

pfieldIndex(name[, default])

Pfield index corresponding to the given name.

parseSchedArgs(args, kws)

Parse the arguments passed to sched

pfieldDefaultValue(pfield)

Returns the default value of a pfield

defaultPfieldValues()

The default pfield values, starting with p5

pfieldsTranslate([args, kws])

Given pfields as values and keyword arguments, generate a list of values which can be passed to sched, starting with p5 (p4 is reserved)

rec(dur[, outfile, args, sr, ksmps, ...])

Record this Instr for a given duration

renderSamples(dur[, args, sr, ksmps, ...])

Record this instrument and return the generated samples

hasControls()

Returns True if this instrument defines a parameters table

controlIndex(param)

Returns the index of a control parameter

overrideControls([d])

Overrides default values for the controls in this instr

originalBody#

original body of the instr (prior to any code generation)

controls: dict[str, float]#

Named controls, mapping name to default value.

name: str#

Name of this instrument

pfields: dict[str, float]#

Dict mapping pfield name to default value

pfield index is assigned by order, starting with p5

init: str#

Code to be initialized at the instr0 level, excluding include files

includes: list[str] | None#

List of included files, or None

numchans#

Number of audio outputs of this instr

doc#

Description of this instr (optional)

id: int#

Unique numeric id of this instr

pfieldIndexToName: dict[int, str]#

Dict mapping pfield index to its name

pfieldNameToIndex: dict[str, int]#

Dict mapping pfield name to its index

pfieldIndexToValue: dict[int, float]#

Dict mapping pfield index to its default value

aliases#

Maps alias argument names to their real argument names

Aliased parameters can be pfields or named controls

register(renderer)[source]#

Register this Instr at the given session

This is just a shortcut for session.register(instr)

Parameters:

renderer (AbstractRenderer) – the renderer to register this Instr at

Return type:

None

Example

>>> from csoundengine import *
>>> s = Engine().session()
>>> Instr('myinstr', ...).register(s)

This is equivalent to

>>> s.defInstr('myinstr', ...)
generateBody(renderer=None)[source]#

Generate the actual body of this instrument

An Instr can generate different csound code depending on the renderer.

Parameters:

renderer (AbstractRenderer) – the renderer for which to generate the body. If not given the code generated for a live session is returned

Return type:

str

Returns:

the actual csound code to be used as the body of this instrument

See also

csoundengine.session.Session.defaultInstrBody()

dump()[source]#

Returns a string with the generated code of this Instr

Return type:

str

unaliasParam(param, default='')[source]#

Return the original name for parameter, if exists

Return type:

str

Example

>>> instr = Instr('foo', r'''
... |kfreq=1000|
... ''', aliases={'frequency': 'kfreq'})
>>> instr.unaliasParam('frequency')
'kfreq'
controlNames(aliases=True, aliased=False)[source]#

Set of names of the controls in this instr

Returns an empty set if this instr has no controls.

Return type:

frozenset[str]

dynamicParamNames(aliases=True, aliased=False)[source]#

Set of all dynamic parameters accepted by this Instr

Parameters:
  • aliases – include aliases

  • aliased – include parameters which have an alias (implies aliases)

Return type:

frozenset[str]

Returns:

a set of the dynamic (modifiable) parameters accepted by this Instr

dynamicPfields(aliases=True, aliased=False)[source]#

The dynamic pfields in this instr

A dynamic pfield is a pfield assigned to a k-variable. Such pfields can be modified via .set using the pwrite opcode

Parameters:
  • aliases – include aliases

  • aliased – include parameters which have an alias (implies aliases)

Return type:

dict[str, float]

Returns:

a dict mapping pfield name to default value.

dynamicPfieldNames()[source]#

Set of dynamic pfields defined in this instr

Dynamic pfields are pfields which have been assigned to a k-variable

If this instr defines aliases for any of the dynamic pfields, these aliases will be included in the returned set

If this instrument does not have any dynamic pfields an empty set will be returned. In general the returned set should be considered immutable

Return type:

frozenset[str]

dynamicParams(aliases=True, aliased=False)[source]#

A dict with all dynamic parameters defined in this instr

Dynamic parameters are not only all defined controls, but also any pfield assigned to a k-variable. They include aliases to any dynamic parameter.

Parameters:
  • aliases – include aliases

  • aliased – include parameters which have an alias (implies aliases)

Return type:

dict[str, float]

Returns:

a dict with all dynamic parameters and their default values. Returns an empty dict if this instr has no dynamic parameters.

paramNames(aliases=True, aliased=False)[source]#

All parameter names

Return type:

frozenset[str]

pfieldNames(aliases=True, aliased=False)[source]#

The set of named pfields declared in this instrument

Parameters:
  • aliases – include aliases

  • aliased – include parameters which have an alias (implies aliases)

Return type:

frozenset[str]

Returns:

a set with the named pfields defined in this instr

paramDefaultValues(aliases=True, aliased=False)[source]#

A dict mapping named parameters to their default values

Named parameters are any named pfields or controls. Also anonymous pfields which have an assigned default value via the ‘pset’ opcode will be included here

Parameters:
  • aliases – included aliases

  • aliased – include parameters which have an alias

Return type:

dict[str, float]

Returns:

a dict of named dynamic parameters to this instr and their associated default values

Example

>>> from csoundengine import *
>>> s = Engine().session()
>>> s.defInstr('test', r'''
... |kfreq=1000|
... pset 0, 0, 0, 0, 0.1, 0.5
... iamp = p5
... outch 1, oscili:a(iamp, kfreq * p6)
... ''')
distributeNamedParams(params)[source]#

Sorts params into pfields and dynamic controls

Parameters:

params (dict[str, float | str]) – a dict mapping name to value given

Return type:

tuple[dict[str | int, float | str], dict[str, float]]

Returns:

a tuple (pfields, dynargs) where each is a dict mapping the parameter to its given value

pfieldName(index, alias=True)[source]#

Given the pfield index, get the name, if given

Parameters:
  • index (int) – the pfield index (starts with 1)

  • alias – if True, return the corresponding alias, if defined

Return type:

str

Returns:

the corresponding pfield name, or an empty string if the index does not have an associated name

numPfields()[source]#

The number of pfields in this instrument, starting with p5

Return type:

int

pfieldIndex(name, default=None)[source]#

Pfield index corresponding to the given name.

Parameters:
  • name (str) – the index or the name of the p-field.

  • default (int | None) – if the name is not known and default is not None, this value is returned as the index to indicate that the parg was not found (instead of raising an Exception)

Return type:

int

Returns:

the index of the parg

parseSchedArgs(args, kws)[source]#

Parse the arguments passed to sched

Parameters:
  • args (list[float | str] | dict[str, float | str]) – a list of values (starting with p5) or a dict mapping named param to value

  • kws (dict[str, float | str]) – a dict mapping named param to value

Return type:

tuple[list[float | str], dict[str, float]]

Returns:

a tuple (pfields5, dynargs), where pfields5 is a list of pfield values starting at p5 and dynargs is a dict of dynamic parameters mapping parameter name to the given value

pfieldDefaultValue(pfield)[source]#

Returns the default value of a pfield

Parameters:

pfield (str | int) – the name / index of the pfield

Return type:

float | str | None

Returns:

the default value. Will raise an exception if the pfield is not known. Returns None if the pfield is known but it was declared without default

defaultPfieldValues()[source]#

The default pfield values, starting with p5

Return type:

list[float | str]

pfieldsTranslate(args=(), kws=None)[source]#

Given pfields as values and keyword arguments, generate a list of values which can be passed to sched, starting with p5 (p4 is reserved)

Parameters:
  • args (Sequence[float | str]) – pfield values, starting with p5

  • kws (dict[str | int, float] | None) – named pfields (a name can also be ‘p8’ for example)

Return type:

list[float | str]

Returns:

a list of float values with 0 representing absent pfields

rec(dur, outfile='', args=None, sr=None, ksmps=None, encoding=None, nchnls=2, wait=True, a4=None, delay=0.0, **kws)[source]#

Record this Instr for a given duration

Parameters:
  • dur (float) – the duration of the recording

  • outfile – if given, the path to the generated output. If not given, a temporary file will be generated.

  • args (list[float] | dict[str, float] | None) – the arguments passed to the instrument (if any), beginning with p5 or a dict with named arguments

  • sr (int | None) – the sample rate -> config[‘rec_sr’]

  • ksmps (int | None) – the number of samples per cycle -> config[‘rec_ksmps’]

  • encoding (str | None) – the sample encoding of the rendered file, given as ‘pcmXX’ or ‘floatXX’, where XX represent the bit-depth (‘pcm16’, ‘float32’, etc). If no encoding is given a suitable default for the sample format is chosen

  • nchnls – the number of channels of the generated output.

  • wait – if True, the function blocks until done, otherwise rendering is asynchronous

  • a4 (int | None) – the frequency of A4 (see config[‘A4’]

  • kws – any keyword will be interpreted as a named argument of this Instr

  • delay – when to schedule the instr

Return type:

str

Returns:

the path of the generated soundfile

Example

>>> from csoundengine import *
>>> from sndfileio import *
>>> s = Engine().session()
>>> white = s.defInstr('white', r'''
...   |igain=0.1|
...   aout = gauss:a(1) * igain
...   outch 1, aout
... ''')
>>> samples, info = sndget(white.rec(2))
>>> info
samplerate : 44100
nframes    : 88192
channels   : 2
encoding   : float32
fileformat : wav
duration   : 2.000
renderSamples(dur, args=None, sr=44100, ksmps=None, nchnls=2, a4=None, delay=0.0, **kws)[source]#

Record this instrument and return the generated samples

Parameters:
  • dur – the duration of the recording

  • args (list[float] | dict[str, float] | None) – the args passed to this instr

  • sr (int) – the samplerate of the recording

  • ksmps (int | None) – the samples per cycle used

  • nchnls (int) – the number of channels

  • a4 (int | None) – the value of a4

  • delay – when to schedule this instr

  • kws – any keyword will be interpreted as a named argument of this Instr

Return type:

ndarray

Returns:

the generated samples as numpy array

See also

Instr.rec()

Example

>>> from csoundengine import *
>>> from sndfileio import *
>>> s = Engine().session()
>>> white = s.defInstr('white', r'''
...  |igain=0.1|
...  aout = gauss:a(1) * igain
...  outch 1, aout
... ''')
# Render two seconds of white noise
>>> samples = white.renderSamples(2)
hasControls()[source]#

Returns True if this instrument defines a parameters table

Return type:

bool

controlIndex(param)[source]#

Returns the index of a control parameter

Raises KeyError if the parameter given is not defined

Parameters:

param (str) – the parameter name

Return type:

int

Returns:

the corresponding slot

overrideControls(d=None, **kws)[source]#

Overrides default values for the controls in this instr

Returns the values for all the defined slots

Parameters:
  • d (dict[str, float] | None) – if given, a dictionary of the form {‘argname’: value}. Alternatively key/value pairs can be passed as keywords

  • **kws – each key must match a named parameter as defined in the tabargs attribute

Return type:

list[float]

Returns:

A list of floats holding the new initial values of the parameters table. The returned list should not be modified

Example

instr.overrideTable(param1=value1, param2=value2)