|
|
Mozy Online Backup: 2GB Free. Automatic. Secure.
Subject: Re: rfc: ControlValue - msg#00078
List: audio.supercollider.devel
Hi Julian,
Thanks for the comments, here are some responses:
> Here is some comments on what I saw in it. I think all in all it is a
> good thing to have something like this on the 'system level' of sc.
>
> a)
> ControlValue seems not to be a Pattern (e.g. no asStream
> parallelisation), although it subclasses Pattern.
> I believe it should simply be a subclass of AbstractFunction or
> of Stream
I don't understand what you mean here.
The goal of subclassing Pattern is to be able to write
Pbind(\field, aControlValue)
and have the ControlValue control the value of the field.
If I use the same ControlValue in several places, I want it to be the
same ControlValue not a different one. I could write:
Pfunc({aControlValue.value})
instead, but that is slower and harder to read.
> input_(input) why not call it set(input), same like synth.set,
> bus.set, point.set, ref.set, ... server.set (just kidding).
> the difference between input_ and value_ is not easy to understand if
> you don't remember it from Preset/Items
The input_ method is intended as a generic interface for external control
sources (like MIDI or game controllers). So the idea is that the
all input_ methods expect a [0,1] range of values.
One could write
controlvalue.value(controlvalue.map(input))
but I want to have objects that start/stop or pause/resume be able to
tie in, so a method seems in order.
I am wary of calling it 'set' precisely because that method name is
heavily used with connotation of direct determination of internal state
rather than a scaled or transformed determination. There are classes that
have set defined that might use input_ as well, for example, EZ-slider.
>
> this means that every node that is sent to the server, say in Synth.new,
> will have to perform an iteration on each argument, checking for it to be
> of controlValue class.
> Also it is inconsistent to have a special method for set (setControls),
> but an internal translation in node.new.
Yeah, I didn't expect this to pass muster. The basic problem is that
there is no easy way to get at the nodeID, setControls has a delay
between the creation of the Synth and the effect of the controls.
I think I'll write a 'newWithControls' method. Actually, this is
better as then Group can support the same method.
> OSCpathResponder(np.group.server.addr, ["/n_end", np.group.nodeID],...
>
> you shouldn't rely on the group of the nodeProxy,
> as on cmd-. the structure is lost.
> the link should be removed only when the proxy calls .clear
> I don't know how this dependancy should be resolved though.
What if there were a controlValues instance variable in NodeProxy and
and NodeProxy-group_ did the linking? The only expense would be
an if(controlValues.notNil, { });
>
> e)
> to have an "untyped" interface I would try to use multiple dispatch
> to have one method for all connects:
>
> a.connectToNodeProxy(np, key) could then be a.connectTo(np,key)
> this method would call NodeProxy-connectControlValue(\key, val) or
> Bus-connectControlValue(val).
Hmm, with an untyped interface its hard to know what classes are
being supported. So, I thought it was a better idea to keep it very
explicit for the time being.
> also then the method wouldn't have to be implemented in Array, but
> connectControlValue could return an array of busLinks you could then register
> whith the OSCresponder.
The Array methods are needed to support raw OSC.
> why do you replace the controlValues in the array when you connect?
> This could be very confusing if you want to reuse the same array.
It was just to try to speed things up, It really came from starting with
the raw OSC messages and working my way up the different abstractions.
You're right, it should go away.
Thanks,
RJK
Was this page helpful?
Thread at a glance:
Previous Message by Date:
click to view message preview
Re: rfc: ControlValue
Hi all,
ControlValue is an approach to making control guis for NodeProxy, server nodes
(generated with raw OSC or the various classes), patterns, etc.
There are plenty of libraries that do similar things, but this
approach works with the basic
constructs of SC3. The only special class needed is a version of
SCWindow that removes
controllers (that link views to ControlValues) when closed.
A help file with examples is included.
Please take a look and send comments. If no one objects, I'll
commit it to the
class library next week.
Here is some comments on what I saw in it. I think all in all it is a
good thing to have something like this on the 'system level' of sc.
a)
ControlValue seems not to be a Pattern (e.g. no asStream
parallelisation), although it subclasses Pattern.
I believe it should simply be a subclass of AbstractFunction or
of Stream.
then these methods could simply be dropped:
// Stream and Pattern support
next { ^value }
reset {}
asStream { ^this }
embedInStream { value.yield }
b)
input_(input) why not call it set(input), same like synth.set,
bus.set, point.set, ref.set, ... server.set (just kidding).
the difference between input_ and value_ is not easy to understand if
you don't remember it from Preset/Items
c)
against this I'd have objections:
+Node {
setControls { arg arrayOfNamesAndControlValues;
server.sendBundle(server.latency,
["/n_set", nodeID] ++
arrayOfNamesAndControlValues.connectToNode(server,nodeID));
}
nodeToServer { arg addAction=\addToTail, target, args;
var msg;
msg = this.perform(addAction, target);
if (args.notNil, { msg = msg ++
args.connectToNode(server,nodeID) });
msg = [msg];
target.asGroup.finishBundle(msg, this);
server.listSendBundle(nil, msg);
}
}
this means that every node that is sent to the server, say in Synth.new,
will have to perform an iteration on each argument, checking for it to be
of controlValue class.
Also it is inconsistent to have a special method for set (setControls),
but an internal translation in node.new.
maybe it would be better to have a message array.asSynthArgs or similar
that you send to the input args.
(btw. I think I'll remove target.asGroup.finishBundle(msg, this) too
as Ensemble class is apparently not used)
btw.
there is a typo in the helpfile:
( // Bus
b = Bus.control;
b.setControls([a]);
Synth("tri").map([\f,b.index]);
a.value_(400);
)
Synth("tri").map([\f,b.index]);
should be
Synth("tri").map(\f,b.index);
d)
OSCpathResponder(np.group.server.addr, ["/n_end", np.group.nodeID],...
you shouldn't rely on the group of the nodeProxy,
as on cmd-. the structure is lost.
the link should be removed only when the proxy calls .clear
I don't know how this dependancy should be resolved though.
e)
to have an "untyped" interface I would try to use multiple dispatch
to have one method for all connects:
a.connectToNodeProxy(np, key) could then be a.connectTo(np,key)
this method would call NodeProxy-connectControlValue(\key, val) or
Bus-connectControlValue(val).
also then the method wouldn't have to be implemented in Array, but
connectControlValue could return an array of busLinks you could then register
whith the OSCresponder.
why do you replace the controlValues in the array when you connect?
This could be very confusing if you want to reuse the same array.
connectToNodeProxy { arg np;
var nodeLinks, controlValue, name;
nodeLinks = [];
forBy (1, this.size - 1, 2, { arg i;
controlValue = this.at(i);
if( controlValue.isKindOf(ControlValue), {
nodeLinks = nodeLinks ++
controlValue.connectToNodeProxy(np, this.at(i-1));
this.put(i, controlValue.value);
});
});
if (nodeLinks.size > 0, {
OSCpathResponder(np.group.server.addr,
["/n_end", np.group.nodeID],
{ arg time, resp, msg; nodeLinks.do({
arg n; n.remove}); resp.remove;}
).add;
})
}
hope this is useful..
--
.
Next Message by Date:
click to view message preview
Re: rfc: ControlValue
Hi Julian,
Thanks for the comments, here are some responses:
Here is some comments on what I saw in it. I think all in all it is a
good thing to have something like this on the 'system level' of sc.
a)
ControlValue seems not to be a Pattern (e.g. no asStream
parallelisation), although it subclasses Pattern.
I believe it should simply be a subclass of AbstractFunction or
of Stream
I don't understand what you mean here.
The goal of subclassing Pattern is to be able to write
Pbind(\field, aControlValue)
and have the ControlValue control the value of the field.
this you can do with by subclassing Stream, too.
or if you subclass AbstractFunction, you'd have to implement
embedInStream / asStream, like in Ref.sc
ControlValue should be no Pattern, because it doesn't create multiple streams.
If I use the same ControlValue in several places, I want it to be the
same ControlValue not a different one. I could write:
Pfunc({aControlValue.value})
instead, but that is slower and harder to read.
input_(input) why not call it set(input), same like synth.set,
bus.set, point.set, ref.set, ... server.set (just kidding).
the difference between input_ and value_ is not easy to understand if
you don't remember it from Preset/Items
The input_ method is intended as a generic interface for external control
sources (like MIDI or game controllers). So the idea is that the
all input_ methods expect a [0,1] range of values.
One could write
controlvalue.value(controlvalue.map(input))
but I want to have objects that start/stop or pause/resume be able to
tie in, so a method seems in order.
I am wary of calling it 'set' precisely because that method name is
heavily used with connotation of direct determination of internal state
rather than a scaled or transformed determination. There are classes that
have set defined that might use input_ as well, for example, EZ-slider.
ok, then I understand.
this means that every node that is sent to the server, say in Synth.new,
will have to perform an iteration on each argument, checking for it to be
of controlValue class.
Also it is inconsistent to have a special method for set (setControls),
but an internal translation in node.new.
Yeah, I didn't expect this to pass muster. The basic problem is that
there is no easy way to get at the nodeID, setControls has a delay
between the creation of the Synth and the effect of the controls.
I think I'll write a 'newWithControls' method. Actually, this is
better as then Group can support the same method.
new with controls might be cause of misunderstanding, as Control
is that thing in the UGen graph. But apart from that this is good,
I think.
OSCpathResponder(np.group.server.addr, ["/n_end", np.group.nodeID],...
you shouldn't rely on the group of the nodeProxy,
as on cmd-. the structure is lost.
the link should be removed only when the proxy calls .clear
I don't know how this dependancy should be resolved though.
What if there were a controlValues instance variable in NodeProxy and
and NodeProxy-group_ did the linking? The only expense would be
an if(controlValues.notNil, { });
hm, there is already a nodeMap that is supposed to care for the linkings.
I don't know it this is the best solution. Anyway usually np.clear is
called very conciously. so one might as well unlink the controls by
hand for now.
I'll think about it.
e)
to have an "untyped" interface I would try to use multiple dispatch
to have one method for all connects:
a.connectToNodeProxy(np, key) could then be a.connectTo(np,key)
this method would call NodeProxy-connectControlValue(\key, val) or
Bus-connectControlValue(val).
Hmm, with an untyped interface its hard to know what classes are
being supported. So, I thought it was a better idea to keep it very
explicit for the time being.
well, maybe I'm too much caring for condensed expressions. I can see
what you mean.
also then the method wouldn't have to be implemented in Array, but
connectControlValue could return an array of busLinks you could
then register
whith the OSCresponder.
The Array methods are needed to support raw OSC.
this I don't understand. They are not sent an osc message?
--
.
Previous Message by Thread:
click to view message preview
Re: rfc: ControlValue
Hi all,
ControlValue is an approach to making control guis for NodeProxy, server nodes
(generated with raw OSC or the various classes), patterns, etc.
There are plenty of libraries that do similar things, but this
approach works with the basic
constructs of SC3. The only special class needed is a version of
SCWindow that removes
controllers (that link views to ControlValues) when closed.
A help file with examples is included.
Please take a look and send comments. If no one objects, I'll
commit it to the
class library next week.
Here is some comments on what I saw in it. I think all in all it is a
good thing to have something like this on the 'system level' of sc.
a)
ControlValue seems not to be a Pattern (e.g. no asStream
parallelisation), although it subclasses Pattern.
I believe it should simply be a subclass of AbstractFunction or
of Stream.
then these methods could simply be dropped:
// Stream and Pattern support
next { ^value }
reset {}
asStream { ^this }
embedInStream { value.yield }
b)
input_(input) why not call it set(input), same like synth.set,
bus.set, point.set, ref.set, ... server.set (just kidding).
the difference between input_ and value_ is not easy to understand if
you don't remember it from Preset/Items
c)
against this I'd have objections:
+Node {
setControls { arg arrayOfNamesAndControlValues;
server.sendBundle(server.latency,
["/n_set", nodeID] ++
arrayOfNamesAndControlValues.connectToNode(server,nodeID));
}
nodeToServer { arg addAction=\addToTail, target, args;
var msg;
msg = this.perform(addAction, target);
if (args.notNil, { msg = msg ++
args.connectToNode(server,nodeID) });
msg = [msg];
target.asGroup.finishBundle(msg, this);
server.listSendBundle(nil, msg);
}
}
this means that every node that is sent to the server, say in Synth.new,
will have to perform an iteration on each argument, checking for it to be
of controlValue class.
Also it is inconsistent to have a special method for set (setControls),
but an internal translation in node.new.
maybe it would be better to have a message array.asSynthArgs or similar
that you send to the input args.
(btw. I think I'll remove target.asGroup.finishBundle(msg, this) too
as Ensemble class is apparently not used)
btw.
there is a typo in the helpfile:
( // Bus
b = Bus.control;
b.setControls([a]);
Synth("tri").map([\f,b.index]);
a.value_(400);
)
Synth("tri").map([\f,b.index]);
should be
Synth("tri").map(\f,b.index);
d)
OSCpathResponder(np.group.server.addr, ["/n_end", np.group.nodeID],...
you shouldn't rely on the group of the nodeProxy,
as on cmd-. the structure is lost.
the link should be removed only when the proxy calls .clear
I don't know how this dependancy should be resolved though.
e)
to have an "untyped" interface I would try to use multiple dispatch
to have one method for all connects:
a.connectToNodeProxy(np, key) could then be a.connectTo(np,key)
this method would call NodeProxy-connectControlValue(\key, val) or
Bus-connectControlValue(val).
also then the method wouldn't have to be implemented in Array, but
connectControlValue could return an array of busLinks you could then register
whith the OSCresponder.
why do you replace the controlValues in the array when you connect?
This could be very confusing if you want to reuse the same array.
connectToNodeProxy { arg np;
var nodeLinks, controlValue, name;
nodeLinks = [];
forBy (1, this.size - 1, 2, { arg i;
controlValue = this.at(i);
if( controlValue.isKindOf(ControlValue), {
nodeLinks = nodeLinks ++
controlValue.connectToNodeProxy(np, this.at(i-1));
this.put(i, controlValue.value);
});
});
if (nodeLinks.size > 0, {
OSCpathResponder(np.group.server.addr,
["/n_end", np.group.nodeID],
{ arg time, resp, msg; nodeLinks.do({
arg n; n.remove}); resp.remove;}
).add;
})
}
hope this is useful..
--
.
Next Message by Thread:
click to view message preview
Re: rfc: ControlValue
Hi Julian,
Thanks for the comments, here are some responses:
Here is some comments on what I saw in it. I think all in all it is a
good thing to have something like this on the 'system level' of sc.
a)
ControlValue seems not to be a Pattern (e.g. no asStream
parallelisation), although it subclasses Pattern.
I believe it should simply be a subclass of AbstractFunction or
of Stream
I don't understand what you mean here.
The goal of subclassing Pattern is to be able to write
Pbind(\field, aControlValue)
and have the ControlValue control the value of the field.
this you can do with by subclassing Stream, too.
or if you subclass AbstractFunction, you'd have to implement
embedInStream / asStream, like in Ref.sc
ControlValue should be no Pattern, because it doesn't create multiple streams.
If I use the same ControlValue in several places, I want it to be the
same ControlValue not a different one. I could write:
Pfunc({aControlValue.value})
instead, but that is slower and harder to read.
input_(input) why not call it set(input), same like synth.set,
bus.set, point.set, ref.set, ... server.set (just kidding).
the difference between input_ and value_ is not easy to understand if
you don't remember it from Preset/Items
The input_ method is intended as a generic interface for external control
sources (like MIDI or game controllers). So the idea is that the
all input_ methods expect a [0,1] range of values.
One could write
controlvalue.value(controlvalue.map(input))
but I want to have objects that start/stop or pause/resume be able to
tie in, so a method seems in order.
I am wary of calling it 'set' precisely because that method name is
heavily used with connotation of direct determination of internal state
rather than a scaled or transformed determination. There are classes that
have set defined that might use input_ as well, for example, EZ-slider.
ok, then I understand.
this means that every node that is sent to the server, say in Synth.new,
will have to perform an iteration on each argument, checking for it to be
of controlValue class.
Also it is inconsistent to have a special method for set (setControls),
but an internal translation in node.new.
Yeah, I didn't expect this to pass muster. The basic problem is that
there is no easy way to get at the nodeID, setControls has a delay
between the creation of the Synth and the effect of the controls.
I think I'll write a 'newWithControls' method. Actually, this is
better as then Group can support the same method.
new with controls might be cause of misunderstanding, as Control
is that thing in the UGen graph. But apart from that this is good,
I think.
OSCpathResponder(np.group.server.addr, ["/n_end", np.group.nodeID],...
you shouldn't rely on the group of the nodeProxy,
as on cmd-. the structure is lost.
the link should be removed only when the proxy calls .clear
I don't know how this dependancy should be resolved though.
What if there were a controlValues instance variable in NodeProxy and
and NodeProxy-group_ did the linking? The only expense would be
an if(controlValues.notNil, { });
hm, there is already a nodeMap that is supposed to care for the linkings.
I don't know it this is the best solution. Anyway usually np.clear is
called very conciously. so one might as well unlink the controls by
hand for now.
I'll think about it.
e)
to have an "untyped" interface I would try to use multiple dispatch
to have one method for all connects:
a.connectToNodeProxy(np, key) could then be a.connectTo(np,key)
this method would call NodeProxy-connectControlValue(\key, val) or
Bus-connectControlValue(val).
Hmm, with an untyped interface its hard to know what classes are
being supported. So, I thought it was a better idea to keep it very
explicit for the time being.
well, maybe I'm too much caring for condensed expressions. I can see
what you mean.
also then the method wouldn't have to be implemented in Array, but
connectControlValue could return an array of busLinks you could
then register
whith the OSCresponder.
The Array methods are needed to support raw OSC.
this I don't understand. They are not sent an osc message?
--
.
|
|