README.md : Updates
This commit is contained in:
parent
1b649124a6
commit
78ca1b3e35
381
README.md
381
README.md
@ -432,7 +432,7 @@ struct in_addr {
|
|||||||
|
|
||||||
export LD_LIBRARY_PATH=~/sdk/libwebsockets/build/out/lib
|
export LD_LIBRARY_PATH=~/sdk/libwebsockets/build/out/lib
|
||||||
|
|
||||||
*** Raspberry Pi Build Notes:
|
### Raspberry Pi Build Notes:
|
||||||
|
|
||||||
cd sdk
|
cd sdk
|
||||||
mkdir libwebsockets
|
mkdir libwebsockets
|
||||||
@ -444,10 +444,10 @@ struct in_addr {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
*** Flow Notes:
|
### Flow Notes:
|
||||||
|
|
||||||
|
|
||||||
- When a variable has a variant with a numberic channel should the 'all' channel variant be removed?
|
- When a variable has a variant with a numeric channel should the 'all' channel variant be removed?
|
||||||
|
|
||||||
- Check for duplicate 'vid'-'chIdx' pairs in var_regster().
|
- Check for duplicate 'vid'-'chIdx' pairs in var_regster().
|
||||||
(The concatenation of 'vid' and 'chIdx' should be unique
|
(The concatenation of 'vid' and 'chIdx' should be unique
|
||||||
@ -469,16 +469,21 @@ specific types, to pass through. For example a 'selector' (n inputs, 1 output) o
|
|||||||
|
|
||||||
DONE: Add a version of var_register() that both registers and returns the value of the variable.
|
DONE: Add a version of var_register() that both registers and returns the value of the variable.
|
||||||
|
|
||||||
*** Flow Instance Creation:
|
### Flow Instance Creation:
|
||||||
|
|
||||||
1. Create all vars from the class description and initially set their
|
0. Parse the 'in' list and create any 'mult' variables whose
|
||||||
value to the default value given in the class. chIdx=kAnyChIdx.
|
'in-var' contains an integer or underscore suffix. See
|
||||||
|
"'in' List Syntax and Semantics" below.
|
||||||
|
|
||||||
|
1. Create all vars from the class description, that were not
|
||||||
|
already instantiated during 'in' list processing, and set their
|
||||||
|
initial value to the default value given in the class. chIdx=kAnyChIdx.
|
||||||
|
|
||||||
Note that all vars must be included in the class description.
|
Note that all vars must be included in the class description.
|
||||||
|
|
||||||
|
|
||||||
2. Apply the preset record from the class description according to the
|
2. Apply the preset records from the class description according to the
|
||||||
label given in the instance definition.
|
'presets' list given in the instance definition.
|
||||||
|
|
||||||
If the variable values are given as a scalar then the existing
|
If the variable values are given as a scalar then the existing
|
||||||
variable is simply given a new value.
|
variable is simply given a new value.
|
||||||
@ -489,17 +494,23 @@ index of the value in the list. This is referred
|
|||||||
to as 'channelizing' the variable because the variable will then
|
to as 'channelizing' the variable because the variable will then
|
||||||
be represented by multiple physical variable records - one for each channel.
|
be represented by multiple physical variable records - one for each channel.
|
||||||
This means that all variables will have their initial record, with the chIdx set to 'any',
|
This means that all variables will have their initial record, with the chIdx set to 'any',
|
||||||
and then they may also have further variable records will for each explicit
|
and then they may also have further variable records for each explicit
|
||||||
channel number. The complete list of channelized variable record
|
channel number. The complete list of channelized variable record
|
||||||
is kept, in channel order, using the 'ch_link' links with the base of the list
|
is kept, in channel order, using the 'ch_link' links with the base of the list
|
||||||
on the 'any' record.
|
on the 'any' record.
|
||||||
|
|
||||||
3. Apply the variable values defined in the instance 'args' record.
|
3. Apply the variable values defined in a instance 'args' record.
|
||||||
This application is treated similarly to the 'class'
|
The 'args' record may have multiple sets of args.
|
||||||
preset. If the variable value is presented in a list then
|
If the preset instance includes an 'argsLabel' value then this record
|
||||||
the value is assigned to a specific channel if the channel
|
is selected to be applied. If No 'argsLabel' is given then
|
||||||
already exists then the value is simply replaced, if the
|
the record named 'default' is selected. If there is no record
|
||||||
channel does not exist then the variable is 'channelized'.
|
named 'default' then no record is applied.
|
||||||
|
|
||||||
|
The application of the args record proceeds exactly the same as
|
||||||
|
applying a 'class' preset. If the variable value is presented in a
|
||||||
|
list then the value is assigned to a specific channel. If the channel
|
||||||
|
already exists then the value is simply replaced. If the channel does
|
||||||
|
not exist then the variable is 'channelized'.
|
||||||
|
|
||||||
4. The varaibles listed in the 'in' list of the instance cfg.
|
4. The varaibles listed in the 'in' list of the instance cfg.
|
||||||
are connected to their source variables.
|
are connected to their source variables.
|
||||||
@ -520,5 +531,345 @@ access to registered variables.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Notes on 'poly' and 'mult':
|
||||||
|
|
||||||
|
The 'in' statement is formed by a list of _Connect Expressions_ :
|
||||||
|
|
||||||
|
`<input_var>:<source_inst.source_var>`
|
||||||
|
|
||||||
|
There are three forms of connect expressions:
|
||||||
|
|
||||||
|
1. Simple Connect Expression: Both the input and source labels
|
||||||
|
identify vars in the input and source instance.
|
||||||
|
|
||||||
|
2. Manual Mult Connect Expression: The input identifer ends with an
|
||||||
|
integer. This expression indicates that an input var will be
|
||||||
|
instantiated and connected to the source var. The integer indicates
|
||||||
|
the suffix (sfx) id of the input var. e.g. `in0:osc.out`,`in1:filt.out`.
|
||||||
|
|
||||||
|
3. PolyMult Connect Expression: The source identifier has an
|
||||||
|
underscore suffix. This form indicates that there will one instance of
|
||||||
|
this var for each poly instance that the source var instances is
|
||||||
|
contained by. e.g. `in:osc_.out` If `osc` is contained by an order 3
|
||||||
|
poly then statement will create and connect three instances of `in` -
|
||||||
|
`in0:osc0.out`,`in1:osc1.out` and `in2:osc2.out`.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- For an input variable to be used in either of the 'Manual' or 'PolyMult'
|
||||||
|
forms the var class desc must have the 'mult' attribute.
|
||||||
|
|
||||||
|
- If any var has an integer suffix then this is converted to it's sfx id.
|
||||||
|
|
||||||
|
- If the input var of a poly mult expression has an integer suffix then this is taken to be the
|
||||||
|
base sfx id for that poly connection. Other connections in the same statement will be
|
||||||
|
incremented from that base value. e.g `in3:osc_.out` becomes
|
||||||
|
`in3:osc0.out`,`in4:osc1.out` and `in5:osc2.out`.
|
||||||
|
|
||||||
|
- The first and last poly source instance can be indicated by specifying a
|
||||||
|
begin poly index and count before and after the source index underscore:
|
||||||
|
e.g. `in:osc3_3.out` becomes: `in0:osc3.out`,`in1:osc4.out` and `in2:osc5.out`.
|
||||||
|
|
||||||
|
- A similar scheme can be used to indicate particular source instance vars:
|
||||||
|
`in:osc.out1_2` becomes `in0:osc.out1`,`in1:osc.out2`
|
||||||
|
|
||||||
|
- It is a compile time error to have more than one input variable with the same sfx id.
|
||||||
|
|
||||||
|
'in' List Syntax and Semantics:
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Syntax:
|
||||||
|
-------
|
||||||
|
The 'in' list has the follow syntax:
|
||||||
|
`in: { in-stmt* }`
|
||||||
|
`in-stmt` -> `in-var-id`":" `src_expr`
|
||||||
|
`src-expr` -> `src-proc-id`"."`src-var-id`
|
||||||
|
`in-var-id` -> `var-id`
|
||||||
|
`src-proc-id` -> `var-id`
|
||||||
|
`src-var-id` -> `var-id`
|
||||||
|
`var-id` -> `label` { `label-sfx` }
|
||||||
|
`label-sfx` -> { `pri-int`} {{"_"} `sec-int` }
|
||||||
|
`pri-int` -> int
|
||||||
|
`sec-int` -> int
|
||||||
|
|
||||||
|
|
||||||
|
Semantics:
|
||||||
|
----------
|
||||||
|
|
||||||
|
### `in-var-id`
|
||||||
|
|
||||||
|
- The `label` part of the `in-var-id` must match to a
|
||||||
|
var description in the input proc class description.
|
||||||
|
|
||||||
|
- If no `label-sfx` is given then no special action
|
||||||
|
need by taken at var creation time. This var will be
|
||||||
|
created by default and later connected to the source inst/var.
|
||||||
|
|
||||||
|
|
||||||
|
- (0) If the "_" is given:
|
||||||
|
+ This is an "iterating" in-stmt where multiple
|
||||||
|
input vars will be created and connected.
|
||||||
|
|
||||||
|
+ If no `pri-int` is given then the `pri-int` defaults to 0.
|
||||||
|
|
||||||
|
+ If the `pri-int` is given then it indicates that
|
||||||
|
an instance of this var should be created where
|
||||||
|
the `pri-int` becomes the sfx-id of the var instance.
|
||||||
|
|
||||||
|
+ If `sec-int` is given then it gives the
|
||||||
|
count of input vars which will be created. The
|
||||||
|
sfx-id of each new input var begins with `pri-int`
|
||||||
|
and increments for each new var.
|
||||||
|
|
||||||
|
+ (1) If no `sec-int` is given then the `sec-int` is implied by the count
|
||||||
|
of source variables indicated in the `src-expr`.
|
||||||
|
|
||||||
|
|
||||||
|
- If no "_" is given:
|
||||||
|
+ No `sec-int` can exist without a "_".
|
||||||
|
|
||||||
|
+ If a `pri-int` is given then a single
|
||||||
|
input var is created and the `pri-int`
|
||||||
|
gives the sfx-id. This single input
|
||||||
|
var is then connected to a single src var.
|
||||||
|
|
||||||
|
+ If no `pri-int` is given
|
||||||
|
then the default var is created
|
||||||
|
with kBaseSfxId and is connected
|
||||||
|
to a single source var.
|
||||||
|
|
||||||
|
|
||||||
|
### `src-proc-id`
|
||||||
|
|
||||||
|
- The `label` part of the `src-proc-id` must match to a
|
||||||
|
previously created proc instance in the current network.
|
||||||
|
|
||||||
|
- If a `label-sfx` is given then the `pri-int` gives
|
||||||
|
the sfx-id of the first proc inst to connect to.
|
||||||
|
If no `pri-int` is given then the first sfx-id
|
||||||
|
defaults to 0.
|
||||||
|
|
||||||
|
|
||||||
|
- If "_" is given:
|
||||||
|
+ This is an "iterating" src-proc and therefore
|
||||||
|
the in-var must also be iterating. See (0)
|
||||||
|
|
||||||
|
+ If a `sec-int` is given then this gives the count of
|
||||||
|
connections across multiple proc instances with
|
||||||
|
sfx-id's beginnign with `pri-int`. Note that if
|
||||||
|
`sec-int` is given then the `in-var-id` must be
|
||||||
|
iterating and NOT specify an iteration count,
|
||||||
|
as in (1) above.
|
||||||
|
|
||||||
|
+ If no `sec-int` is given then the
|
||||||
|
`sec-int` defaults to the count of
|
||||||
|
available proc instances with the given `label`
|
||||||
|
following the source proc inst `pri-int`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- If "_" is not given then this is not an
|
||||||
|
iterating proc inst.
|
||||||
|
|
||||||
|
+ If the input var is iterating
|
||||||
|
then it must specify the iteration count or
|
||||||
|
the `src-var-id` must be iterating.
|
||||||
|
|
||||||
|
+ If the `pri-int` is given then it specifies
|
||||||
|
the sfx-id of the src-proc
|
||||||
|
|
||||||
|
+ If the `pri-int` is not given
|
||||||
|
|
||||||
|
- If the src-net is the same as the in-var net then
|
||||||
|
the sfx-id of the in-var proc is used as the src-proc sfx-id
|
||||||
|
|
||||||
|
|
||||||
|
### `src-var-id`
|
||||||
|
|
||||||
|
- The `label` part of the `in-var-id` must match to a
|
||||||
|
var description in the source proc class descriptions.
|
||||||
|
|
||||||
|
- If a `label-sfx` is given then the `pri-int` gives
|
||||||
|
the sfx-id of the first source var to connect to
|
||||||
|
on the source proc instance. If no `pri-int` is
|
||||||
|
given then the first sfx-id defaults to 0.
|
||||||
|
|
||||||
|
- If a "_" is given:
|
||||||
|
+ This is an "iterating"
|
||||||
|
source var and therefore the input var
|
||||||
|
must specifiy an iterating connection and
|
||||||
|
the source proc inst must not specify an iterating
|
||||||
|
connection. See (0) above.
|
||||||
|
|
||||||
|
+ If a `sec-int` is given then this gives the count of
|
||||||
|
connections across multiple source vars with
|
||||||
|
sfx-id's beginnign with `pri-int`. Note that if
|
||||||
|
`sec-int` is given then the `in-var-id` must be
|
||||||
|
iterating and NOT specify an iteration count,
|
||||||
|
as in (1) above.
|
||||||
|
|
||||||
|
|
||||||
|
+ If `sec-int` is given
|
||||||
|
then the `sec-int` defaults to the count of
|
||||||
|
available source vars with the given `label`
|
||||||
|
following the source var `pri-int`.
|
||||||
|
|
||||||
|
- If "_" is not given then this is not an
|
||||||
|
iterating source var. If the input var is iterating
|
||||||
|
then it must specify the iteration count or
|
||||||
|
the `src-proc-id` must be iterating.
|
||||||
|
|
||||||
|
|
||||||
|
### Notes:
|
||||||
|
|
||||||
|
- If the `in-var-id` is iterating but neither `src-proc-id`
|
||||||
|
or `src-var-id` are iterating then the `in-var-id` must
|
||||||
|
specify the iteration count and the connection will be
|
||||||
|
made to exactly one source var on the source proc inst.
|
||||||
|
|
||||||
|
- If `in-var-id` is iterating then the iterations count
|
||||||
|
must come from exactly one place:
|
||||||
|
+ the input var `sec-int`
|
||||||
|
+ the source proc `sec-int`
|
||||||
|
+ the source var `sec-int`
|
||||||
|
|
||||||
|
This means that only one literal iter count can be
|
||||||
|
given per `in-stmt`. It is a syntax error if
|
||||||
|
more than one literal iter counts are given.
|
||||||
|
|
||||||
|
- Use cases
|
||||||
|
+ connect one input to one source
|
||||||
|
+ connect multiple inputs to the same var on multiple procs
|
||||||
|
+ connect multiple inputs to multiple vars on one proc
|
||||||
|
+ connect multiple inputs to one var on one proc
|
||||||
|
|
||||||
|
Var Updates and Preset Application
|
||||||
|
==================================
|
||||||
|
|
||||||
|
Variable addresses are formed from the following parameters:
|
||||||
|
`(<proc_label><proc_label_sfx_id>)*,var_label,var_label_sfx_id, ch_idx`
|
||||||
|
|
||||||
|
In the cases of poly procs (procs with public internal networks) it
|
||||||
|
may not always be possible to know the `<proc_label_sfx_id>` without
|
||||||
|
asking for it at runtime. For example for the cross-fader control the
|
||||||
|
application must ask for the `<proc_label_sfx_id>` current or next
|
||||||
|
poly channel depending on which one it is targetting.
|
||||||
|
|
||||||
|
It is notable that any proc with an internal network has
|
||||||
|
to solve this problem. The problem is especially acute
|
||||||
|
for proc's which change the 'current' poly channel at runtime.
|
||||||
|
|
||||||
|
The alternative is to include the concept of special values
|
||||||
|
in the address (e.g. kInvalidIdx means the application isn't
|
||||||
|
sure and the network should decide how to resolve the address)
|
||||||
|
The problem with this is that the information
|
||||||
|
to make that decision may require more information than
|
||||||
|
just a simple 'special value' can encode. It also means
|
||||||
|
complicating the var set/get pipeline with 'escape' routines.
|
||||||
|
|
||||||
|
There are at least two known use cases which need to address
|
||||||
|
this issue:
|
||||||
|
1. The cross-fader: The application may wish to address
|
||||||
|
updates to the current or next poly channel but this
|
||||||
|
channel can't be determined until runtime.
|
||||||
|
|
||||||
|
- The application asks for the current or next `proc_label_sfx_id`
|
||||||
|
at runtime depending on what its interested in doing,
|
||||||
|
and sets the update address accordingly.
|
||||||
|
|
||||||
|
|
||||||
|
- Two interface objects are setup as sources for the `xfade_ctl`
|
||||||
|
object. The address of each of these objects can be
|
||||||
|
determined prior to runtime. The application then simply addresses
|
||||||
|
the object corresponding to method (direct vs deferred) it requires.
|
||||||
|
This solution is particularly appealing because it means that
|
||||||
|
presets may be completely resolved to their potential
|
||||||
|
target procs (there would be up to 'poly-count' potential targets)
|
||||||
|
prior to runtime.
|
||||||
|
|
||||||
|
As it stands now the problem with this approach is that it
|
||||||
|
does not allow for the message to be resolved to its final
|
||||||
|
destination. If the message is addressed to a proxy proc
|
||||||
|
then that proxy must mimic all the vars on the object which
|
||||||
|
it is providing an interface for. (This is actually possible
|
||||||
|
and may be a viable solution???)
|
||||||
|
|
||||||
|
One solution to this is to create a data type which is an
|
||||||
|
address/value packet. The packet would then be directed
|
||||||
|
to a router which would in turn use the value to forward
|
||||||
|
the packet to the next destination. Each router that the
|
||||||
|
packet passed through would strip off a value and
|
||||||
|
pass along the message. This is sensible since the 'value'
|
||||||
|
associated with a router is in fact another address.
|
||||||
|
|
||||||
|
2. The polyphonic sampler:
|
||||||
|
|
||||||
|
- How can voices be addressed once they are started?
|
||||||
|
+ A given note is started - how do we later address that note to turn it off?
|
||||||
|
Answer: MIDI pitch and channel - only one note may be sounding on a given MIDI pitch and channel at any one time.
|
||||||
|
|
||||||
|
- Extending ths idea to the xfader: There are two channels: current and deferred,
|
||||||
|
but which are redirected to point to 2 of the 3 physical channels .... this would
|
||||||
|
require the idea of 'redirected' networks, i.e. networks whose proc lists were
|
||||||
|
really pointers to the physical procs.
|
||||||
|
- sd_poly maintains the physical networks as it is currently implemnted.
|
||||||
|
- xfade_ctl maintains the redirected networks - requests for proc/var addresses
|
||||||
|
on the redirected networks will naturally resolve to physical networks.
|
||||||
|
|
||||||
|
- Required modifications:
|
||||||
|
+ variable getters and setters must use a variable args scheme specify the var address:
|
||||||
|
`(proc-name,proc-sfx-id)*, var-name,var-sfx-id`
|
||||||
|
Example: `xfad_ctl,0,pva,1,wnd_len,0,0`
|
||||||
|
- The first 0 is known because there is only one `xfad_ctl`.
|
||||||
|
- The 1 indicates the 'deferred' channel.
|
||||||
|
- The second 0 is known because there is only one `wnd_len` per `pva`.
|
||||||
|
- The third 0 indicates the channel index of the var.
|
||||||
|
|
||||||
|
+ the address resolver must then recognize how to follow internal networks
|
||||||
|
|
||||||
|
+ Networks must be maintained as lists of pointers to procs
|
||||||
|
rather than a linked list of physical pointers.
|
||||||
|
|
||||||
|
+ `xfade_ctl` must be instantiated after `sd_poly` and be able
|
||||||
|
to access the internal network built by `sd_poly`.
|
||||||
|
|
||||||
|
|
||||||
|
Generalizing the Addressing
|
||||||
|
---------------------------
|
||||||
|
Change the set/get interface to include a list of (proc-label,proc-sfx-id)
|
||||||
|
to determine the address of the var.
|
||||||
|
|
||||||
|
Note that this still requires knowing the final address in advance.
|
||||||
|
In general a router will not know how to resolve a msg to the
|
||||||
|
next destination without having a final address.
|
||||||
|
In otherwords setting 'proc-sfx-id' to kInvalidId is not
|
||||||
|
resolvable without more information.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### TODO:
|
||||||
|
|
||||||
|
- Documentation w/ examples.
|
||||||
|
|
||||||
|
- Compile presets: at load time the presets should be resolved
|
||||||
|
to the proc and vars to which they will be assigned.
|
||||||
|
|
||||||
|
- flow classes and variable should have a consistent naming style: camelCase or snake_case.
|
||||||
|
|
||||||
|
- Variable attributes should be meaningful. e.g. src,src_opt,mult,init, ....
|
||||||
|
Should we check for 'src' or 'mult' attribute on var's?
|
||||||
|
|
||||||
|
- DONE: 'poly' should be implemented as a proc-inst with an internal network - but the
|
||||||
|
elements of the network should be visible outside of it.
|
||||||
|
|
||||||
|
- 'sub' should be implemented as proc-inst with an internal network, but the
|
||||||
|
elements of the network should not be visible outside of it. Instead it should
|
||||||
|
include the idea of input and output ports which act as proxies to the physical
|
||||||
|
ports of the internal elements.
|
||||||
|
|
||||||
|
- 'poly' and 'sub' should be arbitrarily nestable.
|
||||||
|
|
||||||
|
|
||||||
|
- Reduce runtime over head for var get/set operations.
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user