Workspace

class maelzel.core.workspace.Workspace(config=None, scorestruct=None, dynamicCurve=None, updates=None, active=False)[source]

Bases: object

Create a new Workspace

Parameters:
  • scorestruct (ScoreStruct | None) – the ScoreStruct. If not given, a default scorestruct (4/4, q=60) is used

  • config (CoreConfig | None) – the active config for this workspace. If None, a copy of the root config is used

  • updates (dict[str, Any] | None) – updates the config

  • dynamicCurve (DynamicCurve | None) – a DynamicCurve used to map amplitude to dynamic expressions

  • active – make this Workpsace active

A Workspace can also be used as a context manager, in which case it will be activated when entering the context and deactivated at exit

from maelzel.core import *
scorestruct = ScoreStruct(r'''
4/4, 60
.
3/4
5/8, 72
''')
notes = Chain([Note(m, start=i) for i, m in enumerate(range(60, 72))])
# Create a temporary Workspace with the given scorestruct and a clone
# of the root config
with Workspace(scorestruct=scorestruct, updates={'quant.complexity': 'low'}):
    notes.show()

Attributes Summary

a4

The reference frequency in this Workspace

active

The currently active workspace

config

The CoreConfig for this workspace

presetManager

Returns the preset manager for this Workspace

root

The root workspace.

scorestruct

The default ScoreSctruct for this Workspace

Methods Summary

activate()

Make this the active Workspace

amp2dyn(amp)

audioSession([outdev, backend, numchannels, ...])

Get the audio Session used for playback

clearCache()

Cleat the Workspace cache.

clone([config, scorestruct, active])

Clone this Workspace

deactivate()

Deactivates this Workspace and sets the previous Workspace as active

getTempo([measureNum])

Get the quarternote tempo at the given measure

isActive()

Is this the active Workspace?

isAudioSessionActive()

Returns True if the sound engine is active

presetsPath()

The path where instrument presets are read/written

recordPath()

The path where temporary recordings are saved

reverbInfo()

Returns information about this workspace's reverb

reverbSynth()

The reverb synth used for live playback

setDynamicCurve([shape, mindb, maxdb])

Set a new dynamic curve for this Workspace

setRecordPath(path)

Set the path where temporary recordings are saved

setReverb([gaindb, delayms, decay, damp, init])

Set parameters for reverb synth

setScoreStruct([score, tempo])

Sets the score structure for the current Workspace

setTempo(tempo[, reference, measureIndex])

Set the current tempo for the active scorestruct

Attributes Documentation

a4

The reference frequency in this Workspace

active: _t.ClassVar[Workspace] = Workspace(scorestruct=ScoreStruct(4/4, tempo=60), config={}, dynamicCurve=DynamicCurve(shape=expon(0.3), mindb=-60.0, maxdb=0.0))

The currently active workspace

config

The CoreConfig for this workspace

presetManager

Returns the preset manager for this Workspace

At the time there is one preset manager shared by all workspaces

Returns:

The preset manager

root: _t.ClassVar[Workspace] = Workspace(scorestruct=ScoreStruct(4/4, tempo=60), config={}, dynamicCurve=DynamicCurve(shape=expon(0.3), mindb=-60.0, maxdb=0.0))

The root workspace. This is the workspace active at the start of a session and is always kept alive since it holds a reference to the root config. It should actually never be None

scorestruct

The default ScoreSctruct for this Workspace

Methods Documentation

activate()[source]

Make this the active Workspace

This method returns self in order to allow chaining

Return type:

Workspace

Example

>>> from maelzel.core import *
>>> from pitchtools import *
>>> w = Workspace(updates={'A4': 432}).activate()
>>> n2f("A4")
432
>>> w.deactivate()
>>> n2f("A4")
442
amp2dyn(amp)[source]
Return type:

str

audioSession(outdev='', backend='', numchannels=None, buffersize=0, numbuffers=0, **kws)[source]

Get the audio Session used for playback

Arguments are ignored if a session is already active

Parameters:
  • outdev – output device used. Depends on the backend used. List all devices via maelzel.core.playback.getAudioDevices, use ‘?’ to select from a list of devices.

  • backend – backend, depends on your platform. Use ‘?’ to interactively select one

  • numchannels (int | None) – number of channels used. Defaults to the number of channels of the audio device used

  • buffersize (int) – buffer size to use, depends on the backend and device used

  • numbuffers (int) – number of buffers, determines the blocksize depending on the backend

  • **kws – any keyword argument is passed to maelzel.core.playback.getSession

Return type:

csoundengine.session.Session

Returns:

the csoundengine.Session active for this workspace. If not already created, a new session is started

static clearCache()[source]

Cleat the Workspace cache.

At the moment this cache includes only the image generated via .show

Return type:

None

clone(config=None, scorestruct=None, active=False)[source]

Clone this Workspace

Parameters:
  • config (Optional[CoreConfig]) – the config to use. Leave unset to clone this Workspace’s config.

  • scorestruct (Optional[ScoreStruct]) – if unset, use this Workspace’s scorestruct

  • active – if True, activate the cloned Workspace

Return type:

Workspace

Returns:

the cloned Workspace

Example

>>> from maelzel.core import *
>>> myworkspace = getWorkspace().clone()
>>> myworkspace.config['A4'] = 432
>>> with myworkspace as w:
...     # This will activate the workspace and deactivate it at exit
...     # Now do something baroque
deactivate()[source]

