8000 GitHub - egelor/tiny-sc: Compact but powerful tools for SuperCollider, with Emacs Org-mode intergration
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
/ tiny-sc Public
forked from iani/tiny-sc

Compact but powerful tools for SuperCollider, with Emacs Org-mode intergration

Notifications You must be signed in to change notification settings

egelor/tiny-sc

 
 

Repository files navigation

Tiny-sc

Compact coding tools for SuperCollider, with Emacs Org-mode intergration

(IZ Tue, 25 Feb 2014 16:20:26ff)

Abstract

The purpose of this library is to provide simple and short solutions for some relatively complex or arduous recurring tasks in SuperCollider. It is hoped that it will make working with SuperCollider easier, at any level. The following sections introduce features of the library through examples.

Examples are added here after being tested. More details about what tiny-sc sets out to do are found in files Roadmap.org and BasicIdeas.org.

Basic synth handling

Associating symbols with synths, starting, stopping with fadeout, replacing the stored synth in the same symbol:

Try the following, one line at a time:

// Start a synth and store it in a name
{ WhiteNoise.ar } => \sound;
// Stop The sound with the default fade-out duration
\sound.fadeOut;
// Restart the stored sound - remake the synth.
\sound.start;
// Replace the synth at \sound with another one
{ SinOsc.ar(440) } => \sound;
// Replace again, fading-out the previous sound in 5 seconds
{ PinkNoise.ar } =>.5 \sound;
// Floating point durations must be given through a message
{ GrayNoise.ar(Decay.kr(Dust.kr(5))) } => \sound.fadeOut(0.5);
// Output channel can be set
1 => ~out;
// So can the amplitude
0.01 => ~amp;  // Alternative syntax: \sound.set(\amp, 0.01)
// Fadeout with 
8000
custom duration
\sound.fadeOut(5);

Setting global fade time

The environment variable ~fadeTime stores the global default duration for fade-in and fade-out of synths. It is stored in the parent environment of the current environment. The =!> operator is used to set environment variables of the parent environment. Examples:

// Set global fade time to 3 seconds
3 =!> \fadeTime;
// Fade in a synth
{ WhiteNoise.ar } => \sound;
// Cross-fade another synth in its place
{ SinOsc.ar(LFNoise0.kr(5).range(400, 4000)) } => \sound;
// And a third synth
{ LPF.ar(GrayNoise.ar, LFNoise0.kr(5).range(400, 4000)) } => \sound;
// Set global fade time to 0.01 seconds
0.01 =!> \fadeTime;
// Notice difference in cross-fading duration
{ LFDNoise3.ar(LFNoise0.kr(15).range(400, 4000)) } => \sound;
// One more time
{ SinOsc.ar(LFNoise0.kr(15).range(400, 4000)) } => \sound;
// Fadeout also uses the global default
\sound.fadeOut;

Synth parameters are environment variables

When a synth template gets chucked to a synthtree with =>, the parameters of that synth get pushed to the current environment. They can then be accessed and set directly as environment variables.

{ LPF.ar(LFSaw.ar(\freq.kr(440)), \filterFreq.kr(1000)) } => \sound;
// Parameters of last chucked SynthTree are in the environment.
// Change the filter frequency:
400 => ~filterFreq;
// Change the generator frequency:
600 => ~freq;
// Play a routine into frequency, then fade out
{ 50 do: { 50.rrand(80).midicps => ~freq; 0.05.wait }; \sound.fadeOut(3); }.fork;

Play patterns in parameters

{ SinOsc.ar(\freq.kr(400)) } => \sound;
// Play a pattern into ~freq:
{ 50.rrand(80).midicps } -> 0.1 => ~freq;
// Alternative formulation:
{ 80.rrand(90).midicps } pp: 0.2 => ~freq;
//: Play another pattern into ~freq:
{ 250 rrand: 350 } -> 0.05 => ~freq;
//: And another:
{ [60, 62, 66, 67].choose.midicps } -> Prand([0.1, 0.2, 0.4], inf) => ~freq;
// Pattern keeps playing when new synth is chucked into tree:
{ LPF.ar(LFPulse.ar(\freq.kr(440)), 1000) } => \sound;
// Open knobs interface to watch how freq changes
~st.knobs;
// Use nil to play with global duration stored in ~dur:
{ [65, 69, 70, 73].choose.midicps } -> nil => ~freq;
// Change global duration:
0.1 =!> \dur;
// Use a pattern for global duration:
Pbrown(0.01, 0.26, 0.05, inf).asStream =!> \dur;

