Skip to content

iani/tiny-inc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Incremental redo of tiny-sc.

Started on [2016-01-28 Thu 00:09]

Player classes

SynthPlayer PatternPlayer

Operators

Operators / revision from 0 version 31 May 2017 22:37 ff

Step 1: +>

// play function as Synth in SynthPlayer
Function +> Symbol; 

// play any pattern-capable object as stream in key in EventStreamPlayer
Pattern +> Symbol;

Starting implementation for EventStreamPlayer 1 Jun 2017 20:00.

STARTED operator syntax - version 201603

  • State “STARTED” from “TODO” [2016-03-17 Thu 12:33]
    started

Operator overview

  1. Playing
    +>
    Start playing something in a SynthLink. Note: If the first (left) operand is an event, it adds or sets the EventPattern of an EventPlayer that is attached to the TaskPlayer as player. The default name of the player is player. Another name is used if it is provided as adverb to the +> operator.
    +>>
    Set the pattern of the TaskPlayer in the SynthLink, and start. Do not add any EventPlayer to the TaskPlayer.
  2. Modifying args For TaskPlayer, these modify the EventStream of the default EventPlayer or the player specified in the adverb to the operator.
    %>
    Add args to event or arg-array
    !%>
    Replace event or arg-array
  3. Modifying pattern of the TaskPlayer These modify the pattern and stream of the TaskPlayer, not of any EventPlayer.
    >>
    !>>
  4. Linking SynthLinks
    @>
    …b・・・
    <@
    @
    @+
    +@

Details

+> : Set source of SynthLink and play.

Play function into SynthPlayer - in SynthLink:

{ } +> \symbol 

Play named and loaded SynthDef into SynthPlayer - in SynthLink:

\default +> \symbol

Play Event into TaskPlayer - in SynthLink:

( ) +> \symbol // Plays through default EventPlayer as TaskPlayer-player
( ) +> \symbol // Plays through default EventPlayer as TaskPlayer-player

Possibly:

number +> \symbol
use number as duration to start TaskPlayer in SynthLink
pattern +> \symbol
use pattern as duration to start TaskPlayer in SynthLink

%> : change args in SynthLink, and send them to player - without restarting

() %> \symbol

for simplicity, these will not be attempted now:

++>
Set source of SynthLink but do not play now
%%>
change args in SynthLink, but do not send them to player now.

Roadmap

Make an object listen to notifications from another object

Notification class.

Real Server Watcher, that tells when system resumes from sleep

Notify an object when a synth starts / ends

  • State “DONE” from “” [2016-03-20 Sun 18:58]

Methods Node:onStart, Node:onEnd.

Hold a node, monitor if it runs, replace with other node on request, notify when it starts and stops running

  • State “DONE” from “” [2016-03-20 Sun 18:58]

Class SimpleSynthPlayer

Do not notify end when a new synth is started to replace a previous one

Done in class SimpleSynthPlayer.

	addNode { | argNode |
		NodeWatcher.register(argNode);
		//  Release previous node if playing,
		//	but prevent that node from triggering a stopped notification when it ends.
		if (this.isPlaying) {
			node.releaseDependants; // do not notify when you end: next node is on the way
			this.prStop;
			argNode addDependant: { | changer, message |
				switch (message,
					// do not notify when started
					// \n_go, { this.changed(\started) },
					\n_end, {
						node = nil;
						this.changed(\stopped);					
					}
				);
			}
		}{
			argNode addDependant: { | changer, message |
				switch (message,
					\n_go, { this.changed(\started) },
					\n_end, {
						node = nil;
						this.changed(\stopped);					
					}
				);
			}
		};
		node = argNode;
	}

Examples with GUI buttons to start/stop a synth

See file

Store the source for starting a node

  • State “DONE” from “STARTED” [2016-03-20 Sun 18:57]
  • State “STARTED” from “” [2016-01-28 Thu 12:37]
    includes inputs and outputs

SynthPlayer

FunctionSynthSource

Stores a Function that is the source for creating Synths. It substitutes { }.play by a mechanism that caches the SynthDef created from the function, so that any new Synths from the same Function can be created by Synth("defName"). This is much more efficient than compiling the SynthDef from the Function and sending it to the Server each time that a new Synth is created.

Behavior:

message play

When receiving the message play, the FunctionSynthSource creates a Synth and returns it immediately. If the SynthDef from the Function stored in the FunctionSynthSource is already loaded in the server, then the Synth is created in the usual manner, with the Synth("defName"). If however the Function is not yet loaded, the Synth is created with Synth.basicNew and the actual Synth instance on the scserver is created as soon as the SynthDef is loaded.

