Reaktor is slightly better on the encapsulation/abstraction front than Max is (I’ve been playing with Blocks and am starting to look at doing a basic grid block)… and gen~, man, whoa. So powerful, but not any better at abstraction or reuse. The best story for encapsulation or testability in Max still looks like it’s to write an external in C, which is a little dismaying.

1 Like

@jasonw22
If you’re going to look at something, take a look at Cut Glove, as it’s more or less a stripped down and updated TPV (the core looper/fx anyways). I also built most of it last year, so it’s a more mature and consistent programming style. Parts of TPV are terrrrrifying, (jesus, look at wtpa_1.maxpat if you want to have a laugh!). That’s one of the oldest bits of code in there, and it’s like a house of cards, so I’ve kind of worked around it as much as possible, but the solution to that problem was just rebuilding from scratch, which is what Cut Glove is.

I’ve used a bit more js here and there, and want to use more of it, but I think it’s harder to ‘hack’ into. So unless you understand the whole block of js, it’s harder to just pull out the bits you want/need. But it’s obviously much better for loops/logic.

I do try to avoid using sends/receives as much as possible, and never use them for audio (send~/receive~). Style-wise I’ve tried to go with a 2-inlet/2-outlet structure for everything. So audio in/out, and an “control” in/out, which uses prepend and route to make for readable flow. Plus I comment and color code the living shit out of everything.

In a share-y way I really want to get into making Max projects, but with something like TPV, there are sooo many files, and with the project documentation not being great, Ive never sat down and figured out how to make sure all of the files are included in the packaged up version. The Max packages thing is a great step forward for getting people into setting up, updating, and managing externals, but it’s still a bit faffy in general.

And yes, TPV2 is coming along nicely. Been working out some really interesting grid interface stuff, just ironing out some bugs.
I look forward to talking about UI stuff too! Congrats on getting the gig.

2 Likes

@misuba do you think it’d be possible to create a serialosc object for Reaktor, out of curiosity? I’ve played around with Reaktor slightly, and it seems pretty darn interesting, especially with Blocks.

@jasonw22 definitely, but maybe it’s another topic.

1 Like

Amazing readings. Thanks. So helpful.

On the subject of JavaScript and/or gen~ within Max, I suspect the single-threaded nature of JavaScript makes it unusable for audio processing. The folks who are making a large use of JavaScript within Max appear to be primarily concerned with MIDI data.

There are two things attracting me to JavaScript:

  • I know it really well
  • There are robust unit testing frameworks that already exist for it

But I’m concerned that I may want to do some DSP programming at which point does my JavaScript work become useless? But if I go the gen~ route it looks like I’ll be on my own for implementing any unit testing framework?

Starting to wonder if I should just stick to C.

Yeah most of the js I’ve seen has been dealing with list/array/loop stuff.

gen~ is great for dsp as you can then use it inside (and outside) of Max. Though it’s probably best to avoid doing non-dsp things with it, as it calculates every sample, which is quite expensive if not needed.

Tangentially, I really hope that cycling74 do something to bridge the gap between Max/gen~ and “real” code that can be used elsewhere. Especially with things like bela out there.

Interesting-seeming book.
http://www.areditions.com/lyon-designing-audio-objects-for-max-msp-and-pd-das025.html

Designing Audio Objects for Max/MSP and Pd

Max/MSP and Pd are the data flow audio programs electronic musicians prefer for their rapid prototyping capabilities, graphical resemblance to analog synthesizer patching, and a wide variety of available synthesis and processing methods. However, a powerful element of these programs is surprisingly under-utilized: the ability to create (in C) new audio externals to process audio with sample-level precision.

The advantage of writing externals in C is the ability to gain far greater control over the specification of new signal processing algorithms that are otherwise difficult or impossible to achieve with data-flow patching techniques. Additionally, externals coded in C can be considerably more CPU-efficient than the comparable algorithm implemented as a patch.

