Skip to content

Commit

Permalink
docs
Browse files Browse the repository at this point in the history
  • Loading branch information
gesellkammer committed Apr 24, 2024
1 parent 772a798 commit aecc33f
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 42 deletions.
95 changes: 57 additions & 38 deletions docs/Introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,42 +42,49 @@ csound code and schedule events without any overhead.
# of the running instrument, which can be used to further control it
event = engine.sched("synth", args=[48, 0.2, 3000, 4])
A csound process is launched by creating a new Engine. One difference to *csound* here is
that **csoundengine** will query the system regarding audio backend, audio device,
number of channels, samplerate, etc., for any option that is not explicitly given
(instead of using some arbitrary default). For example, in linux **csoundengine**
will first check if jack is running and use that as backend, or fallback to using portaudio
otherwise (the order can be configured). If not given an audio device it will use the default
device for the backend and will query the number of channels and use that as
the `nchnls` (number of channels) option.

Another difference to notice is that in **csoundengine** instruments can declare
*pfields* as dynamic values (*k-variables*), which can be modulated after the
event has started.
A csound process is launched by creating a new Engine. **csoundengine** will query the
system regarding audio backend, audio device, number of channels, samplerate, etc.,
for any option that is not explicitly given. For example, in linux **csoundengine**
will first check if jack is running (either as jack itself or within pipewire) and,
if so, use that as backend, or fallback to using portaudio otherwise. If not specified
otherwise, **csoundengine** will use the default audio devices for the backend and query
the number of channels and samplerate to match them.

.. code-block:: python
An :class:`~csoundengine.engine.Engine` uses the csound API to communicate with
csound. **All audio processing is run in a thread with realtime priority to avoid
dropouts**

# Change midinote. setp means: set p-field. This sets p4 (kmidinote) to 50
engine.setp(event, 4, 50)
Built-in instruments
~~~~~~~~~~~~~~~~~~~~

# Modify cutoff (p6)
engine.setp(event, 6, 1000, delay=4)
An :class:`~csoundengine.engine.Engine` provides built-in functionality to
perform common tasks. For example:

# Stop the synth
engine.unsched(event)
* :meth:`~csoundengine.engine.Engine.readSoundfile`: loads a soundfile into a table
* :meth:`~csoundengine.engine.Engine.playSample`: plays a sample from a previously loaded table
* :meth:`~csoundengine.engine.Engine.playSoundFromDisk`: plays an audio file directly from
disk, without loading the sample data first
* :meth:`~csoundengine.engine.Engine.testAudio`: tests the Engine's output

Modulation / Automation
~~~~~~~~~~~~~~~~~~~~~~~

An :class:`~csoundengine.engine.Engine` uses the csound API to communicate with
csound. All audio processing is run in a thread with realtime priority to avoid
dropouts.
Within **csoundengine** instruments can declare *pfields* as dynamic values (*k-variables*),
which can be modified, modulated and / or automated after the event has started. Notice
that in the definition of the 'synth' instrument, ``kmidinote = p4`` or ``kcutoff = p6``
assign a parameter (``p4``, ``p6``) to a control variable.

Built-in instruments
~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
# Schedule an event with a unique id
event = engine.sched("synth", dur=20, args=[48, 0.2, 3000, 4])
# Change midinote. setp means: set p-field. This sets p4 (kmidinote) to 50
engine.setp(event, 4, 50)
# Automate cutoff (p6), from 500 to 2000 hz in 3 seconds, starting in 4 seconds
engine.automatep(event, 6, (0, 500, 3, 2000), delay=4)
An :class:`~csoundengine.engine.Engine` provides built-in functionality to
perform common tasks, like reading a soundfile (:meth:`~csoundengine.engine.Engine.readSoundfile`),
playing a sample from a table (:meth:`~csoundengine.engine.Engine.playSample`) or from disk
(:meth:`~csoundengine.engine.Engine.playSoundFromDisk`)
----------------------------------
Expand All @@ -90,10 +97,11 @@ Each Engine can have an associated :class:`~csoundengine.session.Session`. A Ses
higher level interface, allowing to:

