Base64 Encode/Decode #732
-
|
Does anyone know if there is base64 decode and encode functions in Ctrlr? I'm building a chain manager for the Eventide H9000 and as part of that there are small gzip files that are encoded in base64 and saved within a json file. I need to be able to decode them, change a couple of parameters, and then re-encode them. |
Beta Was this translation helpful? Give feedback.
Replies: 19 comments 26 replies
-
|
There's a base64 class in Juce with encode/decode functions: If it's not bound to Lua yet I'll take a look at it tonight. |
Beta Was this translation helpful? Give feedback.
-
|
The encode decode from/to base 64 is already available to Lua when processed from a memory block : I did not see the whole base 64 class bound so I'll add it to the to do list. Let me know if you can convert it if loaded as memory block 😉 |
Beta Was this translation helpful? Give feedback.
-
|
No problem, I read on the JUCE forum that the decode from base64 is very strict and fails easily if the syntax is not perfect from the source file. Someone there suggested a more tolerant class for this particular task. Take care, get well soon! |
Beta Was this translation helpful? Give feedback.
-
|
Maybe just do it all in lua? |
Beta Was this translation helpful? Give feedback.
-
|
It will be possible to use JUCE zlib in CtrlrX. I can also import GZIP files (.gz) but cannot write to .gz, so the user could in theory load your JSON files now contained in .gz and then the user would resave as .zlib in future versions of your software. You could also perhaps create your own extension, or even use .gz although it wouldn't really be .gz of course. Have also implemented base_64 encoding/decoding for CtrlrX 5.6.34 Note, from google: It is a well-documented fact that the JUCE framework, including version 6.0.8, uses zlib for its compression, despite the naming of certain classes. For many years, users have pointed out that JUCE's GZIPCompressorOutputStream and GZIPDecompressorInputStream classes actually implement zlib compression. |
Beta Was this translation helpful? Give feedback.
-
|
I might as well do a PR for the zlib binding anyway, but it looks like you won't be able to use it. The latest build of CtrlrX now supports XML. Maybe ditch JSON and use XML instead? I've got a panel somewhere that will show you how to implement it. Will check when I get home. |
Beta Was this translation helpful? Give feedback.
-
|
How are you base64 decoding and encoding? Maybe there’s a problem with the base64 library you are using? you could try this build: local base_64_string = utils.base64_decode(input)
local base_64_string = utils.base64_encode(input)
|
Beta Was this translation helpful? Give feedback.
-
|
So for Windows, you're using something like this? |
Beta Was this translation helpful? Give feedback.
-
|
Some interesting reading on Zlib and Gzip and friends here. |
Beta Was this translation helpful? Give feedback.
-
|
I've managed to fix the string, decode the json and extract the base64 string. Directly decoding the string doesn't work with either base64 algorithm, but I think I first need to declare a MemoryBlock and decode into that, then save that memory block to a gzip file. It's late, so I'll try to find some time tomorrow to test it. If anyone wants to have a go the base64 encoded gzip is
A base64 decode should give a gzip file. When it is unzipped it should give a json file
This tool does the base64 decode and gunzip in 1 step - https://codebeautify.org/gzip-decompress-online |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Finally got it working.
You can to build CtrlrX from this branch or download prebuilt exe
I haven't checked any of this functionality. |
Beta Was this translation helpful? Give feedback.
-
|
Big Drum Room.zip When you load it the json file fails because it doesn't load the empty slot ,{}]} at the end. I'm currently running a check for this case, and concatenate that string at the end if it doesn't end with that. This file has 3 of the 4 slots filled. I still haven't tested chains with 1, 2 or 4 slots filled, but I suspect 1 will end with ,{},{},{}]}, 2 will end with ,{},{}]} which will require a more intensive check (I was going to count the number of times "preset":" appears to determine how the string should end. For the zip file included here, if you add ,{}]} to the end of the string, then the json file will load fine and you can extract the json data. This is the gunzipped json file (below) I'm most interested in the section starting with "slots"
json key "preset" gives the base64 encoded gzip file of the preset json file, which I need to also get into to modify the id (I call it the inner id) and I also need to set the other "id" tag (not in the base64 bit) which I call outer id. These both need to be set to user definable id's (there's a formula for decoding these which is below) You can navigate to the different slots by just referring to table elements 1, 2, 3, 4 in place of a specific json key. Currently the H9000 has a maximum of 4 algorithms loaded in a chain, but this may change in the future. An algorithm can be saved without a preset in the chain (a pseudo unnamed preset is created in the preset tag), but it may also be associated with a preset, which are saved parameters of an algorithm, and can have a preset name and preset id. The code below is from processing preset files (not chain files) so the json tags won't work for chain files, but the logic for the bank and algorithm numbers is the same. |
Beta Was this translation helpful? Give feedback.
-
|
Will look at it tomorrow- maybe json.decode is failing like you had suggested originally, because the nesting is too deep? |
Beta Was this translation helpful? Give feedback.
-
|
Perhaps you already read this? I tried some fixes but no dice! Tricky stuff all right. |
Beta Was this translation helpful? Give feedback.
-
|
I think I've finally managed to crack it open, at least for reading the files. Thanks everyone for your help and inspiration. I've just about finished the 1 case where there are 3 of the 4 slots filled, for reading the data. I still have heaps to do for the other cases, and still need to do all the modulator interaction, and then the daunting task of modifying the relevant bits of data and reassembling them all into a file that can be loaded into the H9000. I did find there is actually a 3rd level of encoding which is an encapsulated preset from the Eventide pedals/plugins, which will be handy if I ever want to migrate patches between Eventide products, but that will be a future enterprise. The in line gzip and base64 decoding is working a treat and I'll probably migrate my old code across to make things more steamlined. I'll post some more code once I've cleaned it up, and look forward to the next 5.6.34 ctrlrX distribution so I have it on OSX as well. I'm not configured for compiling from source at the moment. |
Beta Was this translation helpful? Give feedback.
-
|
I have stumbled into another issue. The exported file contains escape characters, so / instead of / and \n I also have an issue with assembling the final file, but that one I'll track down. |
Beta Was this translation helpful? Give feedback.
-
|
I created an installer for VST3,VST2 and EXE (64 bit) here: https://github.com/dnaldoog/CtrlrX/releases/tag/5.6.34_ZLIB_Oct24 |
Beta Was this translation helpful? Give feedback.
-
|
For json.encode and json.decode, are these bound to juce functions directly? I wanted to try the http://dkolf.de/dkjson-lua/ library as it doesn't havhe same empty array issues as json4lua as per http://lua-users.org/wiki/JsonModules, but I can't get the global module json to invoke the dkjson functions, and when I commented out json4lua and dkjson modules in their entirety, the json.encode and json.decode still ran indicating that these are calling from somewhere else, not from the lua modules. I've managed to get the chain editor working for some of the chain files, but it seems Eventide are not consistent about how they encode the json. Rant mode on For some files the slots are array elements, but for others, they are tagged as keys within a single array element, and what's worse, is that they don't always use the lowest numbers of slots, instead creating a sparse array/table. I have one chain that has slots 0, 1 and 3 with entries but slot 2 is empty, which vastly complicates the checking. I think if some string elements on the H9000 contain square brackets, Eventide encode the files differently. This comes from legacy code in an info tag that probably harks back to the H3000. I wish they had just fixed the text elements in their database and standardized the data format rather than just building edge cases for encoding old strings that actually have nothing to do with the dsp code and is essentially just cosmetic. I'm having to build additional logic to check stuff on the file as a string before I can decode the json file for each of these issues I come across which is infutiating. I was hoping to try a more robust/tolerant json.decode function to hopefully open the files and allow me to do the checks on content of json keys rather than very involved string searches, but I think there is generally an issue with opening json (and probably ascii, and maybe data) files that have square brackets before we even get to the decoding. A few things I've learnt about json files:
Anyway, I'm calling it a night and will get back to elaborate string searches tomorrow to deal with how Eventide have built their json files. Rant mode off. |
Beta Was this translation helpful? Give feedback.



I haven't got to base64 yet. I'm still working out how to parse the json file.
The structure is like this
gzip file
-> json file
--> Bunch of tags
--> id
--> base64 string
---> gzip file
----> json file
-----> bunch of tags
-----> id
--> Bunch of tags
--> id
--> base64 string
---> gzip file
----> json file
-----> bunch of tags
-----> id
This is how I'm doing gunzip
tempOutput = io.popen('gzip -d -S 9kf -k "'..fileToConvertPath..'"')To gzip
tempOutput = io.popen('gzip -S .9kp -k -f "'..destinationPath..'*."')This is the library I'm looking at using for base64