At the beginning of 2017, it was almost 10 years ago when I did my first steps in systematically ordering and extending personal SC tools. At that time I already had some experience in SC, but project-oriented composition was my main focus. Meanwhile miSCellaneous lib has grown and when I look at its readme file, although I always tried to keep stuff documented properly, I doubt that the connections between the different classes would be easy to get at a first glance. Topics accumulated, some help files have become huge (VarGui, PbindFx) and a lot of examples and documented (extra-)features might hide the basic motivations. As I was asked by colleagues at the Institute of Electronic Music and Acoustic Graz (IEM) we organized a one-day lecture/workshop on miSCellaneous lib on November 5th, 2016, and this tutorial summarizes the overview given then. At that point I'd like to say that I'm very grateful to IEM Graz and the interested SC community from here and abroad for support and feedback, we are going to have further SC meetings at the same place – Hanns Holger Rutz already continued in December. There's also a focus on artistic research here at IEM, and research projects, events and discussions are lighting an ongoing discourse in the field between art and science, creating an inspiring environment.
Concerning the structure of this file: after a brief history and a grouping of content the tour will guide through selected topics in an order which, hopefully, will outline the central ideas. It will start with VarGui, PLx, then go over PbindFx, EventShortcuts to live coding aspects of PLx, continue with independent classes, class families, methods and SC tutorials and end with the Buffer Granulation tutorial, which again integrates some of the previous topics. PbindFx gets more space, as it's in my recent focus and you can use it for a number of things which are not, or at least not easily doable in plain SC. To a large extent the tour consists of references to selected already existing examples, which are spread over various help files. Conitinuative, but less central topics are marked as such, as well as some legacy code, which is still working, but not very relevant, as other possibilities have been invented meanwhile. A few new examples have been added, the reader is invited to check the exercises and to have fun with his/her favourite instrument resp. effect SynthDefs.
In 2007 / 08 I was working at ZKM Karlsruhe, preparing a piece for flute and multichannel electronics (Lokale Orbits / Solo 3). Then I thought it would be useful to order and document my tools, by doing so my programming would – hopefully – not only be useful for me but for others too and I would be able to give something back to the open source community, from which I have been getting so much valuable input. Also I noticed that a better structuring of code together with the need of documentation stimulated reflection and development and significantly improved the functionality of my tools also just for personal use.
Lokale Orbits is a series of works for small instrumentations and multichannel tape where recordings with involved musicians were the base for granular processings. From the beginning miSCellaneous lib was developed in parallel to the needs that came from that artistic motivation. The first particular motivation was related to the fundamental architecture of SC – the division between language and server – and its consequences for granular synthesis. I never wanted to spend much time in gui programming, but I wanted to have a multi-purpose gui that would easily let me experiment with granular synthesis driven by language (patterns in particular) and server (granulation ugens). It should also be easy to combine these different controls in a single patch, e.g. fine-tune the parameters of a LFO and those of a Pattern resp. the derived running EventStreamPlayer at the same time. This need led to the development of the VarGui interface. It is the the oldest part and, so to speak, the kernel of miSCellaneous, already contained in the first public release of 2009. A player section and a number of features was added in 2011. Thus VarGui doesn't use SC's extended gui features which came up with the invention of Qt and if I had to build something from scratch I'd certainly look for a revised code structure, nevertheless VarGui reliably served my needs quite well over a long period of time. The twofold control option (environmental variables and synth args) turned out to be useful in many contexts, also the handling of arrays (environmental variables as well as synth args) is quite practical and allows a quick instantiation of huge slider+player guis.
Between 2009 and 2016 a number of pattern families was added, some of them with granular synthesis in mind. The one I'm using most is the PLx proxy pattern family which takes advantage of environmental variables and dynamic scoping and goes well together with the VarGui interface concerning control of running Patterns/EventStreamPlayers. PLx also opens nice opportunities for live-coding with very condensed syntax. I'm not doing this on stage but I see live-coding as valuable part of a dynamic compositional process. As a side remark, PLx patterns mirror most of SC's main lib patterns and can also be used as non-proxies. In contrast to main lib's list patterns they default to repeats = inf, which probably saved myself the typing of many thousands of 'infs' over the years.
Another part of miSCellaneous is a number of tutorials, which I added from time to time. Some refer to general SC topics, independent from miSCellaneous (e.g. Event patterns and array args), others to topics specific to miSCellaneous (e.g. PLx and live coding with Strings) and in some I tried a general overview of principal SC strategies, but also used examples with features of miSCellaneous (Buffer Granulation). Finally there's other stuff that doesn't fall into the above categories, e.g. the class EventShortcuts for customized shortcuts with Events and event patterns. Classes related to nonlinear dynamics (single sample feedback with Fb1, generailzed functional iteration synthesis with GFIS) have been added in 2018, Fb1_ODE and related, a framework for general ordinary differential equation integration of initial value problems in 2019.
The VarGui class help file as well VarGui_shortcut_builds are both bloated with information, so I'd like to give just a few examples and references here in order to show its basic features.
For basic control of a self-defined Synth/SynthDef by passing control specs see this example in VarGui help.
For control of multiple Synths/SynthDefs see this example in the same file below.
It's often more practical to pass control specs as SynthDef metadata as done in Ex.1a of the Buffer Granulation tutorial.
Exercise: Control your own (sustained) SynthDef with VarGui, either use SynthDef metadata or VarGui's argument 'synthCtr' for passing specs. |
For basic control of an environmental variable in combination with a Pbind run this example in VarGui help.
These examples show the application of dynamic scoping. A Function has been defined with an "unconnected" free variable and the players evaluate the Function in different Environments provided by the VarGui. Setting the sliders affects the variable of the same name in different Environments of different players.
This example used a Pfunc, but it works the same with PLx patterns, we take a look at them and leave VarGui for a moment.
Pdef and Pdefn are main lib's proxies for replacement of event patterns and non-event patterns. PL is the most general PLx proxy, taking over some combined functionality of Pdef and Pdefn on the base of dynamic scoping, go through the examples of the help file PL to see how it works with value and event patterns.
Though what neither PL nor Pdef/Pdefn can provide is the replacement of pure lists or list items in the case of list patterns. There's a main lib workaround with a combination of Pn and Plazy (PLx suite, Ex.1a), but it isn't satisfying for several reasons, so I suppose that PLx list patterns like PLseq are amongst the most useful ones of the whole PLx family, e.g. see PLx suite, Ex.1b. Other PLx list patterns like PLrand, PLwrand, PLser, PLshuf, PLshufn, PLswitch etc. work similar.
There exists also a number of non-list PLx patterns, have a look at PLwhite as a typical example.
Exercise: Play your own enveloped SynthDef (or take default SynthDef with params: freq, amp, pan) with some PLx patterns and perform live replacements as in the examples above. |
See VarGui, Ex.1a, for basic step sequencing with PLseq, the array variable is implicitely defined in VarGui's first arg.
See VarGui, Ex.1c, for multiple players and array variables and control of multiple sliders and buttons with modifier keys (note that not all functionality might be available on all platforms).
See VarGui, Ex.4a, for a sequencing setup with some PLs used. But more interesting here is that each synth reads is base frequency from a control bus, which gets its data from a separate synth. Synth and EventStreamPlayer are both controlled from the gui. The two slider blocks on the left side concern Synth settings (above) and variable setting for the Pbind / EventStreamPlayer (below). Accordingly we have two players on the right side. Try running the player and starting and stopping the control synth.
Buffer Granulation, Ex.2a, shows basic language-driven granulation, gui values are taken over by PL patterns and Pfunc.
Exercise: Write a combination of an event pattern and PLx patterns as above with your own SynthDef and play it with a VarGui. Note that it's not necessary to control all args by the gui, nor is it necessary to control parameters directly: you can e.g. control bounds for midinotes in the gui and define the calculation for the actual midinote (e.g. random selection) in the event pattern: |
PbindFx is an event pattern for effect handling on per-event base. There are other ways for working with event patterns and effects, already possible with main lib, but they have disadvantages: with Pfx and Pfxb there is no built-in way to sequence effect types or effect parameters, you could also route the event's audio to effect buses, but for overlapping events with different fx graphs/params you'd have to define additional buses beforehand as in Ex. 4a.
First go to PbindFx, Ex. 1a, reboot server with extended ressources and evaluate source and fx synths.
Exercise: Play your own (percussive + stereo) SynthDef (or instrument 'source') with an arbitrary sequencing of no fx and echos (by defining 'fxOrder') and echo params as in Ex. 4c. Note that in fx 'echo' the max echoDelta defaults to 0.2. |
For each event several issues have to be internally considered by PbindFx: building and checking of fx graphs (no cycles !), cleaning buses from possibly remaining residual audio (adding "zero synths"), splitting (in case of parallel parts in the fx graph), grouping of all event-related synths and checking accumulated cleanup delay times. You might skip that for the moment, but for a more detailled overview see Principle of operation, as well as for a listing of conventions.
See PbindFx, examples 1a and 1b.
See PbindFx, examples 2a, 2b, 2c, 2d.
Exercise: Play your own (percussive + stereo) SynthDef (or instrument 'source') with an arbitrary sequencing of fx chains (your fxs and/or fxs from PbindFx help). Maybe just extend your last own example. |
It seems to be a still underestimated option to design effect graphs different from simple chains. In a classical DAW interface a pile of slots for effects in chain is common, although more differentiated possibilities are also there. Considering event sequencing with PbindFx we can select fx graphs per event / grain, in addition to the sequencing of fx parameters itself. See PbindFx, Ex.10a, for a parallel application of echo, note the syntax of the event graph, passed as Event to 'fxOrder'.
Exercise: Compare the sound of the two fx graphs given in Ex.10a, also try the following or similar, how do the corresponding fx graphs look like ? |
See PbindFx, Ex. 10b and 10c for modulation graphs and their sequencing.
Exercise: Play your own (percussive + stereo) SynthDef (or instrument 'source') with an arbitrary sequencing of fx *graphs* (your fxs and/or fxs from PbindFx help). Maybe just extend your last own example. |
This can simple be done by passing arrays within fxData, see PbindFx, Ex.4a.
A further option for parallelism, a typical case would be the application of different effects to the notes of a chord, see PbindFx, Ex.3b (rather straight than 3a).
See PbindFx, Ex.7a for replacement of key streams.
Up to now PbindFx got lists as args in all examples. As args can be event patterns too, they can also be proxy patterns which opens the door for various unusual kinds of source and fx replacements, see PbindFx Ex. 7b and 7c.
Exercise: Take one of your previous working PbindFx examples and rewrite its args (arrays of key/value pairs) as PL or Pbindef proxies. Run the example and replace source and/or fx patterns on the fly. |
For use with VarGui see PbindFx, Ex.8.
For using one fx SynthDef in more than one fxData see PbindFx, Ex.4.
For source and fxs reading from external buses (ar or kr) see PbindFx, Ex.6a-c.
For using value conversions with fxData see PbindFx, PbindFx, Ex.9.
One motivation for the development of PbindFx was the idea to explore granular synthesis variants with differentiated effect processings. The fixed media composition kitchen studies collects six short pieces with different fxs and handlings of fx sequencing, each derived from the kitchen sound of five seconds, which is already contained in miSCellaneous lib. At the same time kitchen studies is an ongoing artistic research project: the commented source code is published in the tutorial kitchen_studies, compressed versions of the original piece as a whole and its parts can be found on my website http://daniel-mayer.at (use a separate browser, players won't work within this window), a further documentation of the compositional process will follow as publication in the artistic research database Research Catalogue (http://researchcatalogue.net).
EventShortcuts is an interface for defining your own shortcut keys for often used keyword in Events and event patterns. For example you might want to write 'inst' or just 'i' instead of 'instrument' etc., then define your collection of shortcuts – e.g. in your startup or a certain load file – and activate it on occasion. There is also a default shortcuts dictionary, see its content and play a simple example:
For examples of (re-)defining or extending shortcut dictionaries see EventShortcuts.
Exercise: Take one of your favourite SynthDefs with non-standard arguments (other than freq, amp, pan, etc.) and write an event pattern example, using these arguments. Then choose useful abbreviations, define a new shortcut dictionary with these (either by extending the default or by defining a new one), make it current and run the event pattern example with abbreviated keys. |
This was not my main focus from the beginning, but it turned out that PLx patterns, in combination with EventShortcuts and/or Character sequencing (tour 6b) open up live coding possibilities with very condensed syntax.
PLbindef is a wrapper class for Pbindef, which allows replacements in pseudo-method syntax in a newly created Environment.
For further examples see PLbindef.
PLbindefPar is also based on Pbindef, but unlike PLbindef it's not a plain wrapper: it employs a number of Pbindefs in parallel, which allows control of polyphonic, additive or granular structures, see PLbindefPar.
Already in plain SC Strings as Arrays of Characters can be used for sequencing. PLx patterns fit and continuate this concept, see PLx_and_live_coding_with_Strings for some options, also in connection with PLbindef, PLbindefPar and PbindFx.
These are a bit paradoxical classes: Patterns which behave as if they were Streams, thus have an internal state and remember its last value(s), which can e.g. be used for recursion or certain demands of repeated embedding as in the following example:
See PSx_stream_patterns for an overview.
Sieves, recommended by Iannis Xenakis as generative principles for arbitrary musical parameters, are implemented twice: with the class Sieve and Psieve patterns, which adapt the sieve calculus for realtime interactions. The tutorial Sieves_and_Psieve_patterns starts from scratch, thus can be studied completely independent from other miSCellaneous stuff and most other SC requirements. The last chapter gives some audio examples, granular rhythms might be an especially interesting application.
PmonoPar follows the Pmono convention of a single synth, being set but extends it to an arbitrary number of differently timed setting streams. With PpolyPar the number of continously running synths is arbitrary as well and setting streams can switch the synths to set. That way complicated fx variations can be achieved by a paradigm different from PbindFx.
A general tool, which can be used for many enumeration and optimization problems (sets, partitions, graphs etc.), melodic shapes and scales are possible musical applications, see enum.
A framework for using server-generated values in Pbind-like objects in the language. A bit outdated now, as synchronous bus gives easy access to server values, however the double-latency mechanism provides a good accuracy of values – if this is needed – by passing a high granularity parameter. A lower value minimizes OSC traffic if this is more important. See Guide_to_HS_and_HSpar.
A dynamic multi-layer pulse divider based on Pspawner, as the latter it supports parallel and sequential sprouting of sub-patterns. Might be used for line ornamentation, polyrhythmical structures, granulation etc., see PSPdiv.
A suite of pseudo ugens, see Smooth_Clipping_and_Folding.
pseudo ugens for crossfaded mixing and fanning according to demand-rate control, see DX_suite.
patterns and drate ugen searching for numbers with integer distance from a source pattern / signal, see Idev_suite.
pseudo ugens for single sample feedback and generalized functional iteration synthesis, see Fb1 and GFIS. General ordinary differential equation integration, see Fb1_ODE and related classes.
pseudo ugens for zero crossing analysis and playing sequences of segments between them with demand rate control, see ZeroXBufWr, ZeroXBufRd, TZeroXBufRd.
This tutorial is about dynamic scope, comparing the behaviour of Functions, Streams and EventStreamPlayers in Environments. It's thus treating some preconditions which are relevant for PLx_suite and VarGui, see Event_patterns_and_Functions.
Continuous (with LFO) and discrete ("LFO-like") control strategies for event patterns are compared in Event_patterns_and_LFOs.
SynthDef array args seem to be a sometimes confusing topic, especially when it's about (pseudo-)variable array lengths and Envelopes, this is even more the case when it comes to the sequencing of such synths. For this reason, and not at last to remind myself to the subtle syntax differences, I wrote this tutorial: Event_patterns_and_array_args.
Actually scheduled as a general overview of granulation possibilities in SC, also collecting various ideas from the sc-users mailing list discussions, I have to admit that in its current form many examples, especially in the Buffer granulation tutorial, require one or more features of miSCellaneous and thus might not always be easy to follow. Then again it would be hard to write such (gui) examples without presuppositions and at the same time with a clearly representable amount of code. However I hope that based on this guided tour it might be easier to step through for people who haven't used this lib before, see Buffer_Granulation and Live_Granulation.