aboutsummaryrefslogtreecommitdiff
path: root/site/udo/legacy/sequencing_melodic_persistence.udo
blob: dd309af56854a28fe687be1722a582ee0a3a1211 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#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