New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Republic Server #17

Closed
wants to merge 1 commit into
base: master
from

Conversation

Projects
None yet
3 participants
@telephon
Collaborator

telephon commented Nov 3, 2017

This adds original Republic functionality, which allows us to locate in
any OSC message a dispatcher to registered servers.

We just tested it and it runs nicely. A little under-the-hood, but very expressive. If you like it, we can also add documentation …

you can write stuff like Pbind(\where, Pseq([0, 5, 1], inf)), which sends to the first, fourth, and second participant. Maybe we could reintroduce \all again.

add Republic Server
This adds original Republic functionality, which allows us to locate in
any OSC message a dispatcher to registered servers.
@telephon

This comment has been minimized.

Show comment
Hide comment
@telephon

telephon Nov 6, 2017

Collaborator

doesn't multichannel expand correctly. We'll have to do it differently.

Collaborator

telephon commented Nov 6, 2017

doesn't multichannel expand correctly. We'll have to do it differently.

@telephon telephon closed this Nov 6, 2017

@muellmusik

This comment has been minimized.

Show comment
Hide comment
@muellmusik

muellmusik Nov 6, 2017

Owner

Sorry, did take a look and was meaning to write up some comments: This seems sensible and useful. I'd talked (with you? Alberto?) about other approaches. A custom event type would seem the 'supported' approach, but is a bit cumbersome. The name RepublicServer (while highlighting its noble lineage :-) is a little misleading. It's not really a server IIUC (okay it is, but...), it's a sort of adaptor which looks for keys to decide which Server to route to. As this is generally useful, not just for recreating functionality, maybe a more generic and descriptive name might make sense?

Also, I'm kind of nervous about this as a design that drops in in place of a server. Have you really thought through all that might mean, and any pitfalls? Would it be cleaner to keep the Server object separate and make this a simple adaptor used only exactly where it should be?

Owner

muellmusik commented Nov 6, 2017

Sorry, did take a look and was meaning to write up some comments: This seems sensible and useful. I'd talked (with you? Alberto?) about other approaches. A custom event type would seem the 'supported' approach, but is a bit cumbersome. The name RepublicServer (while highlighting its noble lineage :-) is a little misleading. It's not really a server IIUC (okay it is, but...), it's a sort of adaptor which looks for keys to decide which Server to route to. As this is generally useful, not just for recreating functionality, maybe a more generic and descriptive name might make sense?

Also, I'm kind of nervous about this as a design that drops in in place of a server. Have you really thought through all that might mean, and any pitfalls? Would it be cleaner to keep the Server object separate and make this a simple adaptor used only exactly where it should be?

@telephon

This comment has been minimized.

Show comment
Hide comment
@telephon

telephon Nov 6, 2017

Collaborator

Probably you are right. The aim is to make it really transparent, so any event that specifies a "where" will be redirected. You have to put the routing somewhere, and the good old way way to just spoof the lowest level - think deep packet inspection ;).

The main problem I ran into is that now the allocator scheme is far more intricate than it used to be, so that the actual nodes that are created on the different servers have the wrong ids. The allocators know nothing of "\where", because they are usually called much further up.

What we really need is an event type that flops before node id allocation happens.

This works, and could be used to distribute to multiple servers:

(
var flop = { |dict, keys|
	var values;
	keys = keys ?? { dict.keys.asArray };
	values = keys.collect { |x| dict.at(x) };
	values.flop.collect { |xs|
		var each = dict.copy;
		keys.do { |key, i| each.put(key, xs.at(i)) };
		each
	}.unbubble
	
};
Event.addEventType(\flop, { |server|
	var all;
	~server = server;
	~type = ~kind ? \note;
	all = flop.value(currentEnvironment, ~flopArgs);
	all.do { |each| each.play }
})
)


(
SynthDef(\sin, { | out=0, freq=440, sustain=0.05 |
	var env = EnvGen.kr(Env.perc(0.01, sustain, 0.2), doneAction: Done.freeSelf);
	Out.ar(out, SinOsc.ar(freq, 0, env))
}).add;

SynthDef(\saw, { | out=0, freq=440, sustain=0.05 |
	var env = EnvGen.kr(Env.perc(0.01, sustain, 0.2), doneAction: Done.freeSelf);
	Out.ar(out, Saw.ar(freq, env))
}).add;
)

(
Pbind(
	\type, \flop,
	\instrument, [\sin, \saw],
	\freq, [900, 50],	
).play;
)

we could simplify the note event a lot even, and then see how well it goes in terms of performance.

Collaborator

telephon commented Nov 6, 2017

