clone45
(Bret Truchan)
January 4, 2020, 9:05pm
1
Hello! I’m working on a module that records mouse movements. So far, it looks like this:
Recording starts when the user clicks in the square area and continues as the user drags around the mouse. Recording stops on mouse-up.
Everything is working great so far except for saving and loading of the recordings. I’m planning on saving those as x,y pairs, and my code for writing to the json file looks like this:
json_t *dataToJson() override
{
json_t *root = json_object();
json_t *recording_memory_json_array = json_array();
for(Vec position : recording_memory)
{
json_t *xy_vec = json_array();
json_array_append_new(xy_vec, json_real(position.x));
json_array_append_new(xy_vec, json_real(position.y));
json_array_append_new(recording_memory_json_array, xy_vec);
}
json_object_set(root, "recording_memory_data", recording_memory_json_array);
json_decref(recording_memory_json_array);
Question: Where is this json saved? I’d like to take a peek at the saved file to see if the json that I’m outputting looks correct.
Quick note: I also intend to only save data after recording has been completed. I intend to use a simple flag for that.
dhemery
(Dale Emery)
January 4, 2020, 9:13pm
2
It’s stored inside the patch—inside your whatever-patch-name.vcv file.
1 Like
You can take a look at my ARENA module which has pretty much mouse interaction stuff going on. Including mouse movement recording and visualization.
# stoermelder ARENA
ARENA is a two-dimensional mixer with 8 inputs with 8 assigned outputs, 4 mixed outputs with 16 motion sequences each and various modulation options. In the center of the module is a big colorful screen that visualizes the positions of the inputs and outputs in two-dimensional space and their modulated parameters.
![ARENA Intro](./Arena-intro.gif)
The module produces no signal on its own.
### IN-ports and OUT-ports
The module has 8 input-ports with assigned controls for "Amount" and "Radius" and are routed their output-ports respectively. The signal sent to the OUT-port is calculated in this way: The amount is used to scale the input linearly between 0-100%. The radius defines the range of influence of the input-signal according to the euclidian distance between each of the MIX-objects in 2d-space considering the x/y coordinates of the objects. These weighted distances are summed in repect of one of the following OUT-modes:
- Scale: Each MIX-port brings in at most $\frac{1}{n}$ * 100% of the input-signal if $n$ MIX-ports are active, so the output can reach 100% at most.
- Limit: Each MIX-port brings in at most 100% of the input-signal and the output is limited at 100% of the input.
- Clip -5..5V / 0..10V: Each MIX-port brings in at most 100% of the input-signal, the sum can be >100% but the output is hard limited on -5..5V or 0..10V.
- Fold -5..5V / 0..10V: Each MIX-port brings in at most 100% of the input-signal, the sum can be >100% but the output is wave-folded on -5..5V or 0..10V.
Each channel has several settings that can be changed by the context-menu of the small text-display or directly on the white circle in the center-screen.
![ARENA radius](./Arena-radius.gif)
This file has been truncated. show original
2 Likes
clone45
(Bret Truchan)
January 4, 2020, 9:56pm
4
Thanks Dale and Ben,
It looks like I’m on the right path:
{
"id": 141,
"plugin": "voxglitch",
"version": "1.0.0",
"model": "xy",
"params": [],
"rightModuleId": 142,
"data": {
"recording_memory_data": [
[
21.8129921,
209.287399
],
[
21.8129921,
209.287399
],
[
21.8129921,
209.287399
],
[
21.8129921,
209.287399
],
...
That output is exactly what I was looking for! I’m going to work on loading next. Ben, thanks for posting your code. I’ll refer to it if I get stuck.
Vortico
(VCV - Andrew)
January 5, 2020, 9:37am
5
You don’t get to choose when dataTo/FromJson()
is called. It is called when Rack needs to serialize the patch or module preset.
You can of course serialize empty array or a nonexistent "recording_memory_data"
property if for some reason you want to load an empty state when unserializing from the serialized data.
clone45
(Bret Truchan)
January 5, 2020, 9:15pm
6
Thanks Andrew. I ended up allowing Rack to save my data as it feel fit. In other words, I didn’t end up adding any flag. I just put the code in dataToJson()
and let VCV handle it.
Here’s my code for saving and loading the vector of x,y vectors. recording_memory
is defined in the module class as vector<Vec> recording_memory;
json_t *dataToJson() override
{
json_t *root = json_object();
json_t *recording_memory_json_array = json_array();
for(Vec position : recording_memory)
{
json_t *xy_vec = json_array();
json_array_append_new(xy_vec, json_real(position.x));
json_array_append_new(xy_vec, json_real(position.y));
json_array_append_new(recording_memory_json_array, xy_vec);
}
json_object_set(root, "recording_memory_data", recording_memory_json_array);
json_decref(recording_memory_json_array);
return root;
}
void dataFromJson(json_t *root) override
{
json_t *recording_memory_data = json_object_get(root, "recording_memory_data");
if(recording_memory_data)
{
recording_memory.clear();
size_t i;
json_t *json_array_pair_xy;
json_array_foreach(recording_memory_data, i, json_array_pair_xy)
{
float x = json_real_value(json_array_get(json_array_pair_xy, 0));
float y = json_real_value(json_array_get(json_array_pair_xy, 1));
recording_memory.push_back(Vec(x,y));
}
}
}