Learning how to write externals for Max/MSP and Pd in C opens an entirely new world of creative possibilities for electronic musicians. This book guides the reader step-by-step through the process of designing externals, from concept through implementation. Twelve externals are presented, each revealing new sonic, musical, and programming possibilities.

The multi-platform approach of this book supports the compilation of Pd externals on Linux, Mac OS X, and Windows, and the compilation of Max/MSP externals on Mac OS X and Windows. The CD-ROM contains complete code for all projects presented in the book. The Max/MSP externals are designed for use with Max 5; a supplementary chapter on the CD-ROM describes how to update Max 5 code to make use of 64-bit processing with Max 6.

I’m concerned about this. As I begin to talk with @Rodrigo about some UI design for TPV2 (partially inspired by the recent tease of the sexy-looking 2020 app) I need to start getting a lot more aware of what constraints the built-in GUI objects present. I’m not surprised to hear that breaking Max’s built-in GUI abstractions makes for far more brittle apps.

indeed, you can really only do control rate interaction with js in max. and that is fine, given gen~ does dsp.

the “dumber” parts of the monome modules have almost interchangeable syntax when it comes to js to c conversion. hence the code in mp2 in max is nearly identical to that in the module. copy-paste, really. i mean, within specific funtion blocks. ie copy the grid key code, then copy the grid led refresh code.

Although I know JavaScript well, I think I’d rather just stick with C than flip between JS and gen~ depending on whether I’m doing control rate or audio rate. It just seems more coherent to me. Unless there are good reasons not to use C?

For the most part I’ve moved over to using live.objects, which can look pretty smart (and not Max-like), though I think you can do a lot with color, layout, and typography (mlrv was a big inspiration for the look of TPV, especially the Setup window).

I did mess with custom on/off indicators and things like that at one point, but abandoned it. So it’s really just about restructuring the space, and then getting into the things you mentioned in your email, establishing a visual/interaction hierarchy.

1 Like

@jasonw22
I would like to encourage you on this topic.

I started teaching CoreAudio on macOS last semester, and this semester I am teaching AudioUnits. I assume that the techniques are very similar to C externals for Max/MSP and Pd, although I have no experience with the latter.

One huge side-effect of teaching is that I find myself thinking about how to teach the broader concepts of structured programming, procedural programming, and object-oriented programming - possibly more than the audio concepts that somehow seem simpler for someone with studio patching experience. Whether the language is Objective C, C++, or plain old C, I find that I always think in terms of objects and the high-level system design. The way that the pieces fit together, and the sharing of information and configuration, is actually way more powerful than the choice of language (although some languages make this easier or harder than others).

Personally, I find that I think in Objective C. At least that’s how my design is constructed in my thoughts. But implementation in standard C or C++ is sometimes chosen based upon the restrictions of the environment, e.g., AudioUnits must be written in C++; user interface must be written in ObjC; certain other pieces, particularly firmware, must be written in standard C.

If you’re written up anything that you’ve learned since starting this topic, please reply with some links. I believe it’s a good thing to be very conscious of design.

Brian Willoughby

Oh… so much to respond to in this thread… Sorry for what will be one of my longer missives…

First, imagine my surprise to wake up to a thread named after a debate that was still raging when I learned programming 40 years ago. Yes, there was a time when people argued about the value of “structured code”.

Max has always failed the “Princess Bride” principle for me: The code often “doesn’t mean what you think it means”. I think this is because, beyond the basic atoms, the constructs don’t have simple effects, easy to reason about. Inserting a send/receive is an example that you want to be able to note, and erase from your mental model of the patch - but you can’t because it affects message order, which is another difficult, global effect in the system.

There’s a long history of visual programming systems, and for the most part they have failed as general programming solutions. The only real successes one can point to are Max and Scratch, both fairly domain specific. The large hurdles remain abstraction, and data structures - and after decades of development (I remember Dan Ingalls’ and Jaron Lanier’s efforts in the 80s) - there is still no breakthrough. As prior comments attest, these remain the pressing problem in larger Max systems.

