musikinformatik / SuperDirt

Tidal Audio Engine
GNU General Public License v2.0
519 stars 75 forks source link

Messages redirection to another SuperCollider instance? 😟 #243

Closed ZephyrRaine closed 3 years ago

ZephyrRaine commented 3 years ago

Hello everyone! Thank you very much for maintaining this great tool; a friend and I just started messing with TidalCycles and GLSL, inspired by all the livecoding we've watched lately.

The problem 🕵️

I'm at my home and want to do shaders coding, while my friend is at his doing some Tidal magic. For sharing the shader part it's no trouble, Atom comes with Teletype so I can push my changes seamlessly to his computer. However, altough we can easily share a Tidal file it doesn't play the same things as him on his computer (obviously).

Resolution attempt 🔨

Our idea was to redirect all messages between Tidal and his SuperCollider instance to mine, so I opened a port on my router and he redirected all incoming messages from Tidal like so :

//CODE SENT ON HIS END
var addr = NetAddr.new(MY_IP_ADDRESS, 3333);

f = { |msg, time, tidalAddr|
    if(msg[0] != '/status.reply'){
        if(msg[0] != '/n_end'){
            if(msg[0] != '/n_go'){
                var latency = time - Main.elapsedTime;
                addr.sendBundle(latency,msg);
            }
        }
    }
};
thisProcess.addOSCRecvFunc(f);

SuperDirt.start;
SuperDirt.resetEverything;

addr.sendMsg("/dirt/handshake");

While on my end I only have

SuperDirt.start

as I would if I was using Tidal "legally", the idea being that SuperCollider wouldn't be able to tell the difference between a genuine TidalCycles client and this mess of a hack... (As you can see we even tried including the handshake but my SC doesn't reply at all, as it does with a genuine Tidal 😭).

I peeked into SuperDirt code and the playFunc function we can see below, thinking I could use an OSCFunc and kinda recreate the behavior I have when simply doing SuperDirt.start but it seems non-trivial without recreating all SuperDirt behavior with orbit management and modules etc etc.

image

So we settled on trying to make SuperCollider thinks it's interacting with a legit Tidal instance.

Networking details 💻

The redirection through the above code seems to work well, OSCFunc.trace(true, true) on my end displays everything as expected, and when comparing packets through Wireshark I can't catch any key difference between this redirect messages and legit Tidal messages (not the same Tidal events but the messages seem correctly constructed) :

image

This is the handshake message sent from my friend (left) and Tidal (right). With Tidal, my SC instance does reply to Tidal, while with my friend my SC simply doesn't respond, as shown below.

image

image

Conclusion

Do you have any ideas what's missing to make my SC thinks it's interacting with a genuine TidalCycles client?

At the end of the day, it's not an ultimate dealbreaker and we'll probably just end up sharing an audio stream from his computer to mine (as I don't need to interact with Tidal at all on my end), but it seemed like a great way to get our hands dirty with SuperDirt (got it?), and would still appreciate some clues if you can spare some time ❤️.

telephon commented 3 years ago

Well, are you listening on port 3333? By default, your superdirt will listen on port 57120.

//CODE SENT ON HIS END
var addr = NetAddr.new(MY_IP_ADDRESS, 3333);

Btw. a less intrusive solution is not to redirect all the incoming messages (the handshakes will point to the wrong reply address that way, I think. But you can ignore the handshake for now, I think).

(
OSCFunc({ |msg, time|

    // do your forwarding here

}, "/dirt/play", ~dirt.senderAddr, recvPort: ~dirt.port).fix
)
ZephyrRaine commented 3 years ago

Thank you for your reply, @telephon

The external (internet facing) port is indeed 3333, and it's redirected to 57120 by my router internally. I do receive the messages correctly on the receiving SuperCollider instance.

We will try your method for forwarding but my main issue is that SuperDirt doesn't interpret received messages as instructions to play!

EDIT: tried your code locally and got this result on the receiving SuperDirt, which means only /dirt/play messages are received, which is great, unfortunately, despite receiving good messages it doesn't play any sound : image

ZephyrRaine commented 3 years ago

When peering into the code I noticed SuperDirt.start can be expecting a senderAddr which is the adress from which it'll accept instructions. By default, this is localhost but by replacing it with the actual sender address or 0.0.0.0 to accept all incoming addresses it works really well!

Sorry for the trouble @telephon :)