Saving chunk in Reaper rpp format


#1

Hi,

I’m currently extracting the vsti chunk in a JUCE host and writing it to a SQLite db blob.

MemoryBlock chunk;
bool isPreset = true;
bool ret = VSTPluginFormat::getChunkData(plugin, chunk, isPreset);

rc = sqlite3_bind_blob(stmt, num_params + 1,
        chunk.getData(), chunk.getSize(), SQLITE_STATIC);

How can I, instead, write the chunk to a txt file in Reapers Base64 format? I mostly code in ocaml, my C++ is very shakey.

  <VST "VSTi: ACE (u-he)" ACE.vst 0 "" 1633895765
    VUVjYe5e7f4CAAAAAQAAAAAAAAACAAAAAAAAAAIAAAABAAAAAAAAAAIAAAAAAAAAnxUAAAEAAAAAABAA
    I3BnbT1pbml0aWFsaXplCi8qQG1ldGEKCkF1dGhvcjoKJ1VycyBIZWNrbWFubicKCiovCgojQU09QUNFCiNWZXJzPTEwMDAxCiNFbmRpYW49bGl0dGxlCiNubT0xOQoj
    bXM9bm9uZQojbXM9TW9kV2hsCiNtcz1QaXRjaFcKI21zPUJyZWF0aAojbXM9WHByZXNzCiNtcz1HYXRlCiNtcz1WZWxvY2l0eQojbXM9UHJlc3N1cmUKI21zPUtleUZv
    bGxvdwojbXM9S2V5Rm9sbG93MgojbXM9QWx0ZXJuYXRlCiNtcz1SYW5kb20KI21zPVN0YWNrVm9pY2UKI21zPUFEU1IxCiNtcz1BRFNSMgojbXM9UmFtcDEKI21zPU1N
    YXAxCiNtcz1DVjAKI21zPUNWMQojbnY9MwojbXY9R2F0ZQojbXY9QURTUjEKI212PUFEU1IyCiNjbT1tYWluCkNjT3A9MTAwLjAwCiNjbT1QQ29yZQpTQmFzZT00ClN3
    aW5nPTAuMDAKU1RyaWc9MQpQU29uZz0wClBGb2xkPTAKUEZpbGU9MQpHRmlsZT0yCkdTY2FsZT0wCkNoTGF5PTAKU3Vyck89MQpSZXY9MjM3MwpMRUQ9MC4wMApQQUdF
    PTAKUGFnZXNPbj0wCkNvcmVOPTMKU2xpY2U9NApVSV9vcD0xCk1pZGlBPTUKTWlkaVA9NgojY209VkNDClZvaWNlcz0xClZvaWNpbmc9MQpNb2RlPTAKUG9ydGFNPTEK
    UG9ydGE9MC4wMApQb3J0YTI9MC4wMApQUmFuZ2U9MTAwLjAwClBCPTIKUEJEPTIKRHJmdD0xCk1UdW5TPTAKTVR1bk49NwpNVHVuVD04ClRyc3A9LTEyCkZUdW49MC4w
    MApWYzE9MC4wMApWYzI9LTAuMDgKVmMzPTAuMDgKVmM0PS0wLjE2ClZjNT0wLjE2ClZjNj0tMC4yNApWYzc9MC4yNApWYzg9LTAuMzIKUHJpb3I9MApNdUNvcmU9MApD
    b250RW49MApSTm90ZT0wClJWZWw9MAojY209RU5WMQpBdGs9MS4wMApEZWM9NTAuMDAKU3VzPTEwMC4wMApGUj0wLjAwClJlbD0xMi4wMApWZWw9MC4wMApSTW9kPTAu
    MDAKUk1TcmM9MApMTW9kPTAuMDAKTE1TcmM9MApDUmF0ZT0wClNuYXBweT0wCkZSUm5nPTEwMC4wMApMYWJlbD05CkF0dHI9MC4wMApMYWc9MC4wMApUcmlnPTAKI2Nt
    PUVOVjIKQXRrPTEuMDAKRGVjPTUwLjAwClN1cz0xMDAuMDAKRlI9MC4wMApSZWw9MjAuMDAKVmVsPTAuMDAKUk1vZD0wLjAwClJNU3JjPTAKTE1vZD0wLjAwCkxNU3Jj
    PTAKQ1JhdGU9MApTbmFwcHk9MApGUlJuZz0xMDAuMDAKTGFiZWw9MTAKQXR0cj0wLjAwCkxhZz0wLjAwClRyaWc9MAojY209UmFtcDEKVXA9MC4wMApIb2xkPTAuMDAK
    RG93bj01MC4wMApSZXN0PTEwMC4wMApDbG9jaz0wCiNjbT1NTWFwMQpNb2RlPTMKTVNyYz0wClN0cHM9MTEKTnVtPTE3CiNjbT1BQ0UxCk91dFNyYzE9MApPdXRTcmMy
    PTAKRmlsdExrPTAKRmlsdE1kPTAKUXVhbGl0eT0zCk9zY0JhbD0tMTAwLjAwClN1YlZvbD0wLjAwCk5vaXNlPTAuMDAKTWl4U3JjPTAKU291cmNlPTAuMDAKTFBUeXBl
    MT0zCkZUeXBlMT0wCkxQVHlwZTI9MwpGVHlwZTI9MApXU2VxPTEyCkNWU3JjMT0wCkNWU3JjMj0wClNsb3A9MC4wMApDVGFsaz0wLjAwCk9zY0NhcD0wLjAwCk14T3Nj
    PTAKTXhTdWI9MApNeE5vaXNlPTAKRlJzZXQ9MAojY209TEZPMQpUTW9kZT00ClR1bmU9MS4wMApGaW5lVHk9MwpGaW5lPTEuMDAKRk1TcmM9MApGTURwdD0wLjAwCkZN
    UmVzPTIKUGhhc2U9NTAuMDAKUE1TcmM9MApQTURwdD0wLjAwClJlc2V0PTEKVm9sPTUwLjAwClZNU2M9MApWTURwdD0wLjAwClNIU3JjPTAKV2F2ZT0xCkxhYmVsPTEz
    CiNjbT1MRk8yClRNb2RlPTQKVHVuZT0xLjAwCkZpbmVUeT0zCkZpbmU9MS4wMApGTVNyYz0wCkZNRHB0PTAuMDAKRk1SZXM9MgpQaGFzZT01MC4wMApQTVNyYz0wClBN
    RHB0PTAuMDAKUmVzZXQ9MQpWb2w9NTAuMDAKVk1TYz0wClZNRHB0PTAuMDAKU0hTcmM9MApXYXZlPTEKTGFiZWw9MTQKI2NtPTJWQ08KV2F2ZUYxPTAuMDAKVE1vZGUx
    PTAKVHVuZTE9MC4wMApGaW5lVHkxPTAKRmluZTE9MC4wMApGTVNyYzE9MApGTURwdDE9MC4wMApGTVJlczE9MgpQVzE9NTAuMDAKUFdTcmMxPTAKUFdEcHQxPTAuMDAK
    UmVzZXQxPTAKV2F2ZUYyPTAuMDAKVE1vZGUyPTAKVHVuZTI9MC4wMApGaW5lVHkyPTAKRmluZTI9MC4wMApGTVNyYzI9MApGTURwdDI9MC4wMApGTVJlczI9MgpQVzI9
    NTAuMDAKUFdTcmMyPTAKUFdEcHQyPTAuMDAKUmVzZXQyPTAKU3luYz0wLjAwClNuY1NyYz0wClNuY01TcmM9MApTbmNNRHB0PTAuMDAKU3ViVHlwZT0wClZvbDE9MC4w
    MApWb2wyPTAuMDAKU3ViVm9sPTAuMDAKRk0xMj0wLjAwClJNMTI9MC4wMApGTVNyYz0wClRyaU1kPTAKVmlicmE9MC4wMApMYWJlbD0xNQojY209VkNGMQpGTVNyYz0w
    CkZNRHB0PTAuMDAKQ3V0b2ZmPTE1MC4wMApGTVNyYzE9MApGTURwdDE9MC4wMApGTVNyYzI9MApGTURwdDI9MC4wMApLZXlGb2w9MC4wMApSZXM9MC4wMApSZXNTcmM9
    MApEQ0Jsaz0wCkxhYmVsPTE2CiNjbT1WQ0YyCkZNU3JjPTAKRk1EcHQ9MC4wMApDdXRvZmY9MTUwLjAwCkZNU3JjMT0wCkZNRHB0MT0wLjAwCkZNU3JjMj0wCkZNRHB0
    Mj0wLjAwCktleUZvbD0wLjAwClJlcz0wLjAwClJlc1NyYz0wCkRDQmxrPTAKTGFiZWw9MTcKI2NtPU11bHRpMQpJbjFBPTAKSW4xQj0wCkluUk09MApJbjJBPTAKSW4y
    Qj0wCkdhaW4xMj0xMDAuMDAKR2FpbjM0PTEwMC4wMApMYWJlbD0xOAojY209TXVsdGkyCkluMUE9MApJbjFCPTAKSW5STT0wCkluMkE9MApJbjJCPTAKR2FpbjEyPTEw
    MC4wMApHYWluMzQ9MTAwLjAwCkxhYmVsPTE5CiNjbT1WQ0ExClBhbj0wLjAwClZvbD01MC4wMApWQ0E9MQpNb2RTcmM9MApNb2REcHQ9MC4wMApQYW5TcmM9MTcKUGFu
    RHB0PTAuMDAKQXR0Uz0xCiNjbT1WQ0EyClBhbj0wLjAwClZvbD0wLjAwClZDQT0xCk1vZFNyYz0wCk1vZERwdD0wLjAwClBhblNyYz0xOApQYW5EcHQ9MC4wMApBdHRT
    PTEKI2NtPVNjb3BlMQpNb2RlPTAKZnJxPTAuMDAKc2NsPTAuMDAKSW5wPTAKY3MxPTAuMDAKY3MyPTAuMDAKcGM9MApNb2Q9MAojY209RlgKTW9kZT0wClNwZWVkPTUw
    LjAwCk1peEZCPTUwLjAwCkNlbnRlcj01MC4wMApEZXB0aD01MC4wMApEZWxUeXA9MApEZWxNaXg9NTAuMDAKRGVsRkI9NTAuMDAKRGVsU3ByPTEwMC4wMApEZWxEbXA9
    NTAuMDAKQmFzcz0wLjAwClRyZWJsZT0wLjAwCkZYb249MQoKCi8vIFNlY3Rpb24gZm9yIHVnbHkgY29tcHJlc3NlZCBiaW5hcnkgRGF0YQovLyBET04nVCBUT1VDSCBU
    SElTCgokJCQkNDU4MAo/Z2RnY2VuZWI6Y2FhYWFhYWE6YWZhYWliYWE6YWFhYWlhZHA6b2FpaWRvY2Y6ZWVvZHBwbHA6ZWFhYWFhYWE6CmtobW5lZGNmOmFhYWJhYWFh
    OnBpb2NwcGxwOmFhOmVjOmxwOmRwOmxvOmViOmRvOmVhOmNhOmdqOmRhOmNmOmQKYzplbTpnbTpoYTppYTppaTphaTpjbjpjbzpkYjpoZTpiYTpkbjpnZiFxeUE3Tmdw
    Z2RnYk9BNmJia2RlbExBMgo3eHN1em9sZWxlZkx2ZmFOZmVjaHZzQTExeHN1Y2lvZHBwQ2JlU21uamF2ZmFOZmVjaGVpb2RwcENtYW1wZWVMClVBMTBmbW9kcHBDc3Bo
    UkdMZ2lvZHBwQ3BtaGhvaGpkdm9tUkdMYWtBMTFiZWFmQVNBMmppb2RwcENBN2NlQTIKc0EzdWtpb2RwcENmaWpkZWZMc2NlQTEwamlvZHBwQ1NBNlVBMnF3QTdKZ29K
    V0pnYk9KaGtaVWdpTVBBTEEyNwp4c3V6b2xlbGVmTHF3QTcxcXdBN2RobGFlbGVvVWphbmNJbGJtaGJwb2hhYmNobWNCbW8xZmpmY1JCZmJla2drCmpwaWxoZG5nWGFj
    ZWVsYmZvZ2NhZmpuY2ttb3BrYmxvZ2NqYWZkZmdwaGJob2FtZmlvcGFiZmJlb25pTmluaGcKZGdqZk5vaWZrYWVxYWVBMTRxeUE3ZmZoY2hkSWVpWmdkZ2xnbmdiZ28x
    QTI0M3FRQTEzOHF3QTdVMkEzMnRBMgpIQTFIMUExUUhBMWthSEExbWFIQTFvYUhxQWFjQTV0QTN0QTJIQTFIMUExUUhBMWthSEExbWFIQTFvYXdGQTFYCkZBMUlGQTFL
    RkExSEZBMWZhRkExZ2FGQTFQRkExUUZBMVJGQTFqYUZBMWppRkExa2FGQTFraUZBMWxhRkExbGkKRkExbWFGQTFtaUZBMW5hRkExbmlGQTFvYUZBMW9pRkExcGFGQTFw
    aUZBMkJBMWFlQkExU0JBMWFtQkExWEJBMQpiZUJBMWJpQkExYm1CQTFJQkExY2VCQTFjaUJBMWNtQkExS0JBMWRlQkExZGlCQTFkbUJBMUhCQTFlZUJBMWVpCkJBMU5C
    QTFmYUJBMWZlQkExZmlCQTFmbUJBMWdhQkExZ2VCQTFnaUJBMU9CQTFQQkExV0JBMWhpQkExaG1CQTEKUUJBMWljQkExaWVCQTFpZ0JBMVJCQTFpa0JBMWltQkExaW9C
    QTFqYUJBMWpjQkExamVCQTFqZ0JBMWppQkExagprQkExam1CQTFqb0JBMWthQkExa2NCQTFrZUJBMWtnQkExa2lCQTFra0JBMWttQkExa29CQTFsYUJBMWxjQkExCmxl
    QkExbGdCQTFsaUJBMWxrQkExbG1CQTFFQkExbWFCQTFtY0JBMW1lQkExbWdCQTFtaUJBMW1rQkExbW1CQTEKbW9CQTFuYUJBMW5jQkExbmVCQTFuZ0JBMW5pQkExbmtC
    QTFubUJBMW5vQkExb2FCQTFvY0JBMW9lQkExb2dCQQoxb2lCQTFva0JBMW9tQkExb29CQTFwYUJBMXBjQkExcGVCQTFwZ0JBMXBpQkExcGtCQTFwbUJBMXBvQnFyQTdG
    CmVlZmRmY0lWQTlhYksyUVNBMUljZ2NjYmdBM3FyQTdGZWVmZGZjSU1BYmdrYWNlY2NiZ0syVEszVEszVGhuSzQKcUFhY0E1dFhvY2JuRGJvamVqYUVtZWlqWENibGhn
    ZGtZb3Bra2poRWxlUmtibGxiaVZjZUNtb2FuTENRVGhqRwpramlqa2NsbnBoa2ZhYkRkbWdwSUdqYm9sbmlHaG1sZnBmRU1jamhwRVNqYmZsREljbWVmRGZobWpwbkVs
    bGtnCmZvQ2VlZmJibUNwa0hTRENjZ2RqRGlkbmdhZkNtZWhrSUNIY2lsaWxuZ2lURENtZ2VwaW9FZmZhZWZiRG9pbGMKaHBEZmhkaWlsRWpsZ2dtZUVQbWxhZUdsaWds
    YmJDbWdmZ21kRWthaGZkZURhcG1uYmlEbWdubG9lRXBuZnBiaApDbmVqZW9ibG5vZ2trZW9DbmFhcGJwQ25vZmtubkdrbWZoampHZGpsZUhDUW5oZ2xDZGlJZ2RFZmNk
    amNwQ21rCmdoaXBFTnBqRDFvYmFjYmtEbGdwZm9vRW9hbG1jZ0NsbWpiZ2lFamtiZllDVE5sZEVva29qY2pEa2pwbXBjR24KbWZwZ2NDcGVuYWRmRGFrbWxoaENobWZv
    YmhETWtlaGNEa2hpcFhFWUxrakVrZUdsY0dpYkpubVlqbGJuR0RtZQpuaWpsbG5oaWxmZmhkbW5kZWtmakN0YmpTbmpFcGNoa01DYmxLbWNsbmhubmlKQ2ZvZGhmbENu
    ZG5jaWxZb21qCmFsaVlrZGtiaGtEcGJtcG5tR2VsSEJEbGNpaG5ubG5pcGVmampsbmZsam5maERiaG5tZmdEZWhrZUNFYWJpY2gKZ0NpamNkbWpFb2Nla2VsREExUUNq
    alZjZEdicGVlYmtFUmxoS0RqbWpjbGFZY2duamNiRGdvZmNpZUVnYmduQQpsbm5hZ3BmaURqamhnZWxEamtsY29jRWhrcGhlcENNbGJhb0NvcGFlYmhEa2ZkbGVwRG9u
    Y2VNRWlvbW1ob0VnCm9iY2FsRGZjWGJqR2ltSG1sR2llcGdhbUNnbldjYkNna25kVkdna2pvZW5FbWxUYmJEbGZnaGNqR2pubWltZ0cKb2RnZWJqQ3BhYmJkZUNoa2Fj
    bGVHbmZrZ2ZpR2xqaG1kZ0RtZWRtb2NkbUNwbW9wR2NoYm5hbENqaWtvY2hDbQpha2xvcFluaWVoamVFcGlmbUhHcUFTQTlVMkEyMDQ0cXJBN05lZ2VwSVZBUDFPWlVQ
    aGNncGdsSldVUGhkSmhsCksyZGRUSzFWMVRxckE3TmVnZXBJTUEyNnFyQTdmZ2VkZXBJVkEyWmdkMWdiYWJBMldVUGhkSmhsSzFhZEExbWEKb2hhamlqbWZxckE3ZWdK
    T1daaGNJVkExNWRkb3BSbWZrZGVqUm1mcXJBN2VnSk9XWmhjSU1BZ2VnbmdkYWJBOApoY0FvYXBhaWdrYWZhbmFjZGJncXJBN2VuaGZPV0pQT1pJVkFtYWdkbmhSbWZj
    ZEFjZGJnZmRhaEExYWNBMVFBCmVuY2RiZ3FyQTdlbmhmT1dKUE9aSU1BNlhtZmFjZ2VBMTA9MjE1NjYyCgAA
    AGluaXRpYWxpemUAEAAAAA==
  >

#2

JUCE has the Base64 class to convert binary data into a Base64 encoded string, but that of course doesn’t help you with the Reaper specific portions that likely must be present in the data. If I recall right, those Reaper portions should contain at least the plugin channel routing, bypass and wet/dry mix values. They may also contain the floating point static (non-automated) parameter values for the plugin.

You will likely not be able to solve this without direct help from the Cockos developers…


#3

In experimenting with decoding reaper chunks in ocaml, I’ve noticed that the top line seems to contain the fx id input count routings etc. Parameter envelopes seem to be separated into text based <PARAMENV and <PT tags.

I posted in the Reaper dev forum a few weeks ago, but haven’t had much success in finding help: https://forum.cockos.com/showthread.php?t=195251

I saw the JUCE Base64 converter but my C++ chops wouldn’t let me get past the void* aspect of the chunk. If you could post a few lines demonstrating the conversion I would really appreciate it. My hope it to get the chunk into a similar format so I can hack it in ocaml.


#4

MemoryBlock chunk;
// fill chunk here…
String b64string = Base64::toBase64(chunk.getData(), chunk.getSize());

(So it’s pretty much the same what you already did with the Sqlite code…)

Note that string returned by Juce might not be directly compatible with Reaper’s rpp text format. (If I recall right, Reaper for example expects very long texts in the .rpp to be split into smaller lines.)


#5

Ahh, thank you for that. I’ll try it when I get home.

I encountered the long string limitation as well… Seeing how ad-hok vst chunks are in reality has been quite the surprise.