Two of the main arguments against “structured code” back in the day were:

  • We can’t afford to waste memory and CPU on standardized looping constructs over hand crafted code.
  • A programmer can better express program flow as they understand the whole problem.

Modern programming has destroyed all that: We have plenty of CPU and memory (for 99.99% of tasks), and no one programmer writes everything any more. As such - coding for clarity, robustness, and reusability generally top all other concerns. As a professional programmer, these concerns are always first. But when we are programming for our personal aims, these need to be first too: Even this kind of programming is no longer a personal endeavor: We open source our code, build on other code frameworks and libraries, and hope people will examine what we do.

Saddly, the call outs from Max are C and Java, and JavaScript. C, by modern standards, is weak in the abstraction department. Java seems now deprecated for Max - and I won’t miss it. JavaScript has the best promise, but well structured code in JS takes almost as much discipline as Max: As a language it was only designed for programming in the small. Compounding all this difficulty is that getting into and out of the language in question is a significant amount of work, which leads away from building the thing at hand.

So where does this leave us? Max does well at audio signal chain, and somewhat well at UI objects that reflect state… but when it comes to control and structure - both of code and of music - I find it totally unworkable. Sorry Max, I can’t bring myself to code anything complex in you.

For myself, my current project is a live-performance oriented percussion sequencer controlled by grid controllers. I am coding it in Haskell: Functional (the current forefront of programming systems), highly concurrent (good for real-time and music), and built to support abstraction in the small and in the large. It will present MIDI in/out ports so I can connect it to other things.

Where I’m looking for better integration with Ableton Live, I will do it via remote scripts: Python is moderately better at larger code, and the Live API is much easier to use from Python than via Max (or even JS via Max). I’ll have to plumb some connection between the Python and the Haskell (probably an OS pipe or perhaps a TCP socket)… which is sad, but frankly seems less awkward than building this thing in Max.


Sooooo… anyone know what the programmable extension environment in Bitwig looks like…?

6 Likes

Much much much better documented than the same in Ableton Live.

A starting point:
https://www.keithmcmillen.com/blog/controller-scripting-in-bitwig-studio-part-1/

That’s always been my experience with Max as well, which is why I’ve never done anything serious with it. I know other artists have been willing to fight with it long enough to make something workable, but as a professional programmer I give up in frustration long before I reach that point.

I prefer Supercollider, even though it has its own warts, and doesn’t have nearly as strong of a UI toolkit.

1 Like

Have some other things to get through first, but when I return to this thread, I’ll write a bit about DSP for macOS/iOS apps, and maybe a bit about DSP for microcontrollers.

Controller scripting is relatively simple by comparison, and I’m honestly less concerned at this moment about how that happens, although I am very curious to learn more about @mzero’s Haskell sequencer (Haskell in general has really started to intrigue me since recent adventures with Tidal). I’m probably also more interested in DSP at the moment simply because it’s my next frontier for music-related programming, it’s something I’ve never really attempted before.

Are you going FRP for the Grid UI? Or a more traditional event loop?

When I bought my 128 one of the potential uses I had in mind was to use it for experimenting with FRP in Haskell. Perhaps once I’ve dragged myself out of the embedded C hole I’m in I’ll actually get round to it.

I’m afraid I haven’t really been following this thread (I despise visual programming). But Haskell is really composable, you could easily write a MSP style inlet / outlet DSL in it. It’s a shame it’s such a royal pain in the backside to learn…

3 Likes

A colleague just pointed me at Luna. Haven’t had time to look deeper than the marketing landing page, but it seems worth investigation time. Design wise it looks an awful lot like Audulus.

1 Like

Ooh, that looks interesting! Also reminding me of Lighttable, which itself was inspired by Bret Victor’s many essays and presentations.

Some good ones:
http://worrydream.com/LearnableProgramming/
http://worrydream.com/MediaForThinkingTheUnthinkable/