When a FunctionSynthSource is created, it adds the given Function - or a default - as SynthDef, and sends it to the Server.

Upon sending a SynthDef to the server, the FunctionSynthSource sets its waiting_for_def flag to true.

The algorithm for the method play is as follows:

if (waiting_for_def) {
    ^node ?? {
        node = Synth.basicNew(defName, server);
    }
}{
    ^Synth(defName, *args);
}

loadAndPlayMethod is one of the following:

sendDef2Server
waitForServer2Load

message source_

  1. Set the

tests

f = FuncNodeSource.new;
f.play;

Unique objects - created only if not found under a key

  • State “DONE” from “STARTED” [2016-03-23 Wed 13:19]
  • State “STARTED” from “TODO” [2016-03-23 Wed 13:18]
    Imported Registry class from tiny-sc.

See Registry class.

STARTED Designing TaskPlayer

  • State “STARTED” from “TODO” [2016-03-21 Mon 17:20]
    started …

Approach 1: Use the same archtecture and approach as for SynthPlayer, involving a TaskSource.

STARTED Synth and Task Bus I/O linking mechanism

  • State “STARTED” from “TODO” [2016-03-22 Tue 23:08]
    basic concept and syntax
\writer @> \reader; // move output of writer to input of reader
\writer <@ \reader; // move input of reader to output of writer
// operator specifies output, adverb specifies input:
\writer@\out1 @>.in2 \reader; // specify output/input params out1 and in2

Possible extra operators:

\writer @+ \reader; // branch output of writer to reader with i/o copy synth
\writer +@ \reader; // branch to input of reader with i/o copy synth

\writer and \reader are unique group/rank and input/output bus holders accessible through their symbols. They can store a SynthPlayer or a TaskPlayer - interchangeably. Class: SynthLink

Structure of SynthLink:

SynthLink {
    var <server;
    var <rank = 0; // smaller numbers mean earlier synth order
    var <group;  // the actual group. Used as target for player.
    var <inputs; // Dictionary of Inputs (param: input, param2: input)
    var <outputs; // Dictionary of Outputs
    var <player; // SynthPlayer, TaskPlayer, or similar/compatible object

    getGroup {
        if (inputs.isNil and: { outputs.isNil }) {
            rank = 0
        }{
            rank = this.allWriters.collect(_.rank).maxItem + 1;
            this.moveToGroup;
        };
        
    }

    moveToGroup {
        this.readers do: _.moveAfter(rank);
        this.setGroup;
    }

    moveAfter { | argRank |
        if (rank <= argRank) {
            rank = argRank + 1;
            this.moveToGroup;
        }
    }
    
    setGroup {
        group = PlayerGroup(server, rank);
        player !? { player.target = group };
    }

    getArgs {
        
    }
}

Input {
    var <parameter; // name of input parameter
    var <bus;
    var <readerNode; // the SynthLink that has this input
    var <writers;   // set of Outputs that write to this input
}

Output {
    var <parameter; // name of input parameter
    var <bus;
    var <writerNode; // the SynthLink that has this output
    var <readers;   // set of Inputs that read from this output
}

PlayerGroup {
    var <server, <groups;
    *new { | server, rank = 0 |
        ^Registry(this, server, { this.newCopyArgs(server, []) })
        .getGroup(rank);
    };

    getGroup { | rank |
        var root;
        root = server.rootNode;
        rank - groups.size + 1 max: 0 do: {
            groups = groups add: Group.tail(root);
        };
        ^groups[rank];
    }
}

STARTED start and restart methods

  • State “STARTED” from “TODO” [2016-04-23 Sat 11:56]
  • Only in SynthLink, not in SynthPlayer or TaskPlayer
start
start if not playing
restart
stop previous process and start again

Overview of Classes

Synth and Task playing

Source containers for players

FunctionSynthSource
SynthDefSource

Players

SynthPlayer
TaskPlayer

Linking Synth I/O

Utilities

Notification

ServerBootCheck

onEnd, onStart

Registry

STARTED SynthLink addEventAsTaskPlayerSource notes

To watch:

player pattern should copy

STARTED SynthLink +>> notes

To watch:

How exactly is the EventPlayer produced, and where, in the chain of method calls, when the TaskPatternPlayer is produced.

UGen + SynthDef Shortcuts

About

Incremental redo of tiny-sc

Resources

Stars

Watchers

Forks

Packages

No packages published