MylesBorins / node-osc

Open Sound Control protocol library for Node.js
GNU Lesser General Public License v3.0
431 stars 72 forks source link

Bundled OSC Messages #47

Closed jshea2 closed 3 years ago

jshea2 commented 3 years ago

Is it possible to receive bundled OSC messages? I receive this error from the 'Server.js' every time I try:

Error: can't decode incoming message: invalid type tag in incoming OSC message, must start with comma at Socket. (/Applications/OSC for OBS.app/Contents/Resources/app/node_modules/node-osc/dist/lib/Server.js:29:23) at Socket.emit (events.js:315:20) at UDP.onMessage [as onmessage] (dgram.js:910:8)

MylesBorins commented 3 years ago

@jshea2 we can likely add support for this.

I'm quickly looking at the OSC spec and seeing the following for bundles

An OSC Bundle consists of the OSC-string "#bundle" followed by an OSC Time Tag, followed by zero or more OSC Bundle Elements. The OSC-timetag is a 64-bit fixed point time tag whose semantics are described below.

An OSC Bundle Element consists of its size and its contents. The size is an int32 representing the number of 8-bit bytes in the contents, and will always be a multiple of 4. The contents are either an OSC Message or an OSC Bundle.

Note this recursive definition: bundle may contain bundles.

This table shows the parts of a two-or-more-element OSC Bundle and the size (in 8-bit bytes) of each part.

Do you any sample code that generates / send a bundle? How would you expect the data to be represented when the message is received? It seems like a bundle is just a collection of messages with a time stamp, would you say that is accurate?

MylesBorins commented 3 years ago

as an alternative it seems like osc.js supports bundles already (thanks @colinbdclark), that might be a good alternative if you need stuff working today.

jshea2 commented 3 years ago

Sorry, totally didn't notice this until now.

I'm using this usually with show control software and some I've noticed that send bundles are 'TouchDesigner' and 'TouchOSC' if you enable it in settings (for testing/sample code). There are some sound and lighting consoles that only send bundled OSC also. Ideally, for my use I would like the data is just as it normally does as individual messages, so if it's possible for your library to take in the bundle OSC and iterate/separate them into separate messages. I also wouldn't need the Time Tag. Do you think this way is possible?

jshea2 commented 3 years ago

PS This library is awesome! Thank you so much for making it. Here's the project I'm using it for if you're curious: OSC for OBS

MylesBorins commented 3 years ago

Very cool! I may not be able to get to this immediately but will try and find some time to poke at it this weekend.

I'll poke at a few different ways to potentially create the "bundled" data packets... I'll see about getting the server to figure out how to receive and parse them, but likely won't add support to the client yet as it doesn't seem like you need them right now.

The underlying decoding / parsing is handled by a really old dependency so it is possible that the scope of this feature may be beyond what I can do in a short session, it might even push me to replace the dependency, which I've been wanting to do for a while.

Will keep you in the loop about progress.

jshea2 commented 3 years ago

Yes, no rush. Thanks so much! 🙌

MylesBorins commented 3 years ago

@jshea2 ended up being a bunch simpler than expected. PTAL at https://github.com/MylesBorins/node-osc/pull/48 and give it a whirl.

jshea2 commented 3 years ago

Thank you so much! This is probably a dumb question, but I'm so bad with git stuff. This isn't committed to the main branch, right? In terminal can I just run npm update "node-osc" or do I have to do a special syntax for this branch?

MylesBorins commented 3 years ago

@jshea2 do you know if your code base is CommonJS or ESM?

MylesBorins commented 3 years ago

@jshea2 I went ahead and wrapped everything up in a release candidate for a v6.0.0

can you try running npm install node-osc@next and play around with it. You can find docs in this branch https://github.com/mylesborins/node-osc/tree/next

jshea2 commented 3 years ago

Thanks! Testing it out now and it's throwing an error for my app:

Screen Shot 2021-04-24 at 11 51 17 AM

I haven't changed anything in my code yet, just updated the library. Looks like the problem might be with not finding "internal/warnings"? Anything I should change on my end?

MylesBorins commented 3 years ago

Hey Joe,

I bundled (pun intended) this change with some other changes that limited support to only more modern versions of node.js

Do you know which version of electron you are using? I can make some small changes to make it compatible

On Sat, Apr 24, 2021, 2:55 PM Joe Shea @.***> wrote:

Thanks! Testing it out now and it's throwing an error for my app: [image: Screen Shot 2021-04-24 at 11 51 17 AM] https://user-images.githubusercontent.com/70780576/115969764-875d9f00-a4f3-11eb-8f1d-8dbaa14afbee.png

I haven't changed anything in my code yet, just updated the library. Looks like the problem might be with not finding "internal/warnings"? Anything I should change on my end?

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/MylesBorins/node-osc/issues/47#issuecomment-826137947, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADZYVY67SGSULFVZ7U3VHTTKMHYLANCNFSM42LEZHQQ .

jshea2 commented 3 years ago

Lol I believe it's 11.0.3 from my devDependencies in package.json

MylesBorins commented 3 years ago

Reopening issue until we have confirmation that this works (and I release 6.0.0)

