Tag Archives: controller

Max/MSP Package: Korg Nano

Ever since Cycling 74 introduced the idea of packages in Max 6.1, I’ve been pretty excited. Previously, there wasn’t a great way to distribute and install tools, objects, externals, media. And if you wanted to use anyone else’s tools, you had to wade through the murky collection of application directories and dump in single files–an unfailing way to ensure that you’d have to re-install these tools after a Max/MSP update.

With packages, Cycling 74 got rid of the mess. Tool creation, installation, and for me, distribution is clear and simple. Even if I’m developing my own set of abstractions for nobody’s computer but my own, packages provide a platform for a confident working-practice with long-term benefits. This post is meant to outline the pros of Max packages by walking through a working example of how one can set up her/his own Max package.

While I have created several Max packages since 2014, the post will outline my latest Max package, Korg Nano.  It’s a basic example, two objects that comprise a software implementation of the Korg nanoKontrol USB controller, certainly enough to get one started.

Installation
After downloading the Korg Nano package, unzip the file and place the unzipped folder directly into the ‘packages’ directory.  For Mac users, the folder is Applications > Max 6.1 > packages.  Or, you can read a short article by Cycling 74 on packages for installation.

What It Is
In short, packages provide global access. Autocompletion, media in global search paths, extras in the top Extras dropdown menu, option clicking helpfiles, it’s all there. What the Korg Nano package provides is a software listener for the 151 controls on the Korg nanoKontrol USB controller. The package is meant to be a plug ‘n play solution for this hardware device (and I use it for prototyping all the time).

After installation of Korg Nano in the Max packages directory (make sure you restart Max), navigate to the folder.  You will see four folders inside (docs, help, media, patchers) and a README file. Each folder has a unique purpose, and there are many more one can add (extras, javascript, clippings, templates, etc). If you’re curious, there is an “about packages.txt” file in the packages directory that outlines the finer points of Max packages. For now, we’ll unpack these four folders (docs, help, media, patchers).

Max/MSP Autocomplete feature for Korg Nano package.
Max/MSP Autocomplete feature for Korg Nano package.

The patchers folder is where you throw your abstractions and objects (not externals), including any additional bpatchers that you may have used to create your objects. Of course, if your package depends upon third-party objects, you can place them here (and within any named subfolder). For Korg Nano, there are two main objects, korgnano and korgnano.inputmenu.  korgnano is built from several bpatchers, which one will see listed in a subfolder (“patchers > korg_nanoKontrol”).

The media folder allows one to place images, audio, and video. This folder becomes global (after restarting Max), so you can also use packages as a way to manage media instead of worrying about “filepath” when you move from computer to computer. Since Korg Nano is a software implementation of the USB hardware controller, I used image buttons that simulate the look and feel of the hardware controller. Placing images in the media folder ensures they will be found, regardless of what computer I am using.

The help folder is exactly what one would expect. Help files ending with the extension .maxhelp.  While help files are useful (e.g. option-click an object to access its help file), Max packages allows one to provide some serious help to the help files. This helpful power boost comes by way of the docs folder.

Korg Nano help file that looks like a standard Max help file.
Korg Nano help file that looks like a standard Max help file.

The docs folder contains reference files that enable hover tooltips, documentation window text, uniform descriptions, and fancy descriptive break downs and object links from within the reference window. To understand what is happening in the help file screenshot above, let’s dig into the docs folder.  Navigate to the “korgnano-0.0.1 > docs > refpages > korgnano > korgnano.inputmenu.maxref.xml” file.  This xml file contains all the descriptions that get pulled for the help file. While this file contains confusing html/xml style tags, one need only look to two examples to see their power.

The first example comes from the first two xml tags <digest> and <description>.  These two description tags show up in the Autocomplete menu, the documentation window, the reference window (outside any help file), and the help file’s title object (actually, a jsui object that uses an application Max script “helpdetails.js” to parse these xml tags and display them for clean documentation).

The second example of documentation power comes from the <seealsolist> tag near the bottom of the .xml file.  One only needs to place additional object names here (e.g. “<seealso name=’korgnano’/>”) and links automatically appear in the reference documentation window, linking to your objects’ help files. This is handy here, as I want to link the korgnano object and the korgnano.inputmenu object together since these objects are symbiotic. The korgnano object grabs data from your Korg hardware controller and then sends the controller data direct to korgnano.inputmenu objects.

Docs, Help, Media, Patchers. That’s it.  A Max package that enables software listening for the Korg nanoKontrol, neatly bundled for distribution. Clear documentation files to help anyone navigate the tools, even me! when I revisit my tool a few months down the line. However, I do not need to distribute to reap the benefits.  Clippings, templates, patchers, or even externals that I use often in my own work have a place within a Max package, easily searchable and documented so I have a working practice that is efficient and scalable. For anyone working in Max, packages offer a clean way to keep your sh** together.

Korgnano object help file
Korgnano object help file

 

Reference
Korg Nano Max package

Notes
Packages also work with Max 7. While my example was built using Max 6.1, there is no reason why it shouldn’t work in Max 7. Email me if you have issues.

Speaking of issues… if you’re having trouble with autocomplete, try creating a message object in a Max window with the text “; max db.reset”.  This will refresh Max’s preferences, but may take 60 seconds+ to reload. Here’s the original forum post where I found this fix.

Qwerty keyboard as Kyma Tool controller

Tools help us carry out particular tasks and functions. Hammers drive in nails. Saws cut wood. In the digital realm, we also use tools. Faders control volume, buttons trigger sounds. However, in software, things are not always so clear cut. Faders don’t have to control volume, and buttons don’t have to trigger sounds. The examples of faders and buttons acknowledge the two types of fundamental control: continuous (faders) and discrete (button). Our digital tools are built upon these two paradigms of continuous and discrete control.

