Skip to content
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

Other controls #16

Open
fis-cz opened this issue Aug 4, 2022 · 8 comments
Open

Other controls #16

fis-cz opened this issue Aug 4, 2022 · 8 comments

Comments

@fis-cz
Copy link

fis-cz commented Aug 4, 2022

Hi,

I love your project. I would like to ask, do you also plan to implement other controls (i.e. gain, phanotm, lpf, eq, compressor and so on?)?

I would like to help you as I want completely control the 24R mixer using the MIDI surface from the electron app. I'll try to help you with the protocol analysis, but I need to get in first.

@featherbear
Copy link
Owner

Hi @fis-cz, thanks for taking interest in the project.

Absolutely; I planned to implement absolutely everything that I can - and ideally recreate the functionality of Universal Control.
(Also a heads up, the folks at PreSonus seem to be developing an API of sorts for Universal Control, so this project may not be needed; though still has its purposes as an independent solution)

The controls you mentioned above are simple to add in, but I first need to solve #14 roadblock.

Currently this project is on hold for me because I'm busy finishing up my university thesis, but hopefully soon™ I should be able to jump back on to this!

@fis-cz
Copy link
Author

fis-cz commented Aug 13, 2022

Great news, I am trying to work with the code now but unfortunately I never obtain the first subscription packet. It seems to me that there is some problem with permissions as all are returning false in previous packets. Hopefully I'll be able to figure it out. I also try to take a look to CK, it seems to me there is ZB inside so I'll try to figure it out.

@featherbear
Copy link
Owner

featherbear commented Aug 13, 2022

There shouldn't be any permission restrictions if I remember correctly.
The access code is sent inside of the ZB packet (encapsulated within CK for detailed configurations) - but it is only a client-side check, so you should be able to completely avoid it, as per #5


You will likely need to use commit ce7f395 which has the ZB wait removed. Note that functions will break because they rely on the contents of ZB

Call connect with <API>.connect(..., true)

@featherbear
Copy link
Owner

Added a packet capture and some notes at #14 (comment)

@fis-cz
Copy link
Author

fis-cz commented Aug 13, 2022

Ok, so got it complete.

The ZB message is the standard compressed BSJson (https://neurojson.org/)

The CK chunk message is just a container for other messages.

CK followed by 6 bytes (some kind of header you've already described somehow, but not important for other parsing.
Then there is the data message identifier (such as ZB) which means compressed data followed by some zero argument then there is an offset of the data in the full data range, then there is total data size (all chunks) then there is the chunk size (current one):

CK xx xx xx xx xx xx ZB 00 00 00 00 aa aa aa aa bb bb bb bb cc cc cc cc XX XX XX XX

xx ... CK header (maybe it is some chunk ID as all related chunks seems to have same, but can't be sure)
ZB ... Chunked message identifier
00 ... ? probably some reserved space - it seems it is some message argument (as in CK case)
aa ... LE int32 data offset (in the final buffer)
bb ... LE int32 total data size
cc ... LE int32 current chunk data size
XX ... Chunk data

Currently I am using these two files to decode (d.ts needed for bjd) (npm install bjd), https://www.npmjs.com/package/bjd.

Of course, this needs to be improved so much, but it gives nice and full state of the mixer.

bjd.d.ts

declare module "bjd" {

   export function decode(data: Buffer): any

}

CK.ts

import Client from "../Client"
import * as zlib from "zlib";
import * as bjd from "bjd";

let chunkBuffer: Buffer[] = [];

export default function handleCKPacket(this: Client, data: Buffer) {

   data = data.slice(4);

   const chunkOffset = data.readUInt32LE(0);
   const totalSize = data.readUInt32LE(4);
   const chunkSize = data.readUInt32LE(8);

   const chunkData = data.slice(12);
   chunkBuffer.push(chunkData);

   if (chunkOffset + chunkSize === totalSize) {
      const fullData = Buffer.concat(chunkBuffer);
      const unzip = zlib.inflateSync(fullData);
      const data = bjd.decode(unzip);
      console.log(data);
   }

}

featherbear added a commit that referenced this issue Aug 14, 2022
Thanks to @fis-cz 🎉

See #16 (comment)

Closes #12
Closes #14
@featherbear
Copy link
Owner

featherbear commented Aug 14, 2022

That's awesome work @fis-cz! I didn't try to combine the two CK payloads... silly me

The https://www.npmjs.com/package/bjd package you used is an implementation of UBJSON.
I had originally implemented the decoder without knowing this, but I eventually found out it was UBJSON after looking at the Universal Control program binaries

I've updated the decoder implementation to support int64 values - 6eed523#diff-4d26eb190012397140dcf516873130b788d14e55420fde3feb6eb0b9b8a5cdf6R92-R98, and it seems to be working well! So we don't need to add in the extra bjd package

Issues #12 and #14 can now be closed ✨

@fis-cz
Copy link
Author

fis-cz commented Aug 17, 2022

Thanks, Great it works, I checked and it seems to be working even on my mixer (24R). Regarding the UBJson, It took a bit to me to figure out, what it is. It was clear it is some JSON extension, but was hard to find on the internet :) Just consider using of that standard lib for one of further major releases. I know it would have a big impact to the code, but as it is a standard and its source is available I would not be afraid to use it. For now, the parser seems to work correctly, but I need to test it more extensively.

@featherbear
Copy link
Owner

I'm happy to use a standard library, I only wrote it myself back when I didn't know that it was a UBJSON payload :)

According to the listed libraries on the specification website, there are two (though not officially checked)

I tried the second one a week ago but it didn't integrate right out of the box
Also, it may be worthwhile to implement an FFI call to the C / C++ code for better performance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants