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.
(this makes 7 books I’m currently reading that were suggested or inspired by this forum, you folks are such good brain food!)
I dove into that recently, but due to other things, haven’t gotten past the first two chapters. I did successfully build an external, which was pretty exciting. I’m curious if anyone has any insight into any fundamental differences in performance between a DSP routine contained in an external, and a DSP routine written in codebox in gen~. I find the quickness and ease of prototyping in gen~ really encouraging. Is the code easily adaptable from gen~ over to C?
Wish I could share some tips, and not just ask questions- but my experience in the topic is limited. I am interested to hear what others have to say!
gen~ performance is supposed to be similar to C performance (I don’t know if it is identical, but it is supposedly comparable).
My motivations for exploring externals aren’t really about performance. Has more to do with things such as code sharing between Max and non-Max projects, unit testing, structured programming, and to be honest, a preference for text over patching. So, for me, it’s more about workflow and collaboration and maintainability than it is about performance. YMMV.
In order to get the first example from the Designing Audio Objects book to build, I needed to use the current version of the Max SDK, which @tehn links to above, and then replace the c74support directory located in the Code/MaxMSP Code/ folder from the book’s DVD.
I also needed to edit the Build Settings in XCode 7 so that it used a 32-bit Intel architecture, and then I needed to change the values under Base SDK to Latest OS X.
Then I needed to ensure that Max 7 started up in 32-bit mode (Get Info on the Max 7.app file to do this)
At that point the build succeeded and the resulting mirror~ external worked as expected in Max 7.
At some point I’ll read the DVD’s Updates/Max 6/Writing Externals for Max 6.pdf and understand how to target 64-bit architectures, which I believe will work in Max 7 regardless of whether Max was started in 32-bit or 64-bit mode.
OK, nice, if I use the files available at the link @Evan provided, there’s no need to change the architecture Build Settings in XCode. It comes pre-configured for a Universal build with the Latest SDK.
But I did still need to open Max in 32-bit mode, so the Updates/Max 6/Writing Externals for Max 6.pdf is still relevant if you want your externals to work in 64-bit mode.
…no wait… i guess i do have some things to add to this thread:
Yes, although gen~ code is based on the language of ‘LUA’, the basic conditionals and other such syntax of C which are used in many languages like Java, C++, etc. are also in gen~ so it can be pretty easily adaptable(LUA is based on C same as many of these other languages).
The fundamental differences in performance are minimal(the DSP routines themselves work pretty much the same calculating things at sample rate and allowing you to hide functions from that calculation within conditional statements wherever necessary). There are some advantages to writing an external in C which have to do with having direct access to the internal ‘struct’(or memory of an external) and performing efficient checks as to whether a signal or a message is attached to the inlets of an external, then catering the DSP method to those(whereas in gen~ it’s all assumed as signals by the time it hits the DSP method within, but certain types of messages are only calculated once per vector…), however, most beginners won’t find these differences to be huge gains or losses.
The main advantages to writing externals in C are found in creating access to some of Max’s more esoteric and special features and functionalities(as mentioned before, you can separate a DSP routine that works specifically for messages as opposed to signals(detecting what’s connected to each inlet then moving from there), but other examples of extending behavior using a C external are: gaining access to specialized functionality within poly~, doing specialized checks and reformatting for changes in external buffer~s, creating behaviors specific to Windows as opposed to MacOSX within the same code, doing special things like handling files, creating a UI within the same audio-handling object, creating different typed outlets(for example in karma~ there’s a regular set of signal outlets, but then an internal scheduler-clock polls certain information to be sent out the last outlet in messaged format), etc.).
Having said all that, if you’re just starting with coding, gen~ is best since it offers a bridge between visual patching and coding(with codebox), and is still highly efficient, but eventually i’ve actually found writing externals in C to be a bit easier simply because i know the SDK and it allows me more modular access to different kinds of functionality and efficiency within one external/code(easier in the sense that i can separate things out to be more readable and develop them in a more organized easy-to-keep-track-of sort of way).