In Kyma, the Virtual Control Surface (VCS) lets us control sounds in real time. The VCS is  a tool that displays virtual faders and buttons (controlled by using a computer mouse or app). Since I don’t own an iPad, I am unable to take advantage of the VCS Kyma Control iPad app. I desired a non-mouse control inside Kyma that would let me get away from mousing and clicking. Thus, I wanted to take advantage of the controller most available to me and other users. The discrete control of the Qwerty keyboard.

Figure 1. Virtual Control Surface (VCS) inside Kyma.
Figure 1. Virtual Control Surface (VCS) inside Kyma.

This blog post covers my foray into Kyma Tools (a largely untapped resource of Kyma) and the result: an open source qwerty keyboard controller built in and for Kyma. One is process and the other is product.

Why Kyma Tool?
But let’s start off with the why. I could have easily created a Max patch that accepts ‘key’ control and then port off my ASCII values as Open Sound Control (OSC) messages to Kyma. Actually, I did. See Figure 1.

Figure 2. Qwerty control in Max/MSP sent as OSC message.
Figure 2. Qwerty control in Max/MSP sent as OSC message.

Yet, this is not as simple as it sounds. Not only do I have to open Max/MSP in order to run this patch, but I have to get the IP address of the Paca(rana), copy the IP address here… each and every time I start the Paca(rana). Not very fast for performance setup.

I wanted to see if I could embed this type of discrete, keyboard control inside of Kyma itself, cutting out third party software and reducing setup time. Hence, my foray into the Kyma Tool (aka. state machine that can read and write EventValues)

Kyma Tool Process
The Kyma Tool is where one can write a patch to carry out multi-step processes (Spectral Analysis Tool), process batch files or a folder of files, create a controller (my keypad tool), or create a virtual interactive environment (think CataRT if you wrote this in Kyma). The Kyma Tool does use SmallTalk and offers a bit different coding experience, but the Tool environment is a pretty powerful editor. I knew that if I wanted to get access to the qwerty keyboard and create a controller, I would need to dive into the Kyma Tool. (For further reference to the Kyma Tool, please see the Kyma X Manual, pp. 309-333).

Figure 3. Keypad.pci backend tool layout
Figure 3. Keypad.pci backend tool layout

Like javascript or php, there are global and local variables, and like Flash, there are event based actions, or rather “triggers” and “responses”. A huge thank you to Carla Scaletti for tipping me to the global variable LastCharacterTyped, where the initial value, $a, stores the last character value of the qwerty keyboard based upon user input. For example, typing ‘f’ becomes $f, or typing a ‘1’ becomes $1. LastCharacterTyped gets you access to the user typing on the keyboard, but only the character value of the user’s action.

The first step of my Keypad Tool is to convert each character into ASCII. Since each value is a character, I convert the character into an ASCII integer using the Capytalk “asInteger”.

keyboard := LastCharacterTyped asInteger.

The Capytalk above stores the ASCII integer into the local variable keyboard. The local variable ‘keyboard’ writes/outputs its value to the HotValue !KeyBoard. Writing the control to a HotValue provides access. !KeyBoard, the ASCII integer of a user’s keyboard, is now accessible, in real time, by any Kyma Sound that references the variable !KeyBoard. So long as one uses the Keypad Tool, !KeyBoard can be used by any Kyma Sound at any time, anywhere, just like the Max patch above.

Figure 4. keyboard variable as !KeyBoard HotValue.
Figure 4. keyboard variable as !KeyBoard HotValue.

The next function I desired, beyond accessing the Qwerty keyboard values as a Kyma HotValue, was to specifically address the number pad 0-9 (in ASCII, 0-9 equal 48-57). For these ten keys, I wanted 0-9 keypad values to store as their actual numbers inside a different HotValue. Below is the Kyma Tool code.

(keyboard between: 48 and: 57)
ifTrue: [keypadNumber := keyboard-48]
ifFalse: [keypadNumber := -1].

Here’s the English version. If the ‘keyboard’ variable (this is our ASCII value) is between 48 and 57 (inclusive so would react to 0-9 on the keyboard), then store your value into variable ‘keypadNumber’. If not, store a -1. In Kyma, we usually write Capytalk true: () false: ().  In Kyma Tool land, I had to learn that we need ifTrue: [] ifFalse: []. Subtle syntax, but one that I lost an hour over. You’ll see in the example files how we’ll utilize the Capytalk true: () false: () in a SoundToGlobalController.

The ‘keypadNumber’ variable also outputs its value to a HotValue, !KeyPad. !KeyPad outputs 0-9 when qwerty keys 0-9 are pressed. Otherwise, any other key value outputs -1.

Kyma Tool in Action
Ok. So how does one use this Kyma Tool?  Similar to the Tools > Fake Keyboard or Tools > Spectral Analysis tool inside Kyma, all one needs to do is open the Tool (‘keypad.pci’) inside Kyma (File > Open) and start typing on the keyboard to output values. No external software or OSC setup necessary. Of course, however, you’ll need to download the tool.

Figure 5. Two states of keypad Tool. Shows lastCharacter, ASCII value (!KeyBoard), and !KeyPad hot value.
Figure 5. Two states of keypad Tool. Shows lastCharacter, ASCII value (!KeyBoard), and !KeyPad hot value.

The only note about Kyma Tools is that their window needs to be highlighted (in front) in order to work properly. This is not a new software concept, but one that users of Kyma Tools should be aware of.

Download
Download the keypad.pci Kyma Tool and example files to help you get started.