OfflineEngine Class#
The OfflineEngine class represents an offline csound process rendering to a soundfile
instead of to the dac. An OfflineEngine is, for the most part, a drop-in replacement
of the Engine class. The main difference is that for an OfflineEngine
time needs to be advanced explicitely via its perform() method.
At any moment it is possible to interact with the offline csound process. While an OfflineEngine is
running it is possible to query variables, load resources, read and write to channels, etc.
Example 1#
from csoundengine import OfflineEngine
import random
engine = OfflineEngine()
engine.compile(r'''
instr vco
pset 0, 0, 0, 263, 0.1, 1, 1000, 0.1, 0.5
ifreq = p4
iamp = p5
ktransp = p6
kcutoff = p7
ifade = p8
ifilterq = p9
kfreq = ifreq * ktransp
aout = vco2:a(iamp, kfreq)
iresonance = 0.6
idistortion = 0.
aout = lpf18(aout, kcutoff, iresonance, idistortion)
aout *= linsegr:a(0, ifade, 1, ifade, 0)
outch 1, aout
endin
''')
f0 = 130
for factor in [1, 2.76, 5.3, 5.4, 8.93]:
freq = f0 * factor
# with unique=True a fractional p1 is generated, this makes it
# possible to automate the event later
# NB: csoundengine parses instr code and is aware of names given to pfields
event = engine.sched('vco', engine.now, 8, unique=True,
ifreq=freq, iamp=0.1, kcutoff=freq*3, ifade=freq/f0* 0.5, ifilterq=0.8)
transp = random.uniform(0.92, 1.08)
# start automation of p6 at time=2. This case, modify the transposition factor,
# from 1 to a random value between 0.92 and 1.08
engine.automatep(event, 6, (0, 1, 5, transp), delay=2)
# The pfield can also be given by name. With overtake=True the value given
# to the pfield at init is used as the starting point
engine.automatep(event, 'kcutoff', (0, 0, 3, freq*1.1), overtake=True, delay=2 + factor*0.3)
# Advance time to actually perform the events. We give some extra time
# to account for fade outs.
engine.perform(extratime=5)
engine.stop()
Example 2: sound analysis#
TODO
- class csoundengine.offlineengine.OfflineEngine(sr=44100, ksmps=64, outfile='', nchnls=2, a4=0, globalcode='', numAudioBuses=None, numControlBuses=None, quiet=True, includes=None, sampleAccurate=False, encoding='', commandlineOptions=None)[source]#
Non-real-time engine using the csound API
This is similar to an
csoundengine.engine.Enginebut it renders offline to a soundfile- Parameters:
sr – sample rate
ksmps (
int) – samples per cycleoutfile (
str) – soundfile to render to. If not given a tempfile is usednchnls – number of output channels
a4 (
int) – reference frequencynumAudioBuses (
int|None) – number of audio buses (see Bus Opcodes)numControlBuses (
int|None) – number of control buses (see Bus Opcodes)quiet – if True, suppress output of csound (-m 0)
includes (
list[str] |None) – a list of files to include. Can be added later viaEngine.includeFile()sampleAccurate – use sample-accurate scheduling
commandlineOptions (
list[str] |None) – command line options passed verbatim to the csound process when startedencoding – the sample encoding of the rendered file, given as ‘pcm<bits>’ or ‘float<bits>’, where bits presents the bit-depth (for example, ‘pcm16’, ‘pcm24’, ‘float32’, etc). If no encoding is given a suitable default for the sample format is chosen.
Methods:
compile(code)Send orchestra code to csound
assignEventId(instr)Assign a unique p1 value for the given instrument number
sched(instr[, delay, dur, args, unique, comment])Schedule an instrument
unsched(p1[, delay])Stop a playing event
A context manager to suppress tracking history
setEndMarker(time)Set the end marker
perform([endtime, extratime])Advance the time, performing any scheduled events within the current time and the end time
cancel([remove])Cancel performance of this engine
stop([render, extratime])Stop this csound process, optionally rendering any pending events
strSet(s)Assign a numeric index to a string to be used inside csound
inputMessage(msg)Schedule a score line
readSoundfile(path[, tabnum, chan, ...])Read a soundfile into a table (via GEN1), returns the table number
queryVariable(variable)Query the value of a csound variable via the
returnopcodecall(func)Call an init-time csound function, returns the result
makeEmptyTable(size[, numchannels, sr, delay])Create an empty table, returns the index of the created table
channelPointer(channel[, kind, mode])Returns a numpy array aliasing the memory of a control or audio channel
initChannel(channel[, value, kind, mode])Create a channel and set its initial value
getControlChannel(channel)Get the value of a control channel
fillTable(tabnum, data)Fill an existing table with data
makeTable(data[, sr, tabnum, delay])Create a new table and fill it with data.
Reports the logical elapsed time of this engine
playSample(tabnum[, delay, chan, speed, ...])Play a sample already loaded into a table.
automatep(p1, pfield, pairs[, mode, delay, ...])Automate a pfield of a scheduled event
rewind([offset])Unschedule future events and set the time pointer to the given offset
Generate a
Csdfrom this OfflineEnginewrite(outfile)Dump this OfflineEngine as a .csd
includeFile(include)Add an #include file to this Engine
playSoundFromDisk(path[, delay, dur, chan, ...])Play a soundfile from disk via diskin2
setp(p1, *pairs[, delay])Modify a pfield of an active note
assignBus([kind, value, persist])Assign one audio/control bus, returns the bus number.
releaseBus(bus[, delay])Release a persistent bus
writeBus(bus, value[, delay])Set the value of a control bus
openOutfile([app])Open the generated soundfile in an external app
Attributes:
The current elapsed time
- compile(code)[source]#
Send orchestra code to csound
The code sent can be any orchestra code
- Parameters:
code (
str) – the code to compile- Return type:
None
- assignEventId(instr)[source]#
Assign a unique p1 value for the given instrument number
This is used internally to assign a fractional p1 when called sched with unique=True, but it can also be used to generate unique p1 for
OfflineEngine.inputMessage()or when using csound’sschedulewithOfflineEngine.compile()- Parameters:
instr (
int|str) – the instrument number- Return type:
float- Returns:
a unique fractional p1
- sched(instr, delay=0.0, dur=-1.0, *pfields, args=None, unique=False, comment='', **namedpfields)[source]#
Schedule an instrument
- Parameters:
instr (
int|float|str) – the instrument number/name. If it is a fractional number, that value will be used as the instance number. An integer or a string will result in a unique instance assigned by csound if unique is True. Named instruments with a fractional number can also be scheduled (for example, for an instrument named “myinstr” you canuse “myinstr.001”)delay – start time, relative to the elapsed time. (see
OfflineEngine.now)dur – duration of the event
args (
ndarray|list[float|str] |None) – any other args expected by the instrument, starting with p4 (as a list of floats/strings, or a numpy array). Any string arguments will be converted to a string index via strSet. These can be retrieved in csound via strgetunique – if True, assign a unique p1
namedpfields – pfields can be given as keyword arguments of the form p4=…, p6=… Defaults are filled with values defined via
pset
- Return type:
float|str- Returns:
a fractional p1 of the instr started, which identifies this event. If instr is a fractional named instr, like “synth.01”, then this same instr is returned as eventid (as a string).
Example
from csoundengine import * e = Engine() e.compile(r''' instr 100 pset 0, 0, 0, 1000, 2000, 0, 9.0 kfreq = p4 kcutoff = p5 Smode strget p6 iq = p7 asig vco2 0.1, kfreq if strcmp(Smode, "lowpass") == 0 then asig moogladder2 asig, kcutoff, 0.95 else asig K35_hpf asig, kcutoff, iq endif outch 1, asig endin ''') eventid = e.sched(100, 2, args=[200, 400, "lowpass"]) # simple automation in python for cutoff in range(400, 3000, 10): e.setp(eventid, 5, cutoff) time.sleep(0.01) e.unsched(eventid) # # To ensure simultaneity between events: now = e.elapsedTime() for t in np.arange(2, 4, 0.2): e.sched(100, t+now, 0.2, relative=False, p7=9.8)
See also
- unsched(p1, delay=0)[source]#
Stop a playing event
If p1 is a round number, all events with the given number are unscheduled. Otherwise only an exact matching event is unscheduled, if it exists
- Parameters:
p1 (
float|str) – the instrument number/name to stopdelay (
float) – absolute time to turnoff the given event. A value of 0 means to unschedule it at the current time
- Return type:
None
Example
>>> from csoundengine import * >>> e = Engine(...) >>> e.compile(r''' ... instr sine ... a0 oscili 0.1, 1000 ... outch 1, a0 ... endin ... ''') >>> # sched an event with indefinite duration >>> eventid = e.sched(10, 0, -1) >>> e.unsched(eventid, 10)
See also
unschedAll()
- setEndMarker(time)[source]#
Set the end marker
When calling
OfflineEngine.perform(), performance will be advanced up to this absolute timeThe current end time can be queried via the
OfflineEngine.endtimeattribute- Return type:
None
- perform(endtime=0.0, extratime=0.0)[source]#
Advance the time, performing any scheduled events within the current time and the end time
By default, perform until the end marker. The end marker is set by the last end time of an event. NB: Events with infinite duration do not modify the end marker. Use
extratimeto assign rendering time for such events.This method is called implicitely at object destruction. To prevent implicit rendering, call
OfflineEngine.stop()withrenderPending=FalseThe rendering process is finished when
OfflineEngine.stop()is called, which happens implicitely at object destrution. If the rendered audiofile needs to be accessed immediately, thenOfflineEngine.stop()needs to be called explicitelyNote
stop()will callperform()if there are any pending events, so in order to render a process to completion, onlystop()needs to be called- Parameters:
endtime – if given, overrides the endtime of the engine
extratime – time added to the current end marker, it is not taken into account if endtime is given
- Return type:
None
Example
from csoundengine import OfflineEngine import sndfileio e = OfflineEngine() e.compile(r''' instr pitchtrack itabnum = p4 ; the sound source itabfreq = p5 ; the table where to put tracked pitch. The table must be big enough itabsize = ftlen(itabfreq) ifftsize = 2048 ifftsize2 = ifftsize * 4 ; this second anaylsis helps smooth the result iwtype = 0 ; hamming kcount init 1 ; the first element is the element count aouts[] loscilx 1, 1, itabnum, 4, 1 a0 = aouts[0] ; only analyze first channel a0d = delay(a0, ifftsize2 * 0.5 / sr) ; shift the original signal fsig pvsanal a0d, ifftsize, 512, ifftsize, iwtype fsig2 pvsanal a0, ifftsize2, 512, ifftsize2, iwtype kfreq, kamp pvspitch fsig, 0.1 kfreq2, kamp2 pvspitch fsig2, 0.08 if kcount >= itabsize || detectsilence(a0, db(-90), 0.1) == 1 then turnoff endif if (kfreq2 == 0 ? 1 : kfreq / kfreq2) < 0.5 then kfreq = kfreq2 endif tabw kfreq, kcount, itabfreq kcount += 1 tabw kcount, 0, itabfreq ; To validate the analysis, we output the original sound and the resynthesized audio outs delay(a0, ifftsize + ifftsize2*0.5), vco2(kamp, kfreq) endin ''') sndtab = e.readSoundfile(sndfile) duration = sndfileio.info(sndfile).duration numcycles = int((duration * e.sr / e.ksmps) freqtab = e.makeEmptyTable(numcycles + 100) e.sched('pitchtrack', 0, duration + 0.1, sndtab, freqtab) # Advance time until analysis has been done e.perform() # Now retrieve information outarr = e.getTableData(freqtab) datalen = outarr[0] freqs = outarr[1:1+datalen] # At any moment the user can access the generated soundfile via the # renderjob variable, even if the engine is still active. e.renderjob.openOutfile() # Stop the engine to clean up e.stop()
- cancel(remove=True)[source]#
Cancel performance of this engine
- Parameters:
remove – if True, remove the generated outfile
- Return type:
None
- stop(render=True, extratime=0.0)[source]#
Stop this csound process, optionally rendering any pending events
- Parameters:
render – if True, advance the clock to render any pending scheduled event.
extratime – if render is True, add extra render time to allow for decays
- Return type:
RenderJob|None- Returns:
a RenderJob containing information about the rendered file, or None if no render took place.
- strSet(s)[source]#
Assign a numeric index to a string to be used inside csound
- Parameters:
s (
str) – the string to set- Return type:
int- Returns:
the index associated with
s. When passed to a csound instrument it can be retrieved viastrget.
- inputMessage(msg)[source]#
Schedule a score line
At the moment, due to a limitation in the csound scheduler input messages are only scheduled at the beginning of the performance. Any meesage scheduled after
OfflineEngine.perform()has been called will be ignored- Parameters:
msg (
str) – the message in score format ('i1 0.5 3 ...')- Return type:
None- Returns:
the p1, will be 0 if a named instrument is used
- readSoundfile(path, tabnum=0, chan=0, skiptime=0.0, delay=0.0, unique=True)[source]#
Read a soundfile into a table (via GEN1), returns the table number
- Parameters:
path (
str) – the path to the output – “?” to open file interactivelytabnum – if given, a table index. If None, an index is autoassigned
chan – the channel to read. 0=read all channels
skiptime – time to skip at the beginning of the soundfile.
delay – performance time at which to read the soundfile
unique – if False and the same file with the same params is already loaded, the existing table is returned
- Return type:
int- Returns:
the table number. Information about the read soundfile can be obtained via
OfflineEngine.tableInfo()
- queryVariable(variable)[source]#
Query the value of a csound variable via the
returnopcode- Return type:
float
Example
>>> engine.compile(r''' ... gkfoo init 0 ... instr 100 ... gkfoo = p4 ... endin ... ''') >>> engine.sched(100, 0, 0, 314) >>> engine.perform() >>> engine.queryVariable('gkfoo') 314.0
- call(func)[source]#
Call an init-time csound function, returns the result
- Parameters:
func (
str) – the function to call, like ‘ftgen(200, 0, 100, 2, 0)’. It must be an init-time function returning one init value- Return type:
float- Returns:
the value returned by the function
Example
# Create an empty table manually with size 100 >>> engine.compile(r’i0 = ftgen(200, 0, 100, 2, 0)’) # Check that the size is correct >>> engine.call(‘ftlen(200)’) 100
- makeEmptyTable(size, numchannels=1, sr=0, delay=0.0)[source]#
Create an empty table, returns the index of the created table
- Parameters:
size (
int) – the size of the tablenumchannels – if the table will be used to hold audio, the number of channels of the audio
sr – the samplerate of the audio, if the table is used to hold audio
delay – when to create the table
- Return type:
int- Returns:
the table number
- channelPointer(channel, kind='control', mode='rw')[source]#
Returns a numpy array aliasing the memory of a control or audio channel
If the channel does not exist, it will be created with the given kind and set to the given mode. The returned numpy arrays are internally cached and are valid as long as this Engine is active. Accessing the channel through the pointer is not thread-safe.
- Parameters:
channel (
str) – the name of the channelkind – one of ‘control’ or ‘audio’ (string channels are not supported yet)
mode – the kind of channel, ‘r’, ‘w’ or ‘rw’
- Return type:
ndarray- Returns:
a numpy array of either 1 or ksmps size
See also
Engine.setChannel()
- initChannel(channel, value=0, kind='', mode='r')[source]#
Create a channel and set its initial value
- Parameters:
channel (
str) – the name of the channelvalue (
float|str|ndarray) – the initial value of the channel, will also determine the type (k, a, S)kind – One of ‘k’, ‘S’, ‘a’. Use None to auto determine the channel type.
mode – r for read, w for write, rw for both.
- Return type:
None
Note
the mode is set from the perspective of csound. A read (input) channel is a channel which can be written to by the api and read from csound. An write channel (output) can be written by csound and read from the api
Example
>>> from csoundengine import * >>> e = Engine() >>> e.initChannel("mastergain", 1.0) >>> e.compile(r''' ... instr 100 ... asig oscili 0.1, 1000 ... kmastergain = chnget:k("mastergain") ... asig *= intrp(kmastergain) ... endin ... ''') >>> eventid = e.sched(100) >>> e.setChannel("mastergain", 0.5)
- getControlChannel(channel)[source]#
Get the value of a control channel
- Parameters:
channel (
str) – the name of the channel- Return type:
float- Returns:
the value of the channel. Raises KeyError if the channel does not exist.
- fillTable(tabnum, data)[source]#
Fill an existing table with data
If data is bigger than the table itself, then only the data which fits in the table is copied. If, on the contrary, the data is smaller than the table, then the rest of the table is left unmodified. For more control considere using
getTableData()- Parameters:
tabnum (
int) – the table number of an already existing tabledata (
Union[ndarray,Sequence[float]]) – the data to put into the table
- Return type:
None
- makeTable(data, sr=0, tabnum=-1, delay=0.0)[source]#
Create a new table and fill it with data.
- Parameters:
data (
Union[ndarray,Sequence[float]]) – the data used to fill the tabletabnum (
int) – the table number. If -1, a number is assigned by the engine. If 0, a number is assigned by csound (this operation will be blocking if no callback was given)sr (
int) – only needed if filling sample data. If given, it is used to fill the table metadata in csound, as if this table had been read via gen01delay – when to allocate the table
- Return type:
int- Returns:
the index of the new table
- property now: float#
The current elapsed time
This is the same as
OfflineEngine.elapsedTime()
- playSample(tabnum, delay=0.0, chan=1, speed=1.0, gain=1.0, fade=0.0, starttime=0.0, lagtime=0.01, dur=-1.0)[source]#
Play a sample already loaded into a table.
Speed and gain can be modified via setp while playing
- Parameters:
tabnum (
int) – the table where the sample data was loadeddelay – when to start playback
chan – the first channel to send output to (channels start with 1)
speed – the playback speed
gain – a gain applied to this sample
fade – fadein/fadeout time in seconds
starttime – playback can be started from anywhere within the table
lagtime – a lag value for dynamic pfields (see below)
dur – the duration of playback. Use -1 to play until the end
- Return type:
float- Returns:
the instance number of the playing instrument.
Dynamic Fields
p4: gain
p5: speed
Example
>>> from csoundengine import * >>> e = Engine() >>> import sndfileio >>> sample, sr = sndfileio.sndread("stereo.wav") >>> # modify the samples in python >>> sample *= 0.5 >>> table = e.makeTable(sample, sr=sr, block=True) >>> eventid = e.playSample(table) ... # gain (p4) and speed (p5) can be modified while playing >>> e.setp(eventid, 5, 0.5) # Play at half speed
- automatep(p1, pfield, pairs, mode='linear', delay=0.0, overtake=False)[source]#
Automate a pfield of a scheduled event
- Parameters:
p1 (
float|str) – the fractional instr number of a running event, or an int number to modify all running instances of that instrpfield (
int|str) – the pfield index. For example, if the pfield to modify if p4, pidx should be 4. Values of 1, 2, and 3 are not allowed.pairs (
Union[Sequence[float],ndarray]) – the automation data is given as a flat data. of pairs (time, value). Times are relative to the start of the automation eventmode – one of ‘linear’, ‘cos’, ‘expon(xx)’, ‘smooth’. See the csound opcode interp1d for more information (https://csound-plugins.github.io/csound-plugins/opcodes/interp1d.html)
delay – the time delay to start the automation, relative to the elapsed time
overtake – if True, the first value of pairs is replaced with the current value in the running instance
- Return type:
float- Returns:
the p1 associated with the automation synth
Example
>>> e = OfflineEngine() >>> e.compile(r''' ... instr 100 ... kfreq = p4 ... outch 1, oscili:a(0.1, kfreq) ... endin ... ''') >>> eventid = e.sched(100, 0, 10, args=(1000,)) >>> e.automatep(eventid, 4, [0, 1000, 3, 200, 5, 200])
See also
setp(),automateTable()
- rewind(offset=0.0)[source]#
Unschedule future events and set the time pointer to the given offset
- Return type:
None
- generateCsd()[source]#
Generate a
Csdfrom this OfflineEngineThis can be used to export a project file and use the csound binary to render it. It might also be useful for debugging
- write(outfile)[source]#
Dump this OfflineEngine as a .csd
This will include all code, instruments and opcodes compiled until now as well as any events scheduled, etc.
Any data files added are written to a folder
'<csdfile>.assets'besides the generated .csd file.- Parameters:
outfile (
str) – the path of the generated .csd file- Return type:
None
- includeFile(include)[source]#
Add an #include file to this Engine
- Parameters:
include (
str) – the path to the include file
- playSoundFromDisk(path, delay=0.0, dur=-1, chan=0, speed=1.0, fade=0.01)[source]#
Play a soundfile from disk via diskin2
- Parameters:
path (
str) – the path to the outputdelay – time offset to start playing
dur – duration of playback, use -1 to play until the end of the file
chan – first channel to output to
speed – playback speed (2.0 will sound an octave higher)
fade – fadein/out in seconds
- Return type:
float- Returns:
the instance number of the scheduled event
See also
- setp(p1, *pairs, delay=0.0)[source]#
Modify a pfield of an active note
Multiple pfields can be modified simultaneously. It only makes sense to modify a pfield if a control-rate (k) variable was assigned to this pfield (see example)
- Parameters:
p1 (
int|float|str) – the p1 of the instrument to automate. A float or a “<name>.<instanceid>” will set the value for a specific instance, an int or a unqualified name will set the value of the given parameter for all instances*pairs – each pair consists of a pfield index and a value. The index is an int, matching the pfield number (4=p4, 5=p5, etc), the value can be a number (string values are not supported)
delay – when to start the automation
- Return type:
None
Example
>>> engine = OfflineEngine(...) >>> engine.compile(r''' ... instr foo ... kamp = p5 ... kfreq = p6 ... a0 oscili kamp, kfreq ... outch 1, a0 ... endin ... ''') >>> p1 = engine.sched('foo', args=[0.1, 440], unique=True) >>> p1 'foo.0001' >>> engine.setp(p1, 5, 0.2, delay=0.5)
- assignBus(kind='', value=None, persist=False)[source]#
Assign one audio/control bus, returns the bus number.
Audio buses are always mono.
- Parameters:
kind – the kind of bus, “audio” or “control”. If left unset and value is not given it defaults to an audio bus. Otherwise, if value is given a control bus is created. Explicitely asking for an audio bus and setting an initial value will raise an expection
value (
float|None) – for control buses it is possible to set an initial value for the bus. If a value is given the bus is created as a control bus. For audio buses this should be left as Nonepersist – if True the bus created is kept alive until the user calls
releaseBus(). Otherwise, the bus is reference counted and is released after the last user releases it.
- Return type:
int- Returns:
the bus token, can be passed to any instrument expecting a bus to be used with the built-in opcodes busin, busout, etc.
A bus created here can be used together with the built-in opcodes busout, busin and busmix. A bus can also be created directly in csound by calling busassign
A non-persistent bus is reference counted: it is kept alive as long as there are clients using it and it is released when it is not used anymore. At creation the bus is “parked”, waiting to be used by any client. As long as no clients use it, the bus stays in this state and is ready to be used. A persistent bus stays alive until it is freed via
OfflineEngine.releaseBus()Order of evaluation is important: audio buses are cleared at the end of each performance cycle and can only be used to communicate from a low priority to a high priority instrument.
For more information, see Bus Opcodes
Example
Pass audio from one instrument to another. The bus will be released after the events are finished.
>>> e = OfflineEngine(...) >>> e.compile(r''' ... instr 100 ... ibus = p4 ... kfreq = 1000 ... asig vco2 0.1, kfreq ... busout(ibus, asig) ... endin ... ''') >>> e.compile(r''' ... instr 110 ... ibus = p4 ... asig = busin(ibus) ... ; do something with asig ... asig *= 0.5 ... outch 1, asig ... endin ... ''') >>> bus = e.assignBus("audio") >>> s1 = e.sched(100, 0, 4, (bus,)) >>> s2 = e.sched(110, 0, 4, (bus,)) >>> e.perform()
Modulate one instr with another, at k-rate. NB: control buses act like global variables, the are not cleared at the end of each cycle.
>>> e = OfflineEngine(...) >>> e.compile(r''' ... instr 130 ... ibus = p4 ... ; lfo between -0.5 and 0 at 6 Hz ... kvibr = linlin(lfo:k(1, 6), -0.5, 0, -1, 1) ... busout(ibus, kvibr) ... endin ... ... instr 140 ... itranspbus = p4 ... kpitch = p5 ... ktransp = busin:k(itranspbus, 0) ... kpitch += ktransp ... asig vco2 0.1, mtof(kpitch) ... outch 1, asig ... endin ... ''') >>> bus = e.assignBus() >>> s1 = e.sched(140, 0, -1, (bus, 67)) >>> s2 = e.sched(130, 0, -1, (bus,)) # start moulation >>> e.unsched(s2) # remove modulation >>> e.writeBus(bus, 0) # reset value >>> e.unschedAll()
See also
writeBus(),readBus(),releaseBus()
- releaseBus(bus, delay=None)[source]#
Release a persistent bus
- Parameters:
bus (
int) – the bus to release, as returned byOfflineEngine.assignBus()delay (
float|None) – when to release the bus. None means now
- Return type:
None
See also
- writeBus(bus, value, delay=0.0)[source]#
Set the value of a control bus
Normally a control bus is set via another running instrument, but it is possible to set it directly from python. The first time a bus is set or queried there is short delay, all subsequent operations on the bus are very fast.
- Parameters:
bus (
int) – the bus token, as returned viaEngine.assignBus()value (
float) – the new valuedelay – if given, the modification is scheduled in the future
- Return type:
None
See also
readBus()assignBus()automateBus()Example
>>> e = Engine(...) >>> e.compile(r''' ... instr 100 ... ifreqbus = p4 ... kfreq = busin:k(ifreqbus) ... outch 1, vco2:a(0.1, kfreq) ... endin ... ''') >>> freqbus = e.assignBus(value=1000) >>> e.sched(100, 0, 4, args=[freqbus]) >>> e.writeBus(freqbus, 500, delay=0.5)