#ifndef UDO_MELSEQUENCINGPERSIST_LEGACY #define UDO_MELSEQUENCINGPERSIST_LEGACY ## /* Melodic sequencer persistence: saving/loading from files and database Legacy: superceded by JSON This file is part of the SONICS UDO collection by Richard Knight 2021, 2022 License: GPL-2.0-or-later http://1bpm.net */ #include "pgdb.udo" #include "sequencing_melodic.udo" #include "array_tools.udo" #include "interop.udo" /* Save state to file p4 path to save to */ instr mel_savestate_fs Spath = p4 ftsave Spath, 1,\ gimel_chords, gimel_notes, gimel_lengths, gimel_action1,\ gimel_action2, gimel_actionthreshold,\ gimel_active, gimel_importance,\ gimel_mod1, gimel_mod2,\ gimel_mod3, gimel_mod4,\ gimel_state turnoff endin /* Load state from file p4 path to load from */ instr mel_loadstate_fs Spath = p4 isize = -1 iline = 0 /* ; COMMENTED AS readfi IS NOT AVAILABLE ON LIVE COMP?!?!?! - testing if size matches etc ; get size from first table while (isize == -1 && iline != -1) do Sline, iline readfi Spath if (strcmp(strsub(Sline, 0, 4), "flen") == 0) then isize = strtod(strsub(Sline, 6, strlen(Sline)-1)) isizefound = 1 endif od ; size not found in file if (isize == -1) then isize = ftlen(gimel_chords) ; resize required elseif (isize != ftlen(gimel_chords)) then gimel_number = isize _mel_refreshactions() ; update actions list to cater for number of patterns index = 0 while (index < lenarray(gimel_fns)) do ifn = gimel_fns[index] ftfree ifn, 0 itemp ftgen 0, 0, -isize, -7, 0 index += 1 od endif */ ftload Spath, 1,\ gimel_chords, gimel_notes, gimel_lengths, gimel_action1,\ gimel_action2, gimel_actionthreshold,\ gimel_active, gimel_importance,\ gimel_mod1, gimel_mod2,\ gimel_mod3, gimel_mod4,\ gimel_state gkmel_futures_refresh_trig = 1 turnoff endin /* Save state to database mel_savestate_db Sname Sname identifier to be used */ opcode mel_savestate_db, 0, S Sname xin pgdb_table_save Sname, "melseq", gimel_state index = 0 while (index < lenarray(gimel_fns)) do pgdb_table_save strcat(Sname, strcat("||", gSmel_names[index])), "melseq", gimel_fns[index] index += 1 od endop ; broken: underlying pgdb_table_savek not working opcode mel_savestate_dbk, k, S Sname xin ilength = lenarray(gimel_fns) ktrigger init 0 kcomplete init 0 kindex init -1 if (kindex == -1) then kdone pgdb_table_savek Sname, "melseq", gimel_state, -1 else kdone pgdb_table_savek strcatk(Sname, strcatk("||", gSmel_names[kindex])), "melseq", gimel_fns[kindex], ktrigger ktrigger = 0 endif if (kdone == 1) then if (kindex + 1 < ilength) then kindex += 1 ktrigger = 1 else kcomplete = 1 endif endif xout kcomplete endop ; ftresize ????? /* Load state from database mel_loadstate_db Sname Sname identifier to be used */ opcode mel_loadstate_db, 0, S Sname xin inull pgdb_table_get Sname, "melseq", gimel_state index = 0 while (index < lenarray(gimel_fns)) do StestName = sprintf("%s||%s", Sname, gSmel_names[index]) inull pgdb_table_get StestName, "melseq", gimel_fns[index] index += 1 od gkmel_futures_refresh_trig = 1 endop /* 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 distinct (string_to_array(name, '||'))[1] FROM savearray WHERE unit = 'melseq'" ilen = lenarray(Sresult) Sdata[] init ilen index = 0 while (index < ilen) do Sdata[index] = Sresult[index][0] index += 1 od xout Sdata endop ; broken instr mel_savestate_dbk Sname = p4 kdone mel_savestate_dbk Sname if (kdone == 1) then io_sendstring("mel_state_saved", Sname) turnoff endif endin instr mel_savestate_db Sname = p4 mel_savestate_db Sname event_i "i", "mel_hostsendstates_db", 0, 1 ; resend list of items if (timeinstk() >= 3) then outvalue "mel_state_saved", Sname turnoff endif ;io_sendstring("mel_state_saved", Sname) ;turnoff endin instr mel_loadstate_db Sname = p4 mel_loadstate_db Sname event_i "i", "mel_updatehost", 0, 1 if (timeinstk() >= 3) then outvalue "mel_state_loaded", Sname turnoff endif ;io_sendstring("mel_state_loaded", Sname) ;turnoff endin instr mel_hostsendstates_db Sjson = sprintf("{\"states\": %s}", arr_serialise(mel_liststates_db())) ;io_sendstring("mel_dbstates", Sjson) ;turnoff if (timeinstk() >= 3) then outvalue "mel_dbstates", Sjson turnoff endif 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