@jshea2 I've removed use a package.imports, which I think was causing the error you were running into. I very much wanted to start using that new feature but might need to wait a tiny bit longer 😢

I just published 6.0.0-r.c.2 which should work for you now. PTAL

jshea2 commented 3 years ago

Thank you! No worries, is it the same node-osc@next for installing?

MylesBorins commented 3 years ago

Yup

jshea2 commented 3 years ago
Screen Shot 2021-04-25 at 2 43 06 PM

So I got the new update installed and I'm still getting the same original error when i send the bundled osc. I've tried putting in your new code and commenting out my current OSC listening message. Do you want me to send you a sample Touchdesinger show file? That's what I'm currently using to test. Plus TD is free to use osc

MylesBorins commented 3 years ago

If you could share a touch designer file that would be great

On Sun, Apr 25, 2021, 5:52 PM Joe Shea @.***> wrote:

[image: Screen Shot 2021-04-25 at 2 43 06 PM] https://user-images.githubusercontent.com/70780576/116010657-345c1880-a5d5-11eb-8ea6-af2d1ce38933.png

So I got the new update installed and I'm still getting the same original error when i send the bundled osc. I've tried putting in your new code and commenting out my current OSC listening message. Do you want me to send you a sample Touchdesinger show file? That's what I'm currently using to test. Plus TD is free to use osc

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/MylesBorins/node-osc/issues/47#issuecomment-826395775, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADZYV3LISL35G5VJ6EK4FDTKSFKVANCNFSM42LEZHQQ .

jshea2 commented 3 years ago

https://drive.google.com/file/d/1ZARg6eskuGJ0F97wvFmWpk5Yo3U7tS_J/view?usp=sharing

It's set up to send a bundle of 2 OSC messages (/test and /test2) to localhost on port 3333

MylesBorins commented 3 years ago

@jshea2 I think I figured out what's going on... When I did the last publish I didn't set the correct dist-tag and actually published over latest instead of publishing it as next... oops.

I've updated the tags but it might take a bit of time for the change to propagate on npmjs.com

Try install the specific version install npm install node-osc@6.0.0-rc.2

Here is a small script you can run standalone in Node.js to see the bundles coming from touch designer are working (I tested locally). If you are still running into issues and want to share the project with me I can take a look and see if I can get it working.

const { Server } = require('node-osc');

var server = new Server(3333, '0.0.0.0');

server.on('listening', () => {
  console.log('OSC Server is Listening');
});

server.on('bundle', (bundle) => {
  bundle.elements.forEach(element => {
    console.log(`${bundle.timetag[0]}.${bundle.timetag[1]} ${element.join(' ')}`);
  })
});
jshea2 commented 3 years ago

This works amazing! Thank You!

The last question I had is I'm trying to make a filter if it has the same address' and values as the previous then just return else send bundle. That way the console on the user's end isn't getting spammed with logs. I set it up like this:

server.on('bundle', function (bundle) {
    if (lastBundle == bundle.elements){
        console.log('YOU SHALL NOT PASS')
        return
    } else {
    console.log(lastBundle)
    console.log(bundle.elements)
    lastBundle = bundle.elements
    bundle.elements.forEach((element, i) => {

    //console.log(`Timestamp: ${bundle.timetag[i]}`);
    if (element.includes("/_samplerate")){
        return
    } else {
        console.log(`Message: ${element}`);
        clientLoopback.send(element)
    }
});
    }
});

(I have a global let lastBundle = {})

The problem I'm getting is when I store the lastBundle it's not storing the arguments, only the addresses.

Screen Shot 2021-04-25 at 5 34 28 PM
MylesBorins commented 3 years ago

@jshea2 thinking through it... unless it has the same timetag don't you still want to forward the data? The odds are you are not getting duplicated data unless there is an error with tool / software / hardware sending the OSC messages. I can think of valid instances of the exact same data on the same address such as a light sensor having its beam "broken".

With that said you can't do comparison by comparing to deep objects, since they will technically be "different objects" even if the contents are the same. You want to do a "Deep Equality" check... which you can do using the built in assertion library in Node.js, although it might not be the best way to do it (there are utility libraries for this too). Here's an example

const { notDeepStrictEqual } = require('assert');
const { Server } = require('node-osc');

var server = new Server(3333, '0.0.0.0');

server.on('listening', () => {
  console.log('OSC Server is Listening');
});

server.on('error', e => {
  console.error(e);
})

let lastBundle;

server.on('bundle', function (bundle) {
  try {
    notDeepStrictEqual(lastBundle, bundle.elements)
  } catch (e) {
    console.log('YOU SHALL NOT PASS')
    return
  }
  console.log(lastBundle)
  console.log(bundle.elements)

  lastBundle = bundle.elements
  bundle.elements.forEach((element, i) => {
    //console.log(`Timestamp: ${bundle.timetag[i]}`);
    if (element.includes("/_samplerate")){
        return
    } else {
        console.log(`Message: ${element}`);
        // clientLoopback.send(element)
    }
  });
});
MylesBorins commented 3 years ago

closing again as it seems we have something working. Feel free to keep asking questions

jshea2 commented 3 years ago

Thanks again for adding this feature and how responsive you've been! Much appreciated! I have some time tomorrow to test this code.