Restart synths after Command-.

Add some more synths to the tree:

{ SinOsc.ar(440) } => \la;
{ SinOsc.ar(550) } => \doDiese;
{ SinOsc.ar(660) } => \mi;

Stop all synths by typing Command-. (on SC IDE), or Control-c Control-s (on Emacs), or by evaluating this:

thisProcess.stop;

Then run this to restart the synths:

SynthTree.initTree;

Clearing SynthTree status

To stop all synths of the SynthTree from being restarted, evaluate this:

SynthTree.stopAll;

After this, no synths will be restarted with SynthTree.initTree.

Patching Audio Synth I/O

Example 1: Simple patching of one source to one effect:

// Start an effects synth with a low-pass filter
{ LPF.ar(Inp.ar, \freq.kr(2000)) } => \lpf;
// Start a WhiteNoise synth
{ WhiteNoise.ar } => \source;
// Send the noise synth to the filter
\lpf =< \source;
// Change the frequency of the low pass filter
\lpf.set(\freq, 5000);

Example 2: Several synths sending to one effect.

{ LPF.ar(Inp.ar, LFNoise0.kr(40 ! 2).range(500, 4000)) } => \lpf;
\lpf =< ({ PinkNoise.ar } ==> \source);
\lpf =< ({ LFPulse.ar(LFNoise0.kr(30).range(3000, 4000)) } ==> \source2);

Example 3: Changing the synths of the source and of the effect:

{ Inp.ar * Decay.kr({ Dust.kr(\trigRate.kr(1)) } ! 2) } =>.5 \lpf;
\lpf =< ({ LFTri.ar(LFNoise2.kr(12).range(400, 4000)) } ==> \source2);

Confirm that the tree can be restarted after Command-. also when it contains linked synths:

thisProcess.stop; // run this to stop all synths first
// Then run this to restart all stopped synths:
SynthTree.initTree;

GUI Views

Overview: 5 View Types

There are 5 main view types:

Fader View
Vertical strip on the left, showing the currently registered SynthTree instances and their run status, with a slider for controlling the level of each instance.
Knobs View
Horizontal strip at the bottom, one for each SynthTree instances, with knob controls for setting all registered parameters of the SynthTree. This is opened from the Fader view by typing “k” on a selected SynthTree strip’s label.
Synth Template View
A window with 2 list views: The left list shows the tags (categories) of SynthTree templates (SynthDefs or Functions) and the right list shows the templates belonging to the selected category. At the bottom is a drag view showing the name of the selected template. Drag the selected template onto any label on the Fader view to play that template on the SynthTree belonging to that fader strip.
Pattern Template View
(Tentative / Under development!) Holds templates of patterns to play in SynthTrees. May be integrated in the same list as the Synth Template View.
Process Registry View
Experimental / Proof of concept: Shows a list of currently running synth and routine processes, in a manner similar to the process view of Mini Audicle in ChucK. Works together with Emacs/Org-Mode (see keyboard shortcuts). Can also work with SuperCollider IDE, but requires using different methods for playing Functions, Synths or Routines. This feature is superseded by the Fader View, but kept here as proof-of-concept.

The Synth Template View

SynthTemplate.gui;

Keyboard commands on Synth Template view

