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 aRenderer
(offline rendering)Note
An Instr must be registered at the Session/Renderer before it can be used. See
csoundengine.instr.Instr.register()
orcsoundengine.session.Session.defInstr()
- Parameters:
name (
str
) – the name of the instrumentbody (
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 pargdoc – 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 workaliases (
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 aliasuseDynamicPfields (
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:
original body of the instr (prior to any code generation)
Named controls, mapping name to default value.
Name of this instrument
Dict mapping pfield name to default value
Code to be initialized at the instr0 level, excluding include files
List of included files, or None
Number of audio outputs of this instr
Description of this instr (optional)
Unique numeric id of this instr
Dict mapping pfield index to its name
Dict mapping pfield name to its index
Dict mapping pfield index to its default value
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
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
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
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
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()
- 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.
- 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
- 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 valuekws (
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 p5kws (
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 recordingoutfile – 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 argumentssr (
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 chosennchnls – 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
See also
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 instrsr (
int
) – the samplerate of the recordingksmps (
int
|None
) – the samples per cycle usednchnls (
int
) – the number of channelsa4 (
int
|None
) – the value of a4delay – 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
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)
- 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)