* Define instrument templates (an :class:`~csoundengine.instr.Instr`), which can be
instantiated at any order of evaluation, allowing to implement processing chains
instantiated at **any order of evaluation**, allowing to implement **processing chains**
of any complexity
* An :class:`~csoundengine.instr.Instr` can have named parameters which can be
used to control the scheduled event.
* Define **named parameters** and **default values**. An :class:`~csoundengine.instr.Instr`
can use named parameters and assign default values; when an instrument is scheduled,
only parameters which diverge from the default need to be passed.
* A :class:`~csoundengine.session.Session` provides a series of built-in
:class:`~csoundengine.instr.Instr`'s to perform some common tasks, like playing
samples from memory or from disk, perform audio analysis, etc.
Expand All @@ -103,10 +111,18 @@ higher level interface, allowing to:
from csoundengine import *
# Create an Engine and a corresponding Session. It is possible to be specific about
# Engine parameters.
# When a session is created, the underlying Engine is created as well. The engine
# is thus created with default values
session = Session()
# If the Engine needs to be customized in some way, then the Engine needs to be
# created first
session = Engine(nchnls=4, ksmps=32).session()
# An Engine has only one Session assigned to it. Calling .session() on the engine
# again will return the same session
assert session.engine.session() is session
# define instruments
session.defInstr("synth", r'''
|ibus, kmidi=60, kamp=0.1, ktransp=0, ifade=0.5|
Expand All @@ -132,7 +148,7 @@ higher level interface, allowing to:
outch 1, asig
''')
# create a master audio channel
# create a master audio bus
masterbus = session.assignBus()
# Start a master instance at the end of the evaluation chain
Expand Down Expand Up @@ -209,7 +225,7 @@ A :class:`Renderer` can also be created from an existing :class:`Session`, eithe
:class:`Renderer` is created in which all instruments and
data defined in the Session are also available.

Taking the first example, the same can be rendered offline by modifying this:
Taking the first example, the same can be rendered offline by placing this:

.. code-block:: python
Expand All @@ -229,7 +245,7 @@ Taking the first example, the same can be rendered offline by modifying this:
filt.automatep('kcutoff', [0, 2000, dur*0.8, 500, dur, 6000], delay=start)
with this:
inside the ``rendering`` context manager:

.. code-block:: python
Expand Down Expand Up @@ -262,6 +278,7 @@ this knowledge into a wrapper which is flexible for advanced use cases but enabl
user to start and control a csound process very easily. See below for a detailed description of
*csoundengine* ´s features


Features
--------

Expand All @@ -280,8 +297,10 @@ Features
in order to minimize latency and/or increase performance.
* **Automation** - *csoundengine* provides a built-in method to automate the parameters of a
running event, either via break-point curves or in realtime via any python process.
See :meth:`Engine.automatep() <csoundengine.engine.Engine.automatep>` or
:meth:`Engine.setp() <csoundengine.engine.Engine.setp>`
See :meth:`Engine.automatep() <csoundengine.engine.Engine.automatep>`,
:meth:`Engine.setp() <csoundengine.engine.Engine.setp>` or the corresponding
:class:`~csoundengine.synth.Synth` methods: :meth:`~csoundengine.synth.Synth.set` and
:meth:`~csoundengine.synth.Synth.automate`
* **Bus system** - an :class:`~csoundengine.engine.Engine` provides a bus system (both for
audio and control values) to make communication between running events much easier. See
:meth:`~csoundengine.engine.Engine.assignBus` and :ref:`Bus opcodes<busopcodes>`
Expand Down
17 changes: 17 additions & 0 deletions docs/_static/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,20 @@
table.autosummary {
margin-bottom: 2rem;
}


/*
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
text-decoration-thickness: max(3px, .0625em);
}
*/


a.headerlink {
visibility: hidden;
}
16 changes: 14 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#
import os
import sys

from sphinxawesome_theme import ThemeOptions

sys.path.insert(0, os.path.abspath('../'))


Expand All @@ -36,7 +39,12 @@
'sphinx_autodoc_typehints',
'sphinx.ext.viewcode',
'sphinx.ext.inheritance_diagram',
'sphinx.ext.graphviz'
'sphinx.ext.graphviz',
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.extlinks",
"sphinx_design",
"sphinxawesome_theme.highlighting",
]

# Add any paths that contain templates here, relative to this directory.
Expand All @@ -54,7 +62,8 @@
# a list of builtin themes.
#
# html_theme = 'piccolo_theme'
html_theme = 'sphinx_book_theme'
# html_theme = 'sphinx_book_theme'
html_theme = 'sphinxawesome_theme'

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
Expand Down Expand Up @@ -94,8 +103,11 @@

html_theme_options = {
'navigation_depth': 3,
'awesome_headerlinks': True
}

html_css_files = [
'custom.css',
]


4 changes: 2 additions & 2 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ numpyx
appdirs
sphinx-autodoc-typehints
sphinx-automodapi
piccolo-theme
autodocsumm
sphinx_book_theme
sphinxawesome_theme
sphinx_design

0 comments on commit aecc33f

Please sign in to comment.