KeyAction
returnsend template to currently selected SynthTree instance*
shift-returnsend template to a new SynthTree instance
control-returnadd template as input to currently selected SynthTree instance
control-.thisProcess.quit (like in SuperCollider IDE)
control-/SynthTree.initTree (restart all SynthTrees stopped by control-.

(*) Note : The currently SynthTree is selected in the Faders panel by clicking on the label displaying the SynthTree description (template name + synthtree name), or by chucking into a SynthTree in code (=>).

The SynhTree-Fader View

SynthTree.faders;

Keyboard commands on SynthTree.faders

KeyAction
On the whole window
bOpen Buffer List for creating buffer-playback synth
,Stop synths and routines (thisProcess.stop)
.Stop synths and remove from SynthTree.initTree
iSynthTree.initTree. Restart non-removed synths
/SynthTree.initTree. Restart non-removed synths
0-9Set global fade time to 0.02, 1, 2, 3 … 9 seconds
On slots that contain a SynthTree:
kOpen knobs window for controlling all parameters of synth
gstart synth
sstop synth
spaceToggle play status of selected SynthTree.
,Stop synths and routines (thisProcess.stop)
.Stop synths and remove from SynthTree.initTree

The Knobs view

Creating Views for any parameter

{ SinOsc.ar(\freq.kr(440)) } => \viewtest;
\viewtest.view(\freq).view(\amp);

Setting fadeTime in individual synths

// Start an "effect" synth with an input
{ LPF.ar(In.ar(\in.kr(0)), \freq.kr(4000)) } => \lpf;
// Set fadeTime of effect:
\lpf.fadeTime = 10;
// Send a synth to the input of the effect synth
\lpf =< ({ WhiteNoise.ar } ==> \source);
// Set fadeTime of source;
\source.fadeTime = 5;
// change effect, with fadeTime stored previously
{ Inp.ar * Decay2.kr(Dust.kr(3)) } => \lpf;
// change source, with fadeTime stored previously
{ SinOsc.ar(2000 rrand: 3000) } ==> \source;
// change source again, With fadeTime stored previously
{ LFTri.ar(400 rrand: 800) } ==> \source;

Buffers and samples

Play a sample loaded from disk with PlayBuf (If no name is specified, the name of the receiver of .buf is used to find a buffer of the same name. If no such buffer exists, then a Dialog window is opened for choosing a file to load into a buffer):

{ \buf.playBuf } => \chimes.buf.set(\amp, 1);

Play the same sample in a different synth, with different rate

{ \buf.playBuf(rate: 1.2) } => \different.buf(\chimes).set(\amp, 1);

BufferList autoload

Setting classvar autoload of BufferList to true will make SuperCollider load all .aiff and .wav files that are found under folder sounds in the SuperCollider user support directory (Platform.userAppSupportDir) whenever the default server boots.

Buffer list view

Following opens a Buffer List view with all buffers loaded through selecting from a SynthTree as shown above, or put in the default “sounds” folder in User App Support Dir/SuperCollider

BufferList.showList;

Keyboard commands on the Buffer List list view:

KeyAction
returnplay/stop selected buffer in a SynthTree named as the buffer
shift-returnlike return, but set loop to 1 (loop buffer)
space, shift-spacelike return, but always create new SynthTree to play in
lload a new buffer from file
ssave list of loaded buffers to file
oload list of buffers from file

Keyboard Bindings

Following keyboard bindings only apply to Emacs.

Global key bindings

C-c C-x C-/
sclang-init-synth-tree

Following keyboard shortcuts allow one to choose a synthtree from the list of synthtrees currently loaded in SuperCollider, or operate on the last chosen synthtree in emacs:

H-c c
org-sc-select-synthtree-then-chuck
H-c H-c
org-sc-chuck-into-last-synthtree
H-c k
org-sc-select-synthtree-then-knobs
H-c space
org-sc-toggle-synthtree
H-c H-space
org-sc-toggle-last-synthtree
H-c g
org-sc-start-synthtree
H-c s
org-sc-stop-synthtree
H-c H-s
org-sc-stop-last-synthtree

The chuck commands (H-c c, H-c H-c) enclose the snippet or section into a function before chucking. Try for example H-c c placing the cursor in the following line of code in sclang-mode:

//:
SinOsc.ar(\freq.kr(800) * LFNoise0.kr(12).range(0.8, 1.2));
//:

Stop the example above by typing H-c H-space.

Following keyboard shortcuts select a buffer from the list of buffers currently loaded in SuperCollider, or operate on the buffer list:

H-b g
org-sc-play-buffer
H-b l
org-sc-load-buffer
H-b f
org-sc-free-buffer
H-b L
org-sc-show-buffer-list
H-b o
org-sc-open-buffer-list
H-b s
org-sc-save-buffer-list

Org-mode bindings

General org-mode bindings for SuperCollider

C-c C-s
sclang-main-stop
H-C-o
org-sc-toggle-mode

Evaluating org-mode sections in sclang

Note: The process registry window and the org-sc-eval-in-routine technique is now superseded by SynthTree and its guis. SynthTree Fader gui is a more convenient way to control running synths. The process registry is nevertheless kept here as mere “proof of concept”, imitating the MiniAudicle process list window of ChucK.

H-C-r
sclang-process-registry-gui: Open registry gui.
C-M-x
org-sc-eval
H-C-x
org-sc-eval-in-routine. Wraps code in routine and registers it in ProcessRegistry.
C-M-z
org-sc-stop-section-processes. Stop all processes started from the current section. Uses automatically generated section ID to identify the current section.
H-C-z
org-sc-stop-section-processes
C-c C-M-.
org-sc-stop-section-processes
H-C-n
org-sc-next-section
C-M-n
org-sc-eval-next. Go to next section and evaluate as in org-sc-eval.
H-C-p
org-sc-previous-section
C-M-p
org-sc-eval-previous
C-c C-,
sclang-eval-line
C-c C-9
sclang-eval-dwim
C-c C-x l
org-sc-toggle-autoload
C-c C-x C-l
org-sc-load-marked

Examples for evaluating in orgmode

Before evaluating the following sections, type H-C-r to open the Process Registry window. This displays the currently running processes. Selecting a process and typing delete will stop or free that process.

A sine, 3 frequencies

// Type C-M-x with the cursor in the current section

a = { SinOsc.ar(\freq.kr(440), 0, 0.1) }.pla; 0.1.wait; a.set(\freq, 550); 0.1.wait; a.set(\freq, 660); a release: 3;

Sine, simple loop

// Type C-M-x with the cursor in the current section

a = { SinOsc.ar(\freq.kr(440), 0, 0.1) }.pla; 7 do: { 0.1.wait; a.set(\freq, 550); 0.1.wait; a.set(\freq, 660); }; a release: 3;

Sine, random melody loop

// Type C-M-x with the cursor in the current section

a = { SinOsc.ar(\freq.kr(440), 0, 0.1) }.pla; 50 do: { 0.1.wait; a.set(\freq, (440 * (4..12).choose / 4).postln); }; a release: 3; 3.wait; “DONE!”.postln;

Wandering dense sine cluster

// Watch the registry window tracking 1 to 30 rapidly changing synths // Kill the routine by selecting it in the registry window and // hitting the backspace key. // Then kill any remaining synths one by one with the backspace key

var synths, fwalk, swalk, synth; synths = List(); fwalk = (Pbrown(30, 90, 0.75, inf) + Pfunc({ 0.01.exprand(1.5)})).asStream; swalk = Pbrown(0, 30, 1, inf).asStream; loop { if (swalk.next > synths.size) { synths add: Syn(“adsrsine”, [\freq, fwalk.next.midicps]); }{ synth = synths.choose; synth.release(1.0.exprand(5.0)); synths remove: synth; }; 0.05.wait; };

Ghost voices

var synths, fwalk, swalk, synth; synths = List(); fwalk = (Pbrown(30, 90, 0.75, inf) + Pfunc({ 0.01.exprand(1.5)})).asStream; swalk = Pbrown(0, 30, 1, inf).asStream; loop { if (swalk.next > synths.size) { synths add: Syn(“adsrringz”, [\freq, fwalk.next.midicps, \decayTime, 3, &, 0.02]); }{ synth = synths.choose; synth.release(1.0.exprand(5.0)); synths remove: synth; }; 0.05.wait; };

Sclang-mode bindings

H-C-o
org-sc-toggle-mode
C-c .
sclang-execute-current-snippet
C-c C-,
sclang-eval-line
C-c C-.
sclang-select-snippet
C-M-x
sclang-execute-current-snippet
C-M-f
sclang-goto-next-snippet
C-M-b
sclang-goto-previous-snippet
C-M-n
sclang-execute-next-snippet
C-M-p
sclang-execute-previous-snippet
C-H-f
sclang-goto-next-snippet
C-H-b
sclang-goto-previous-snippet
C-H-n
sclang-execute-next-snippet
C-H-p
sclang-execute-previous-snippet
C-H-r
sclang-process-registry-gui
C-c l
sclang-recompile
M-C
sclang-clear-post-buffer

Triggering synths in routines

Use =|> to set the source of a SynthTree without starting it. This is necessary in cases like the following, where the starting of the synth is done explicitly by trig in a routine:

//:
{
	var synth;
	synth = { [SinOsc, LFPulse, LFTri, LFSaw].choose.ar(\freq.kr(400)) } =|> \test;
	50 do: {
		synth.trig(\freq, 400 rrand: 1200);
		0.1.wait;
	}
}.fork
//:

UGen shortcuts

Inp.ar

{ Inp.ar * Decay2.kr({ Dust.kr(1) } ! 2, 0.5, 2) } => \smooth;
\smooth =< ({ GrayNoise.ar(3) } ==> \gray);

List of running synths and patterns

Another way to play patterns

Broadcast data events to any listening object

About

Compact but powerful tools for SuperCollider, with Emacs Org-mode intergration

Resources

Stars

Watchers

Forks

Packages

No packages published
0