Complex preset/automation data structure with mxj. Alternatives to preset/pattr?
Dec 16, 2010 at 5:59pm
Complex preset/automation data structure with mxj. Alternatives to preset/pattr?
…and i'm dreaming of some complex presets/automation data structure coming with it :
In the past, I was using a lot [preset] and [pattr] objects, but for the following reasons i think i will not use them in my new projet, or please tell me if you see an easy workaround or special hidden external object somewhere, to help on one of theses points :
1 – I would like real time automation of all my UI objects in my max patch. (and also automation of the preset changes) I would need functions like record/stop/play but also the ability to ask for the “state of my max patch” at one exact time at xxx millisec. in the recording. I guess there is no simple way to do that using pattr.
2 – I'd like a “2D” presets array instead of “1D”. I mean that i would like a list of presets, and in each preset storage i could have various presets versions.
3 – When we add a new UI object/parameter in a patch where we already have a lot of presets, if we want this new UI object to be initialized with a 'standard' value in each previous preset, we need to recall/resave each preset, which can be a heavy process even if automated.
4 – In my patches, most UI objects in max send its state to an mxj routine, which have to recalculate some process when i modified an object state with my mouse. Then when i recall some preset, there are as many recalculations repeated in my mxj routine as UI objects in my patch… which can bring serious buggy delays each time i click on a preset. I would need to know, from inside java, which way the object state have been modified, with the mouse, or by a preset change?
5 – I'm also wondering about building a special UI object to replace the preset object (in a lcd, because no UI mxj until now in max), in order to have multicolor presets (it often hard to recover my dozens of presets in the actual object) and also to integrate this “2D” presets structure.
Plus knowing that for my sound presets i might want also to interpolate on the flight between 3 or more presets (for example when the frequency of my note is changing), from inside my mxj routine, i think i definitely need a custom preset structure all made inside java.
But again, if somebody have some ideas about resolving one of theses points above, using some existing objects, or maybe, you never know, patches/mxj work already made by someone sharing it, please tell me about it,
Thank you !
* with all the mxj objects statically connected together using a great Hans trick : http://cycling74.com/forums/topic.php?id=26312
** Deep pressure sensing on two points on a screen, see picture. (cintiqs only work with one pen)
Dec 16, 2010 at 7:09pm
Dec 16, 2010 at 8:37pm
Hi Brendan, no I don’t. I built it already one year ago, but my project was going really slow so i didn’t really used it yet! Feel free to ask anything about it.
Dec 16, 2010 at 9:10pm
for #1, in particular the ability to recall the exact state of the patch (where object values are in an automation) you can look at my “alternative to [mtr]” posting, which saves values in jit.qt.movie and uses jit.fill/spill to create and play back the values. Also Andrew Benson’s post at the bottom points to the GestureRecord patch which does something similar (and is probably much more robust).
Sounds like an interesting project, let us know how it goes!
Dec 16, 2010 at 9:56pm
Dec 16, 2010 at 11:36pm
Thanks for your interesting links seejayjames, i was looking at them and the thought that is coming to me about both methods in Andrew’s GestureRecord(and yours too), with pattr or with jit.qt.record, is that it’s copying EVERY parameters data at each frame, 30 times per second. If i have dozens of multisliders, numbersboxes, filtergraphs in my big patch, and recording for more than 15 minutes, that a HUGE amount of useless data… …Knowing i’m only changing one object at a time with my mouse (or, ok, two at the same time thanks to my dual-pen DIY-intuos2screen !), and not as often than 30 times per seconds for 15 minutes. I hope the automation system that i’m planning in mxj to be much more light-weighted and manipulable.
Brendan, you’re welcome, tomorrow i’ll post another topic with details about my intuos2screen.
Dec 17, 2010 at 1:36am
Sounds pretty ambitious!
Of course you could go 10 fps or whatever, as you know, but with enough parameters it would still eat up a lot of data. Possibly you could work out some system where only the changes would get recorded, but of course you’d need a second data stream which keeps track of the overall time when each new event happens (maybe just a jit.matrix with float32, and the values scale to the overall time length). For long chunks where nothing changes, this could be well worth the saved data… but maybe not worth the extra programming… :)
Anyway, looking forward to seeing what you come up with!
Dec 17, 2010 at 11:50am
The structure i’m thinking about for my sequence data would be like this (all in an array in java/mxj) :
I’m still questioning myself on several things :
- ‘Current_time_in_millisec’ should be int or long, while ‘data_array_from_the_max_object‘ should be floats values… 1: So what a call ‘an array’ would be in fact an array of objects of type ‘line_of_data()’, with different types of datas inside it. 2: Or maybe just two array, an int one, and a float one. the first solution might be more convenient while the second one might be more efficient** (when retrieving the data to display it as a visual sequence, in the future, for example).
- Tracks. Should i use different tracks for different gestures data from my interfaces and parameter changes in max ? Or should i do one simple track for EVERYTHING ? (parameter changes in max, the thing we are talking about here, and also gestures data from my interfaces)
** I know i’m mad about ‘efficiency’, maybe because i’ve been traumatized with slow softwares running on fast computers, in the past? but maybe also because being mad with efficiency may be the only way to go to make real-time instruments working with gestures 200 times a second that are REALLY working smoothly in any case. So in my case, my rule one about optimization is ‘think about optimization the sooner possible’ maybe in total contradiction to this Donald Knuth principle claiming ‘premature optimization is the root of all evil’. That said, in the present above case, i might still be tempted by the first solution :-)
Feb 5, 2011 at 9:27pm
I finally made my blog: http://musique.alexandrehd.org/
Here are some details about my prototype as requested :
Feb 6, 2011 at 3:27am
I’ve been learning java through programming a single max program for about four years. It’s structured the same way: mxj and max GUI objects and nearly zero max logic. I’m going to humbly suggest you work off my variant of model view controller. When I switched to this way of working, things got less buggy very quickly. If I have a complex patch that has crazy logic to it, I sometimes give the view, it’s own model-view-controller so that you don’t have to store button states in the main model. I have almost 25,000 lines of code written like this and I’m doing very well.
Feb 9, 2011 at 4:14am
“The controller manage the events to update the view or the model and synchronize them. It receives all user event, and triggers actions to take. If an action requires a change in the data, the controller changes the model data, then the model notifies the view* that the data has changed for it to update. Some events do not affect user data, but the view. In this case, the controller ask it for the change. The controller doesn’t performs any processing, and doesn’t alter any data. It analyzes the client’s request and simply call the appropriate model and return the view corresponding to the request.”
Then I have several questions about all this :
First question :
-> To make it clearer in my head, do you have an example of a situation were it is less buggy to use this “controller” separated object, instead of connecting ‘view’/'interface’ objects directly to the heart of the program ? What kind of bug did you get that you don’t have anymore ?
Second question :
In my case I will have many Views and many Models, but then… one “controller” object ? or many ?
So for example, while performing, I would load an object of type Interface_ipad_fs() and another Interface_magic_trackpad(), an object of type Instrument_prototype_1(), an object of type Sound_synthesis_1() and another Sound_synthesis_2(), and then i would have 5 different associated patchers loaded in max, with an mxj object in each one… that’s the beginning…
So if i understand well, in my case, what i call “interfaces” can be just several “views” in the MVC concept, right? After i don’t know if i have to divide instrument and sound classes in “view” and “model”…
-> Do i need one single “controller” object** to manage all the communications between all my objects in my different patchers ? (This would be possible using Hans trick to share context between many mxj objects http://cycling74.com/forums/topic.php?id=26312 ) …Or should I use several “controller” objects ?
*Third question :
-> You write in your diagram: no direct msg from model to view… but in this wikipedia article and on the internet there is… So what is the advantage, clearly ? Do you have an example to show why it would be a “bad programmer” habit in your usage ?
** This “controller” mxj object would be, in fact, inside a sixth max patcher in max, and would keep track of which, and how many, objects/patchers are loaded in my modular system…
Feb 9, 2011 at 1:19pm
This is how *I* have things laid out. As I said I’m self taught and there are many more professional programmers. But this is how I figured out how to work. I’d probably check with someone else to make sure I’m not totally insane. It may seem a bit bureaucratic at first but it stays almost exactly this simple as it scales up.
The reason I think that get and set should be avoided is because the word “get” is a misnomer. it’s far to easy and tempting to say
Also, it’s far to easy to fall into the habit of a.getB().getC()…getD();
Set, in this context is event worse because you could go directly to your model, change something and no event is fired and your view will end up out of sync. To fire an event for ever set message seems a little extreme. Maybe that’s the way other people work.
So this example shows how you can show the same data in various contexts. In extreme cases is if you want to display a big complex model, I would send the view a path, have the view “get” the model and make a seperate copy in the view object. So, for instance, say you want to have a seperate module name editor dialog. You would call some function that creates a nameEditDialog object and feed it a ModuleSoup, then it would copy all the module names into the nameEditDialog.
So, yes, you have the same data in two places but the strength is that if you stick to the concept (MVC) your object will always work even if things get out of sync.
Another strength of this way of working is that it makes it easy to work in one place and not worry about the rest. If you’re working on the interface all you do is send events “into the ether” when the user clicks, and update the interface when they come back.
It also means that you can control and view your data from anywhere in the patch. Just write a subclass the View object and all the other views update.
In your case, you might write a View for audio and a view for GUI.
Let me know what you think. Also, I wouldn’t suggest using this example for your patch… It’s just something generic to get you thinking like I do about this.
Feb 10, 2011 at 3:17am
Hey, many thanks for spending time to make an example like this..
I was examining your code and patch for an hour and a half, and one first thing is that i’m a bit lost with all the “event” and “eventListener” concept, and the way you use it in the code, my level in java didn’t reach that since all the true events first happen in max and that i then just send them to java methods.
Second, through that the way you are adding modules/patchs/views-associated in a max patcher and connect them together is nice and inspiring, i will not use that way of doing for a simple reason:
Therefore, i use abstractions patches only when i really need it… So i will not use abstractions like your “ViewAModule.maxpat” in your example.
Instead, I would have :
>> AudioMatt says: “So, yes, you have the same data in two places but the strength is that if you stick to the concept (MVC) your object will always work even if things get out of sync.”
Not sure why you want to “have the same data in two places” ??
I’m also a bit lost in your get/set discussion.. And about getters&setters, perhaps i’m gonna look even more like a newbie, but not sure if i like this pragmatism yet… (And where i need efficiency, for example in sound synthesis, hundreds of harmonics to compute each millisec, i’m sure i will not use them, but will have direct access to public data instead.)
But again, structuring well my project is VERY important for me at this point. I think i will use many “abstract-classes” to define well each different type of module that can be connected together.
Feb 10, 2011 at 4:02am
Perhaps I should have commented a bit more. First of all, the event stuff, I just copied from the included link. In use, all an event is is an object that gets sent to all the objects that have signed up to listen to it. It’s very similar to a [counter 0 0 16]–>[send clock] and [receive clock] setup. All you have to do to listen for events is implement the Listener interface and write EventSenderObject.addListener(this).
As for views, we can only wish for the day that we could write a modular patch that functioned like mine! The point is that you are manipulating and viewing the status of the data out in a patcher in a very flexible and decentralized way. If your doing your audio processing in MXJ, you’re still going to need parameters in max gui. So the data you might display would be all the parameter values. Setting and updating those parameter values is easy with MVC. It would be easier to write ChorusModuleInterface extends UserInterface than it would be to recode the whole thing. It’s also much easier to write a document from a data object that doesn’t contain information about the UI. It’s easier to send a preset to the controller and have the controller take care of the data and update the UI.
In you’re example it would be easier to subclass a View two different ways, one would be a java object that takes all the parameter information and processes audio, and another would be a MaxObject that interfaces with the UI.
Picture this: you want to make a chorus module. You write a mono chorus in Java. All you do to make it stereo is instantiate two of those objects, both of them listen for update events and you’re done. Further more, maybe you want to display the LFO in your UI. All you have to do is send the LFO info from inside the left Module, and it updates both the right one and a max slider. Why? Because they are all listening for the same event.
So that’s what I got.
Feb 12, 2011 at 10:36pm
> About events
Thanks for your explanations. Well, my feeling is that the situations – like in your chorus example – where i will have more than one module/object that listen to an input info are not going to happen really often… So i’m wondering that i might not use all this ‘event-java-stuff’, but call object’s method directly instead..
(Also this is not clear in my head: If you have many listeners to an event, in which order are they called? and… On same java thread? the one after the other?)
> “It’s also much easier to write a document from a data object that doesn’t contain information about the UI”
Of course, as the best O.O. approach, i think i will create as many objects as possible to structure my code, but this have nothing to do with the MVC concept, or have it ?
Perhaps i will post a diagram of my patches/mxj classes structure when i will get it better in my head, for the moment i’m wondering also about the best way to connect max UI and Java : http://cycling74.com/forums/topic.php?id=31145
You must be logged in to reply to this topic.