|
From: Stephen S. <rad...@gm...> - 2012-02-28 22:36:48
|
On Mon, Feb 27, 2012 at 6:59 PM, J. Liles <mal...@gm...> wrote: > > Ha. Yes, I saw that recently. I wasn't aware you were the one working on it. > I actually took a couple of days to implement something similar for Non > (going into the next release). The difference is that I don't use multicast > (peers discover eachother through NSM), and a central authority (NSM) > assigns the symbolic names for each peer. Therefore, all the connections are > internal to the session. I have outputs, inputs, listing, automatic syncing > with notifications of signal ports being destroyed and created, renamed etc. > All signals have range limits and one output can connect to multiple inputs > and inputs receiving signal data from multiple outputs do additive mixing. > So, basically, I'm emulating the exact features I had with Control Voltage > signals over JACK, but in a lower data rate with OSC and calling it Control > Signals. Interesting, we have considered the converse, adding a JACK transport for connections that require high bandwidth ;) Not quite there yet though, everything is still UDP/IP packets for now. However each connection can have its own "properties", so in theory it's possible to specify other transport layers. We're planning to add an option for TCP soon, so liblo's TCP support will get a lot more exercise from me eventually. > I think the only things I'm lacking are the formula, and I don't think that > should go in the system anyway, as you could always have a device sit > between two peers and do transformations. Yup, we do that for more complex things that require "mixing" signals. If two clients send to the same destination, the messages will just mix together, so if it's necessary to add two signals or combine them in other ways, it's necessary to create an intermediate layer. We are doing this for some fun machine learning stuff. > If it weren't for the multicast stuff and the lack of an obvious way to > assign specific peer names by a central authority, I would have probably > just used libmapper... It certainly would have been less trouble, I'm sure. Multicast is only used in libmapper for coordinating, the data streams are sent directly between peers. We chose multicast because it was a convenient way to get multiple computers to find each other. Actually I've had some ideas about allowing peers to mirror the multicast bus to each other, allowing a kind of mesh network approach. We were specifically looking to avoid the "central authority" approach however, but there's no fundamental reason we couldn't have gone that way. We just used multicast because it meant not having to run a "server". For the session management scenario I can totally see why having a "master control station" makes sense though, as it simplifies certain things. (Hence *cough* some of our difficulty with er.. session management. We've got some good ideas though, just more ideas than time to work on them.) > Anyway, you'll be able to see what I've done in the next release of Non*. > Maybe we can find some ways to bring the two systems together in a > compatible way. IMHO, OSC is practically useless for audio software control > purposes without some kind of signal layer like libmapper provides, so I'm > all for helping its adoption, even if I do seem a little Gung Ho by > implementing my own. Sure, let's see where it goes. We'd love more people to use it and think we've got a good approach here, but it's just as interesting to hear about places where it sort-of-fits-but-not-exactly, because maybe it could use ideas we didn't think of. Some sort of connection protocol for OSC is clearly needed, it's just hard to get people to agree on one. > It's just usually faster for me to do it myself than > deal with external dependencies. Believe me I get that ;) > Just adding + getpid() in the equation would probably fix it. However, I > think one of the patches I saw relied on the OS to assign the port number, > which is probably even better. Agreed, I'll look into it. > >> >> > 2. Bi-directional TCP is lacking, and it would be nice to have. >> >> Main problem here is API. I'm not sure how it should be done in terms >> of how specific the relationship between a server and address. There >> were some tentative ideas on the list previously but nothing concrete. >> Something about lo_address_new_for_server() or something to that >> effect, or maybe lo_server_get_address().. hm. Or maybe >> lo_send_message_from() would be enough to do this. > > > I don't see what lo_send_from couldn't. Maybe that's the way to go then. >> > 3. There's no call that I can see in the API to (always) get an IP >> > address out of a lo_address handle. >> >> There is lo_address_get_hostname() which returns a string that could >> be passed into gethostbyname(). It could be nice to add a function >> that returns the already-resolved address, although it would have to >> smoothly handle both IPv4 and IPv6. > > > Specifically, my issue has to do with storing peer addresses in tables and > comparing them with incoming messages. Even just an API function to compare > two lo_addresses would be fine, but I think getting the IP is more general > (and yes I know I'm ignoring NAT and all that stuff). A function to compare lo_addresses is not necessarily a bad idea, since it seems to me that comparing IP addresses would require some kind of custom function anyways, due to handling IPv6. Suddenly you require some smarts to check if two addresses are the same instead of being able to just compare some integers. (For instance, an IPv4 address can be embedded in an IPv6 address...) You could restrict your application to IPv4 though, to simplify, and I agree there should be a way to get at this information. The lo_address structure keeps an addrinfo anyways, all it needs is an accessor function. >> 4. I'm not sure that I understand why lo_send can't always behave like >> lo_send_from. > >> I'm not sure what you mean here, lo_send() doesn't take the same >> arguments as lo_send_from()? The idea is to be able to send a message >> that is not associated with a server. > > > You're right. My fault. Let me say it another way: I don't see why lo_send() > should be in the API ;-) Maybe I'm not understanding.. sometimes apps do not need to receive OSC messages but only send them, I've definitely written programs that never create a lo_server(). >> > 5. Multithreading semantics aren't articulated in the documentation. >> > Is it save to call lo_send_from on the same server that's being recv'd >> > on in another thread? >> >> Documentation could be improved. Personally I'm not a fan of using >> any threading with liblo, I try to keep my liblo calls on the same >> thread, so I never use the lo_server_thread API. >> As for the specific question, lo_send_from() only accesses the >> server's fd, which doesn't change so I can't think of any threading >> issues here. > > > I'm not really talking about lo_server_thread (I don't use it either). Just > about what is threadsafe and what isn't. Right. This might take some thought and some work. Let's see: There is very little global data shared between calls to liblo fortunately, so most of it should be threadsafe between different lo_address and lo_server instances. I would probably avoid passing in the same instance of these in different threads simultaneously, though most _get() functions are likely safe to call in parallel, but this would need verifying. One issue that has always irked me on this front is the use of the lo_client_sockets global data in server.c/send.c. It is used for reusing sockets between calls to lo_send(), and for reusing the first server socket if one has been previously created. I recall looking into removing it once, or at least ensure that it only gets written to once, but never finished the job. I think it turned out to be more complicated than I'd expected. Not sure if this poses issues with thread safety but it struck me as one of the few places where the use of global data might cause problems. Steve |