Probably you are right. The aim is to make it really transparent, so any event that specifies a "where" will be redirected. You have to put the routing somewhere, and the good old way way to just spoof the lowest level - think deep packet inspection ;).

The main problem I ran into is that now the allocator scheme is far more intricate than it used to be, so that the actual nodes that are created on the different servers have the wrong ids. The allocators know nothing of "\where", because they are usually called much further up.

What we really need is an event type that flops before node id allocation happens.

This works, and could be used to distribute to multiple servers:

(
var flop = { |dict, keys|
	var values;
	keys = keys ?? { dict.keys.asArray };
	values = keys.collect { |x| dict.at(x) };
	values.flop.collect { |xs|
		var each = dict.copy;
		keys.do { |key, i| each.put(key, xs.at(i)) };
		each
	}.unbubble
	
};
Event.addEventType(\flop, { |server|
	var all;
	~server = server;
	~type = ~kind ? \note;
	all = flop.value(currentEnvironment, ~flopArgs);
	all.do { |each| each.play }
})
)


(
SynthDef(\sin, { | out=0, freq=440, sustain=0.05 |
	var env = EnvGen.kr(Env.perc(0.01, sustain, 0.2), doneAction: Done.freeSelf);
	Out.ar(out, SinOsc.ar(freq, 0, env))
}).add;

SynthDef(\saw, { | out=0, freq=440, sustain=0.05 |
	var env = EnvGen.kr(Env.perc(0.01, sustain, 0.2), doneAction: Done.freeSelf);
	Out.ar(out, Saw.ar(freq, env))
}).add;
)

(
Pbind(
	\type, \flop,
	\instrument, [\sin, \saw],
	\freq, [900, 50],	
).play;
)

we could simplify the note event a lot even, and then see how well it goes in terms of performance.

@monodread

This comment has been minimized.

Show comment
Hide comment
@monodread

monodread Nov 6, 2017

Hi Julian, Scott,
just a utopia user's comment on the side:
To have (again) the possibility of flexible targeting of recipients while playing would be really good & cool to have. I always thought that particularly the old 'where: \all' syntax, allowing for a "tutti" way of playing, gives nice dynamics of expanding and compressing the group size(s) during a performance. Quite a while ago Graham and I where working on a tool to also introduce some way of visualising this kind of routing-panning strategy (though never finished). Maybe now this is a good moment to pick it up again – I am however not part in any networking group for creating good test scenarios currently. :( will keep the idea in mind though. in any case: thanks for your work so far!

monodread commented Nov 6, 2017

Hi Julian, Scott,
just a utopia user's comment on the side:
To have (again) the possibility of flexible targeting of recipients while playing would be really good & cool to have. I always thought that particularly the old 'where: \all' syntax, allowing for a "tutti" way of playing, gives nice dynamics of expanding and compressing the group size(s) during a performance. Quite a while ago Graham and I where working on a tool to also introduce some way of visualising this kind of routing-panning strategy (though never finished). Maybe now this is a good moment to pick it up again – I am however not part in any networking group for creating good test scenarios currently. :( will keep the idea in mind though. in any case: thanks for your work so far!

@muellmusik

This comment has been minimized.

Show comment
Hide comment
@muellmusik

muellmusik Nov 27, 2017

Owner

My thinking is that an event type is the way to do it. The inconvenience of this is having to specify this in your streams. Two possible solutions:

  1. Add the ability to extend a given event type (i.e. note)
  2. Make it possible to set the default event type (perhaps already possible?)
Owner

muellmusik commented Nov 27, 2017

My thinking is that an event type is the way to do it. The inconvenience of this is having to specify this in your streams. Two possible solutions:

  1. Add the ability to extend a given event type (i.e. note)
  2. Make it possible to set the default event type (perhaps already possible?)
@telephon

This comment has been minimized.

Show comment
Hide comment
@telephon

telephon Nov 29, 2017

Collaborator
  1. Add the ability to extend a given event type (i.e. note)

You can do this:

Event.addEventType(\x, {
      ~myValue = ~thatOtherValue;
      ~type = ~kind ? \note;
      currentEnvironment.play
}
  1. Make it possible to set the default event type (perhaps already possible?)

that is a good idea. I think it is possible by setting the Event.defaultParentEvent.

Collaborator

telephon commented Nov 29, 2017

  1. Add the ability to extend a given event type (i.e. note)

You can do this:

Event.addEventType(\x, {
      ~myValue = ~thatOtherValue;
      ~type = ~kind ? \note;
      currentEnvironment.play
}
  1. Make it possible to set the default event type (perhaps already possible?)

that is a good idea. I think it is possible by setting the Event.defaultParentEvent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment