aboutsummaryrefslogtreecommitdiff
path: root/site/udo/sequencing_melodic_persistence.web.udo
diff options
context:
space:
mode:
Diffstat (limited to 'site/udo/sequencing_melodic_persistence.web.udo')
-rwxr-xr-xsite/udo/sequencing_melodic_persistence.web.udo213
1 files changed, 213 insertions, 0 deletions
diff --git a/site/udo/sequencing_melodic_persistence.web.udo b/site/udo/sequencing_melodic_persistence.web.udo
new file mode 100755
index 0000000..01d005f
--- /dev/null
+++ b/site/udo/sequencing_melodic_persistence.web.udo
@@ -0,0 +1,213 @@
+#ifndef UDO_MELSEQUENCINGPERSIST
+#define UDO_MELSEQUENCINGPERSIST ##
+/*
+ Melodic sequencer persistence: saving/loading from files and database
+ Web version
+
+ This file is part of the SONICS UDO collection by Richard Knight 2021, 2022, 2024
+ License: GPL-2.0-or-later
+ http://1bpm.net
+*/
+
+#include "/sequencing_melodic.udo"
+#include "/array_tools.udo"
+#include "/table_tools.udo"
+#include "/interop.udo"
+#include "/json.udo"
+
+
+/*
+ Get the current state as a JSON object
+
+ iJson mel_getstate_json
+
+ iJson the JSON object containing current sequencing and progression data
+
+*/
+opcode mel_getstate_json, S, 0
+ Sjson = "{"
+ index = 0
+ while (index < lenarray(gimel_fns)) do
+ Sjson = strcat(Sjson, sprintf("\"%s\":%s,", gSmel_names[index], tab_serialise(gimel_fns[index])))
+ index += 1
+ od
+
+ Sjson = strcat(Sjson, sprintf("\"state\":%s,", tab_serialise(gimel_state)))
+ Sjson = strcat(Sjson, sprintf("\"details\":\"%s\",\"mel_number\":%d,\"seq_tempo\":%f,\"seq_swing\":%f}", gSmel_details, gimel_number, i(gkseq_tempo), i(gkseq_swing)))
+ xout Sjson
+endop
+
+
+/*
+ Set the current sequencing and progression state
+
+ mel_setstate_json SJson
+
+ SJson JSON string containing state data
+
+*/
+opcode mel_setstate_json, 0, S
+ Sjson xin
+
+ i_, gSmel_details, i_ json_parse Sjson, "details"
+ i_, S_, gimel_number json_parse Sjson, "mel_number"
+ i_, S_, itempo json_parse Sjson, "seq_tempo"
+ i_, S_, iswing json_parse Sjson, "seq_swing"
+
+#ifdef MEL_INITTIME
+ gkseq_tempo init itempo
+ gkseq_swing init iswing
+#end
+
+ ; if data to be loaded has more progression items than ftables, free and generate again
+ if (gimel_number > ftlen(gimel_fns[0])) then
+ index = 0
+ while (index < lenarray(gimel_fns)) do
+ ftfree gimel_fns[index], 0
+ gimel_fns[index] = ftgen(0, 0, -gimel_number, -7, 0)
+ od
+ endif
+
+
+ index = 0
+ while (index < lenarray(gimel_fns)) do
+ i_, Stringvalue, i_ json_parse Sjson, gSmel_names[index]
+ iarray[] json_getnumericarray Stringvalue
+ copya2ftab iarray, gimel_fns[index]
+ index += 1
+ od
+
+
+ i_, Stringvalue, i_ json_parse Sjson, "state"
+ iarray[] json_getnumericarray Stringvalue
+ copya2ftab iarray, gimel_state
+endop
+
+
+
+
+instr mel_savestate_fs
+ prints sprintf("%s unsupported in web UDO\n", nstrstr(p1))
+ turnoff
+endin
+
+instr mel_loadstate_fs
+ prints sprintf("%s unsupported in web UDO\n", nstrstr(p1))
+ turnoff
+endin
+
+
+/*
+ Save the sequencing and progression state to database
+
+ p4 reference name in database
+ p5 optional callback ID for host interop; sent on completion
+*/
+instr mel_savestate_db
+ Sname = p4
+ icbid = p5
+
+ turnoff
+endin
+
+
+
+
+
+/*
+ Load the sequencing and progression state from database
+
+ p4 reference name in database
+ p5 optional callback ID for host interop; sent on completion
+*/
+instr mel_loadstate_db
+ Sname = p4
+ icbid = p5
+
+ schedule("mel_futures_refresh", 0, 1)
+ turnoff
+endin
+
+
+
+/*
+ Load the sequencing and progression state from a string channel
+
+ p4 channel name containing string representation of JSON
+ p5 optional callback ID for host interop; sent on completion
+*/
+instr mel_loadstate_channel
+ Schannel = p4
+ icbid = p5
+ Sdata chnget Schannel
+ mel_setstate_json(Sdata)
+ if (icbid != 0) then
+ schedule("io_callback", 0, 1, icbid)
+ endif
+ schedule("mel_futures_refresh", 0, 1)
+ turnoff
+endin
+
+
+/*
+ Just get state: interop host handles persistence
+ p4 callback ID to send data with/to
+*/
+instr mel_getstate_string
+ icbid = p4
+ Sjson = mel_getstate_json()
+ Sjson json_appendvalue Sjson, "cbid", icbid
+ io_sendstring("callback", Sjson)
+ turnoff
+endin
+
+
+/*
+ Get an array of the known mel states from database
+ Sdata[] mel_liststates_db
+
+ Sdata[] the state names
+
+opcode mel_liststates_db, S[], 0
+ Sresult[][] dbarray gidb, "SELECT name FROM savejson WHERE unit = 'melsys'"
+ ilen = lenarray(Sresult)
+ Sdata[] init ilen
+ index = 0
+ while (index < ilen) do
+ Sdata[index] = Sresult[index][0]
+ index += 1
+ od
+ xout Sdata
+endop
+*/
+
+/*
+ Get a list of mel states from database and return to host with the specified callback ID
+
+ p4 callback ID
+*/
+instr mel_liststates_db
+ icbid = p4
+ turnoff
+endin
+
+
+; if MEL_INITPATH or MEL_INITDB is set, load the specified progression data accordingly
+#ifdef MEL_HASINIT
+instr _mel_persistence_init
+#ifdef MEL_INITPATH
+ subinstrinit "mel_loadstate_fs", "$MEL_INITPATH"
+#end
+#ifdef MEL_INITDB
+ ;mel_loadstate_db "$MEL_INITDB"
+ subinstrinit "mel_loadstate_db", "$MEL_INITDB"
+#end
+ alwayson "_mel_manager"
+ turnoff
+endin
+schedule "_mel_persistence_init", 0, 60
+
+; end MEL_HASINIT
+#end
+
+#end