Deactivates this Workspace and sets the previous Workspace as active

Note

There is always an active Workspace. An attempt to deactivate the root Workspace will be ignored

Return type:

None

Returns:

the now active workspace

getTempo(measureNum=0)[source]

Get the quarternote tempo at the given measure

Return type:

float

isActive()[source]

Is this the active Workspace?

Return type:

bool

isAudioSessionActive()[source]

Returns True if the sound engine is active

Return type:

bool

static presetsPath()[source]

The path where instrument presets are read/written

Return type:

str

Example

Running in linux

>>> from maelzel.core import *
>>> path = getWorkspace().presetsPath()
>>> path
'/home/XXX/.local/share/maelzel/core/presets'
>>> os.listdir(path)
['.click.yaml',
 'click.yaml',
 'noise.yaml',
 'accordion.yaml',
 'piano.yaml',
 'voiceclick.yaml']
recordPath()[source]

The path where temporary recordings are saved

We do not use the temporary folder because it is wiped regularly and the user might want to access a recording after rebooting. The returned folder is guaranteed to exist

The default record path can be customized by modifying the config ‘rec.path’ :rtype: str

reverbInfo()[source]

Returns information about this workspace’s reverb

Return type:

dict[str, Any]

Returns:

a dict with reverb settings corresponding to the values which can be set via setReverb(). Modifications to this dictionary have no side effects.

reverbSynth()[source]

The reverb synth used for live playback

Return type:

csoundengine.synth.Synth | None

Returns:

the reverb synth or None if no synth using reverb has been scheduled

setDynamicCurve(shape='expon(0.5)', mindb=-80, maxdb=0)[source]

Set a new dynamic curve for this Workspace

Parameters:
  • shape – the shape of the curve

  • mindb – the db value mapped to the softest dynamic

  • maxdb – the db value mapped to the loudest dynamic

Return type:

None

setRecordPath(path)[source]

Set the path where temporary recordings are saved

Parameters:

path (str) – the new path. It must be an existing path

Return type:

None

setReverb(gaindb=None, delayms=None, decay=None, damp=None, init=False)[source]

Set parameters for reverb synth

This modifies the running reverb and/or sets any values for reverb if used in the future or used for offline rendering. Only values passed are modified, None indicates to use the current value/default value. Default values can be modified via the config (ie. getWorkspace().config['reverbGaindb'] = -3). To check the current values, see ???

Parameters:
  • gaindb (Optional[float]) – gain of reverb, in dB. Default: -6 (config: reverbGaindb)

  • delayms (Optional[int]) – predelay, in milliseconds. Default: 60 (config: reverbDelayms)

  • decay (Optional[float]) – decay time in seconds. Default: 3 (config: reverbDecay)

  • damp (Optional[float]) – damping factor between 0-1 (lower=less damping). Default: 0.2 (config: reverbDamp)

  • init – if True, start the reverb synth if not started already. This will start the audio session if needed

Return type:

None

setScoreStruct(score=(4, 4), tempo=60)[source]

Sets the score structure for the current Workspace

This is the same as ScoreStruct(...).activate()

If given a ScoreStruct, it sets it as the active score structure. As an alternative a score structure as string can be given, or simply a time signature and/or tempo, in which case it will create the ScoreStruct and set it as active

Parameters:
  • score (str | ScoreStruct | tuple[int, int]) – the scorestruct as a ScoreStruct, a string score (see ScoreStruct for more information about the format) or simply a time signature.

  • tempo (Fraction | int | float) – the quarter-note tempo. Only used if no score is given

Return type:

None

See also

  • getScoreStruct()

  • setTempo() (modifies the tempo of the active scorestruct)

  • ScoreStruct

  • getWorkspace()

Example

>>> from maelzel.core import *
>>> w = getWorkspace()
>>> w.scorestruct = ScoreStruct(tempo=72)
>>> w.setScoreStruct(r'''
... 4/4, 72
... 3/8
... 5/4
... .         # Same time-signature and tempo
... , 112     # presetSame time-signature, faster tempo
... 20, 3/4, 60   # At measure index 20, set the time-signature to 3/4 and tempo to 60
... ...       # Endless score
... ''')
setTempo(tempo, reference=1, measureIndex=0)[source]

Set the current tempo for the active scorestruct

Parameters:
  • tempo (float) – the new tempo.

  • reference – the reference value (1=quarternote, 2=halfnote, 0.5: 8th note)

  • measureIndex – the measure number to modify. The scorestruct’s tempo is modified until the next tempo

Return type:

None

Example

from maelzel.core import *
# A chromatic scale of eighth notes
scale = Chain(Note(m, dur=0.5)
              for m in range(60, 72))

# Will play 8th notes at 60
scale.play()

w = getWorkspace()
w.setTempo(120)
# Will play at twice the speed
scale.play()

# setTempo is a shortcut to ScoreStruct's setTempo method
w.setTempo(40)
>>> setScoreStruct(ScoreStruct(r'''
... 3/4, 120
... 4/4, 66
... 5/8, 132
... '''))
>>> w = getWorkspace()
>>> w.setTempo(40)
>>> w.scorestruct.dump()
0, 3/4, 40
1, 4/4, 66
2, 5/8, 132