Announcing ajm objects

Adam Murray's icon

ajm objects 0.7 beta. Sequencing, scripting, and more for Max/MSP.

[ajm.ruby]
Ruby interpreter for Max. Ruby (http://www.ruby-lang.org) is an easy, yet powerful object oriented scripting language. This is an MXJ external that gives Ruby access to Max's Java API (so you can do things like script your Max patches), as well as access much of the standard Java and Ruby APIs.

[ajm.seq]
Manipulation and traversal of sequences containing numbers, messages, and lists. Includes MIDI note name parsing, support for chords, and more.

[ajm.rseq]
Rhytmic version of ajm.seq. Use together with ajm.seq for modular sequencing.

[ajm.SQ16]
16 track "alternative" sequencing app with independent control of pitch, rhythm, and velocity (built with my other objects).

Plus a growing list of miscellaneous other stuff, including:
[ajm.psui] - A simple pattrstorage GUI that let's you queue up preset recalls.
[ajm.env] - An MSP envelope generator with independent breakpoint functions for attack and release that comes with its own GUI object

Comes with an extensive set of help files so you can hopefully understand what the heck I am talking about.

All patches and code are open source and free for you to use and modify under the very permissive FreeBSD license. If you happen to make improvements please submit changes back to me so we can make the objects better for everyone.

Future Plans:
* Tighter integration with Ruby and ajm.seq/rseq to sequence with algorithms: cellular automata, petri nets, whatever you can code...
* Evolve ajm.SQ16. I'm thinking about having a hierarchy of them (with a configurable number of tracks) whose patterns can change independently and be sequenced by a master sequencer. The UI and pattr system should get an overhaul after Max 5.

About sample accuracy (I know some MSP wizard will call me on this).
My sequencing objects are event (bang) based and therefore not sample accurate. I don't see that as a problem, here's why: These objects are intended for working at the Macro and Meso time level (where *sample* accuracy often doesn't matter) and for automating things that would be event based anyway (Human/MIDI input). At the Micro time level, use MSP patches as usual to ensure sample accuracy where desired. Think of my objects for controlling an MSP "black box" from the outside. Things like sequencing commands to a sample-accurate step sequencer to create varying rhythmic patterns.

Anyway, I find these objects very fun and useful, maybe you will too!

zipb's icon

Op 13-feb-2008, om 4:32 heeft Adam Murray het volgende geschreven:

> [ajm.ruby]
> Ruby interpreter for Max. Ruby (http://www.ruby-lang.org) is an
> easy, yet powerful object oriented scripting language. This is an
> MXJ external that gives Ruby access to Max's Java API (so you can
> do things like script your Max patches), as well as access much of
> the standard Java and Ruby APIs.

Interesting. I use Ruby a lot in addition to Max, using the Max shell
object to invoke the Ruby programs. Will definitely look into this. I
much prefer Ruby to MXJ/all flavors of Java.

Best,

Zip

Adam Murray's icon

Quote: Zip Boterbloem wrote on Wed, 13 February 2008 07:05
----------------------------------------------------
>
> Interesting. I use Ruby a lot in addition to Max, using the Max shell
> object to invoke the Ruby programs. Will definitely look into this. I
> much prefer Ruby to MXJ/all flavors of Java.
>

Then you will probably like my object. Compared to invoking Ruby from the shell, my object has much tighter integration with Max. Ruby's numerical types will convert to Max ints or floats when possible (Ruby can handle much larger numbers - those will turn into messages). One dimensional arrays will turn into lists. You can define your own implementation of bang(). And you can configure the object for as many outlets as you want, and inside your Ruby script call outlet() to control the output of the script in any way you see fit. I hope to make the integration even tighter in the future.

Hopefully it won't be a turn off that this is Ruby embedded in Java. Doing it this way had some definite benefits:
- I can easily release this cross platform
- You can script Java APIs and the Java-based Max APIs from Ruby.
- If you have some Java know-how, you can use my open source code (included with ajm objects) to directly embed a Ruby interpreter in any MXJ external. I have some articles on setting up a development environment for this on my website.

The downsides are:
- It runs on JRuby which is not quite the same as Ruby. There are some limitations (http://jruby.codehaus.org/Limitations)
- It's slower than standard Ruby. I wouldn't use it for running massive Ruby-based applications inside Max, or for DSP (that's what lua~, chuck~, etc are for). So far it seems slow to initialize but is snappy after that.

Those downsides could be addressed by someone doing a C version of this object but it would lose the benefits. I have no plans to try that.

Let me know how it works out.

Adam Murray's icon

Update on windows compatibility:
The ajm.SQ16 sequencing application was designed and built on a Mac. I had some more time to test it on Windows and I'm not thrilled with the results. It functions ok on a newer Vista machine, but it has some annoying screen refresh issues (Max 5, I'm counting on you to magically fix all my cross platform GUI problems!). On an older XP machine the timing was horrible, rendering the app useless.

Part of the problem is it's all metro/event-based, and interacting with the GUI can throw off the metro timing. On my Mac and Vista, I just turn on Overdrive and all is well. I'll try throwing in an MSP-based metro~ soon and see if that helps on the older XP machine, but perhaps this app is simply too inefficient.

The other objects seem fine.

bitbutter's icon

Thanks very much for this. I've poked around the ajm.ruby examples.
I'm used to working with ruby on rails for web projects, but my knowledge of the wider world of ruby is still quite limited.

I'd like to refactor a complicated max patch into a cleaner MVC-like structure. Do you think ajm.ruby is suitable for this?

Please excuse this beginner question: Is it possible to somehow have separate ajm.ruby instances communicate with one another without relying on max messages between them? (eg a 'controller' object that talks to a separate controller object elsewhere) or should I be picturing one big ajm.ruby object (with many outputs?)

Thanks in advance for any guidance you might be able to give.

Adam Murray's icon

Quote: bitbutter wrote on Sun, 11 May 2008 03:58
----------------------------------------------------
>
> I'd like to refactor a complicated max patch into a cleaner MVC-like structure. Do you think ajm.ruby is suitable for this?

I normally use ajm.ruby to replace fairly small parts of my patch when the logic gets too complicated and I can more easily express them in Ruby. Regarding MVC, I tend to use ajm.ruby for pieces of the controller logic or generating the model.

I'm not using Ruby for the MVC structure itself. For MVC-like structures inside a Max patch, I'm using Max's pattr objects (pattr, pattrforward, pattrstorage, etc). It works well for my purposes.

That isn't to say you couldn't do all the MVC in Ruby. Whether or not it is suitable depends on where you choose to draw the line between Max patching and Ruby code.

> Is it possible to somehow have separate ajm.ruby instances communicate with one another without relying on max messages between them? (eg a 'controller' object that talks to a separate controller object elsewhere) or should I be picturing one big ajm.ruby object (with many outputs?)

I am planning on releasing a new version soon, hopefully this week (watch this thread for a link). One of the new features is a shared evaluation context, so you can send a script to one object and share all the variables, classes, etc between multiple ajm.ruby objects. This feature may help you, but it's just a data sharing mechanism and doesn't provide a convenient way to communicate between the objects. You could use the standard Max send/receive objects to send messages between ajm.ruby objects, or perhaps they could talk directly using networking APIs.

There's a lot of unexplored territory here, so please share any successes or failures. Feel free to email me directly if you don't want to spam the forum.