Categories
Computing

Nicaragua, Forget Paris

Nicaragua was not on any of our lists of places to visit — I don’t think my wife and I had ever even said the word Nicaragua to each other before my wife’s company began doing business there. For a Central American trip, Costa Rica would have been a more likely choice, and we had talked about doing just that in 2002 — I had convinced her to marry me on the Amalfi coast in Italy instead.

IMG_1161


 

Like many Americans, if my wife had said, “hey, let’s vacation in Nicaragua”, it would have given me pause. I’m sure my response would have been “what? … why? … … what?!?”. My first thoughts would have to do with Sandinistas, Contras, incursions from Honduras, an unstable government, unfriendly socialists, violence and poverty.

The poverty aspect may have some degree of truth — I’ve read that Nicaragua is the poorest country in Central America. Despite the State Department’s warning to avoid public demonstrations (a great idea in any country), we found the country to not be affluent, but it was also friendly, beautiful and inviting. Even our brush with the Nicaraguan military wasn’t all that off-putting.

In any event, my wife’s company sent her to Nicaragua, and my first response was “you’re not going down there by yourself”.

https://upload.wikimedia.org/wikipedia/commons/d/d8/Map_of_Central_America.png


On the flight from Miami to Managua, we sat next to a native Nicaraguan, now a current US Citizen working in Miami. She seemed pleased that we would be visiting Managua and San Juan del Sur. I got the impression that she wanted us to see the best parts of her country — Nicaraguans definitely have pride in their country, but not in an off putting “we’re better than you” manner. She was both friendly and quite gracious for my assistance with her bag — given my 6’1″ frame, and her not quite 5’0″ frame, the overhead bin was nearly impossible for her, and not an issue for me. This was our first, and very pleasant, encounter with the citizens of Nicaragua. There were exactly zero unpleasant experiences.

Our stay in Managua was pleasant enough. We spent one night on each end of our trip at the Camino Real near the airport. Oddly, the picture on their homepage doesn’t do justice to the hotel. Our stay in Managua was limited to the hotel and driving through some poor-looking sections. The Camino Real has a mostly gracious, reserved, friendly staff, an inviting bar, a free welcome drink and a very reasonably priced restaurant. On the night before traveling back, we spent an hour at their beautiful pool sipping wine and watching some corporate visitors having quite a lot of fun. (And this picture does the pool no justice either.)

IMG_1151
Pool
IMG_1149
Outdoor Private Seating



 

On the road from Managua to San Juan, we tossed our luggage into the back of a pickup. Pickups seem to be the mode of transport. It’s not uncommon to see a Toyota pickup with 8 people sitting or standing in the back. (It’s also not terribly uncommon to see oxen or horses pulling carts, rickshaws, and bicycles all sharing the road. At one point, we saw a small pony darting across the two-lane highway. You’ll see many methods of transportation.) We definitely saw some poorer areas on the road. However, stands selling good were everywhere. Capitalism is alive in Nicaragua!

IMG_1139
Speeding down the highway
IMG_1141
Herding Cattle
IMG_1125
Rickshaw and Roadside Stand

I had noticed only one US-style strip mall in any of the towns we drove through — most of the edifices were pretty modest by North American standards. As a fellow travel companion and I agreed on, we were pretty surprised by the amount of garbage seen by the side of the road near Managua. In the picture below, you can see a modern gas station with a simple stand built out nearest to our driver, Jennifer. The stands are ubiquitous, the gas stations less so.

IMG_0959
Gas and Roadside Stand
IMG_1134
Another Roadside Stand

The reason for our trip, to drop off Dane to address issues with one of the company’s turbines, was quite interesting. The turbines do fit the landscape quite well, but it’s a little out-of-place to see these very modern edifices after seeing other structures that are quite a bit more modest in design.

IMG_1023
Suzlon Turbines

IMG_0974

IMG_0977
Dane getting ready for the climb
IMG_0979
Climbing Gear

 

In San Juan, we were guests at The Pelican Eyes Resort. This resort is quite picturesque, and given the foliage, reminds me a great deal of Italy.

IMG_1112

Walking out of our resort, one immediately notices a change in affluence.

IMG_1088

IMG_1089
I referred to the resort as “the compound” as it was protected by a boom barrier and one, often two, uniformed security guards controlling ingress and egress. Taking a back road into the resort, one is also presented with a boom barrier and similar uniformed security.
The change in affluence though is not to say the area around the resort is dangerous. In fact, the area seems to have many small businesses and families living in close proximity.

IMG_1084
The Local “7-11”, small and packed with goods
IMG_1082
The Local Laundry
IMG_1090
The 24-hour carwash

We often mistake lack of affluence for danger, or at least I’ll admit some guilt in that area. (Affluent neighborhoods in Chicago seem to be experiencing a crime rate, not on par with an affluence that one might think brings safety.) Employees and resort guests appear to be welcome to come and go from the resort. My first thought is that the resort likely provides a decent amount of revenue for San Juan. Would-be criminals are likely not very welcome, especially given the potential for bad press given social media and online reviews.

If you are a thief, and you want to find your way into Pelican Eyes beyond security, you’re then welcome to climb 100-300 stairs to rob someone’s room. Then you need to climb back down, get around security again to get away with my dirty laundry.

The area around the resort reminded me of my neighborhood growing up before it turned bad. Lots of families outside, little stores, a church, plenty of street activity — kids playing, dogs sleeping on the sidewalk, people sitting outside at night talking and visiting. Quite different from the modern-day American suburbia where we drive into our garage and press the garage door opener button to seal ourselves away. (And that is only to say that it’s different, not better or worse.)

In this little Nicaraguan neighborhood, I didn’t ever feel threatened, and to some extent, while carrying an E2D LED Defender Ultra didn’t create overconfidence, it didn’t hurt either. As it turned out, it was particularly helpful navigating the dimly lit 311 stairs back to the room. (Interestingly, the retired Army Colonel we were traveling with noticed “the defender” immediately.)

IMG_1103
The Stairs

We were approached my street vendors on several occasions. A simple “no” or shake of the head sent them packing. Except for one who had just the hat I needed at the rock bottom price of $10. He will not be getting rich anytime soon unless he’s acquiring those hats for free. Even then, he’s not getting rich soon.


The resort itself, as these pictures show, is quite beautiful. This was our view daily for breakfast.
IMG_1117
In the evenings, our views looked like this.
IMG_1037IMG_1032IMG_1072
Overall, not tough to take.

The highlight of our trip was a sailing adventure. We docked off a white sandy beach and Terry, Sue Anne and Dee all swam to shore (note to self — bring trunks to Nicaragua next time).

IMG_1056
Victory

Soon after they returned from the beach, it became home to 8-12 Nicaraguan Army regulars. That’s a story for another time.


 

A little side trip I took was to Fight Club San Juan. I wasn’t able to take a class there, and there were no heavy bags to practice on. To say this gym is gritty is an apt description. There is a boxing ring where presumably classes are held. There were a few mats, some mirrors for shadow boxing, a bunch of free weights and no lack of weight benches. I enjoyed working out there quite a bit, my wife not so much.

One particularly nice feature of the gym was the temperature. It was easily 90 degrees inside, so working up a sweat was quite easy. I was soaked after 5 minutes of shadow boxing.

Should we return to San Juan, I would definitely spend a bit more time there.


Whatever the politics here, the people seem to be interested in capitalism and business.
To a large extent, given my last few experiences in France, I honestly feel safer in the bits of Nicaragua I have seen than I do in Paris — at the very least, people here are not trying to take advantage of me and preaching to me about whoever happens to be taking up residence in the White House. They are happy to provide a service — they are always gracious when accepting tips. While they might want to sell me a hat or might be working hard for a tip, they are definitely looking to trade rather than take advantage of. My recollections of Paris are replete with taxi drivers trying to rip me off, restaurant owners wanting to lecture me on the evils of America and hawkers stopping me in the street trying to swindle money out of me. In the future, it’s Nicaragua, San Juan del Sur and other parts there, not Paris.

Categories
Computing

Friendly Hostnames with SSH

This article is for Mac OS X, 10.9.5. We’ll review how to log in to a machine on AWS using a friendly hostname rather than an IP address.

If you have many servers in your care, recalling all the related IP Addresses can be tedious, confusing and error-prone. Keeping a list in a database or spreadsheet is one way to track IP Addresses, but a more efficient method is to keep that list in the hosts file on your machine. Once you set up your hostname, there won’t be anything to look up!

Instead of typing in:

ssh 192.168.10.109 -l myusername -i mypemfile

we’ll be able to type in:

ssh myservername -l myusername -i mypemfile

If you’ve adopted naming conventions, logging in is quite easy.


Four Easy Steps Overview

  1. Check to see if you have a file called /etc/hosts.
  2. If not, create a symbolic link to /private/etc/hosts.
  3. Edit the file using pico adding the desired entry.
  4. Log in to the target machine.

Four Easy Steps with Detail

  • From any directory, type ls -l /etc/hosts. If the terminal responds with “no such file or directory“, we’ll create the link to /private/etc/hosts in the next step.
  • To add the symbolic link, use the ln command with the -s option (the -s option specifies that the link is symbolic). This will create a link from /etc/hosts to the actual file /private/etc/hosts and make the hosts file generally available wherever you are in terminal.
ln -s /private/etc/hosts /etc/hosts
  • Now, edit /etc/hosts using nano, pico or your favorite text editor. Add an entry similar to what is shown below. (Note that the ip address is hidden in the example.) In this case, we’re mapping the IP to a standard machine abbreviation used to represent the company (gwa), the type of server — ws (webserver), and the number of the server.

etc_hosts_file

  • At the point, you should be able to log in to your target machine using the hostname specified in the hosts file. The first time you connect, you’ll see a message similar to the following.

friendly_hostname_login

That’s it!

Categories
Computing

Inspiration

Hustle. I’m seeing a lot of it these days, and in ways that are inspiring.

Many of the people I’m meeting up with these days are part of new businesses, or they are revitalizing and transforming existing ones. It doesn’t really matter which. They seem energized with the possibility of something better, and fatigued by the same old.

There has been a lot of “we can’t” floating around in my world. There has been a lot of “do it for me”. I’ve been listening to people complain about “getting older”. Like a long winter, it’s gotten tiresome. It seems like it’s time to replace that with the grace of energy and possibility.


Grace. Having decided that I wanted something non-electronic in my hand to read for our trip to South Beach, we headed out to Barnes & Noble with our friend Cindy. Much to our surprise — on a cold, sunny January day — the parking lot was quite full, and the store was quite busy with book buyers. There wasn’t anything in particular that I had in mind to purchase. A hardcover (a real book in my thinking) seemed like a nice indulgence that would be a welcome change of pace from the books on the iPad — non-fiction rather than fiction seemed like a good choice as well.

(For whatever reason, a hardcover book seems like something to be savored. The iPad book — something to get through.)

After wandering about the store for a bit, I came across a section of award-winning books. One, in particular, caught my eye.

The Art of Grace, by Sarah L. Kaufman, certainly has an interesting title. Reading a bit of the book and book jacket, I was intrigued to see that Ms. Kaufman was going to talk about Grace in light of history, religion, Motown, tennis, Hollywood, art and dance — to name a few. Her words.

Grace — the kind I’m talking about, everyday grace, honest and disarming — doesn’t exist without a test. It is most apparent when we have fallen, when we are bare. It is revealed in the simply act of paying attention, when a subtle change, a bit of hidden choreography or an unexpected show of understanding suddenly becomes a moment of truth. We just have to look.

We just have to look.

Looking is what I seem to be doing, and not looking very hard to see evidence of grace all around. Grace is in the hustle I see in so many people working to make their lives, and the lives of others around them, better. Everyday grace, honest and disarming.


Inspiration. It can come from many places and is something to be savored and appreciated. It is not always there. A new love, great book, visited place, opportunity or situation in our lives can spur excitement and possibility.

This is truly a great thing.

I just came across the following quote — I had long ago shared this with the choir I was directing, as it had been shared with me by a professor.

“Whatever you can do or dream you can, begin it. Boldness has genius, power and magic in it!”

– attributed to Goethe

“Begin it” has an element of newness to it. Not as often, when we stay with something or someone, and are loyal, and we encounter newness, we can be inspired in a much deeper way.

With this inspiration, we are assured that we know and understand the people involved. We’ve seen them at their best, maybe not quite their best, but mostly in their daily lives.

They know us too and they’re ok with us the way we are.


These days, I find inspiration among the hardest working people I know. They are horsemen and fighters. They are women and men, younger and older, new to a sport, in it for a long time.

The horsemen creating this latest inspiration are people who work and play at our new, private barn where we board our horse, Bo. Many of these people also work outside of this barn, but gather in this place to create something new and better. When I do see each one of these people, it might make sense for them to be resting. Instead, they show up early to a cold, damp barn on Sunday mornings (as we do) when others are tucked warmly in bed. They might ride horses, they might walk horses or they might clean stalls. They might manage the barn, or oversee the training of the horses. They might be installing ductwork or putting mirrors in the arena. They work hard to make this new place an ideal, or to make a few more bucks to meet whatever their ideal world is. They work toward their vision. And Mario says, “no one person is more important than other”. We all contribute different things. Some of us pay board; some are working students. Everyone works and works hard.

IMG_2226

In the words of a legendary rock guitarist, “I was always told if you want something you work for it”. There is no reliance on having others do it for you. It’s a short sentence. You can try to interpret it, but you shouldn’t get too far. It’s not a complicated thought.

And in that thought, there is great struggle and great joy. Not everyone I encounter wants to put the time in. Many want to rely on others, are on their past accomplishments, to move forward.

The “work for it” vision doesn’t involve taking advantage of others. Work for what you want. “You do it”, as a riding instructor often told me with an emphasis on “you”. (Her instructions were always simple, straight to the point and pretty deep.) The horse won’t do it; the instructor won’t. You do it. You put your leg there; you ask; maybe you go. Maybe not. Maybe that horse throws you on the ground or scrapes you against the wall. You figure it out.

These people work. They don’t acquiesce. They don’t take “no” for an answer, and they’re not willing to settle for anything less than their vision, and they’re not looking for others to do it for them.

They inspire, and they should.

12391996_1223991454282794_1084299048987183058_n

Every week at this barn, I see improvement. One week, it’s better lighting. Then, there’s heat in the barn (yes, for the horses); internet access; a better stall with more natural sunlight, an old coffee pot that still wants to do its job, a heated shower (for the horses), a freshly dragged arena, a clean horse, a new big screen TV to review video, a free horse show for those who have encountered difficulty in their lives.

Sometimes, not always, we stay with people and are rewarded. That’s not always the case. Perhaps karma will sort everything out. Probably not.


At the gym where I train in Muay Thai, the mats are clean. People share their wisdom and passion for Muay Thai. There might be 4 people in the class; there might be 40. For the instructor, their passion and interest isn’t reflected by more or less students.

The child in us can see this and tell the difference between authenticity and those things that are fake. This photo is a testament to that.

IMG_2222

Some people fight for themselves. They work hard for what they want and make the world a better place.

IMG_2223

MMA fighters, in particular, work for what they want. At the end of the day, they shake hands and embrace their opponent. They may be fighting each other, but truth be told, they are really fighting to get somewhere. They would gladly root for the other guy, but maybe next fight. I’m glad to know them. They work very hard and are tremendously disciplined.

IMG_0573

The people that inspire me the most, are the ones that work the hardest for their dreams. They may never be prize fighters, Olympic medalists or world-renowned trainers. They will, however, have a lasting impact on their world and those around them. In so many ways, they seem so much more important than the prize fighter or the Olympic medalist. They such a positive impact on the world in ways that don’t involve just themselves. I’m glad to know them all, and be part of their world.

 

 

 

Categories
Computing

SQL Server Date to Varchar Conversion Formats

Often, I find the need for a specific format for a date. SQL has lots of great options with its convert function.

Here’s a handy chart.

select convert(varchar, getdate(), 101) -- 12/23/2015
select convert(varchar, getdate(), 102) -- 2015.12.23
select convert(varchar, getdate(), 103) -- 23/12/2015
select convert(varchar, getdate(), 104) -- 23.12.2015
select convert(varchar, getdate(), 105) -- 23-12-2015
select convert(varchar, getdate(), 106) -- 23 Dec 2015
select convert(varchar, getdate(), 107) -- Dec 23, 2015
select convert(varchar, getdate(), 108) -- 08:32:49
select convert(varchar, getdate(), 109) -- Dec 23 2015 8:33:06:007AM
select convert(varchar, getdate(), 110) -- 12-23-2015
select convert(varchar, getdate(), 111) -- 2015/12/23
select convert(varchar, getdate(), 112) -- 20151223
select convert(varchar, getdate(), 113) -- 23 Dec 2015 08:33:25:220
select convert(varchar, getdate(), 114) -- 08:33:25:220
select convert(varchar, getdate(), 115) -- 115 is not a valid style number when converting from datetime to a character string.
select convert(varchar, getdate(), 116) -- 116 is not a valid style number when converting from datetime to a character string.
select convert(varchar, getdate(), 117) -- 117 is not a valid style number when converting from datetime to a character string.
select convert(varchar, getdate(), 118) -- 118 is not a valid style number when converting from datetime to a character string.
select convert(varchar, getdate(), 119) -- 119 is not a valid style number when converting from datetime to a character string.
select convert(varchar, getdate(), 120) -- 2015-12-23 08:34:39
select convert(varchar, getdate(), 121) -- 2015-12-23 08:35:46.370

Feature Photo by Andrew Neel on Unsplash

Categories
Computing

Spinning up a New VM via Azure PowerShell – Quick

 

A more in-depth version of this post can be found here.

This article assumes that you have the following:

  • An active Azure subscription.
  • An Azure PowerShell installation. (This differs from the normal PowerShell installation.)

Let’s get started. From the Azure Powershell command prompt, type:

Add-AzureAccount

Sign in to Azure.

To get your SubscriptionName, simply execute the cmdlet Get-AzureSubscription. Use the SubscriptionName in the command below.

Set-AzureSubscription -SubscriptionName "Free Trial" -CurrentStorageAccount "yourstorageaccount"

It’s important to note that the SubscriptionName is not the GUID you see when logging in.

Assuming you know the ImageName and the InstanceSize, your command will use New-AzureVMConfig to create the VM. (Note that this is in a ps1 file.) In this case, we’re also piping to Add-AzureProvisioningConfig, Set-AzureSubnet and New-AzureVM.

Screen Shot 2015-12-19 at 6.46.43 AM

Execute the contents simply by typing the filename. Since we’ve returned to the command prompt without issue, the VM is being created.

Screen Shot 2015-12-16 at 6.49.02 AM

We can see evidence of the machine being created at manage.windowsazure.com.

Screen Shot 2015-12-19 at 6.52.49 AM

Categories
Computing

Using a Correlated Subquery to Update a Base Table

The syntax for updating using correlated subqueries can be a little confusing at times. The example shown below uses a table variable as its target.

The key is to include an aliased version of the table in the UPDATE’s FROM clause.

Once that is aliased, you can simply reference the alias in the subquery.

For example:
UPDATE
    x
SET
    PROJCOMMENTID = 
    (
        SELECT 
            MAX(pc.PROJCOMMENTID) 
        FROM 
            ProjectComments pc (NOLOCK) 
        WHERE 
            pc.PROJECTID = x.PROJECTID
    )
FROM
    @ProjComments x

Featured Photo by Maarten Deckers on Unsplash

Categories
Computing

Spinning Up a New VM via Azure Powershell

Screen Shot 2015-12-16 at 6.49.02 AMThis article assumes that you have two items:

  • An active Azure subscription.
  • An Azure Powershell installation.

Let’s get started. From the Azure Powershell command prompt, type:

Add-AzureAccount

Sign in to Azure with the appropriate credentials when prompted. After successfully signing in, you will see your subscription information.

Screen Shot 2015-12-11 at 12.28.11 PM

For the next command, Set-AzureSubscription, it’s recommended to specify the subscription being used. In my case, at this juncture, the command looks like the following:

Set-AzureSubscription -SubscriptionName "Free Trial" -CurrentStorageAccount "pwgazstore"

(pwgazstore is the Storage Account set up previously. Creating that is beyond the scope of this post.)

It’s important to note that the SubscriptionName is not the GUID you see when logging in. To get your SubscriptionName, simply execute the cmdlet Get-AzureSubscription.

Screen Shot 2015-12-11 at 12.38.03 PM

In order to find the name of the image you’d like to install, you can type the following.

Get-AzureVMImage | Select ImageName

As it turns out, even when piping with | more, it’s rather tedious to sift through the results. The list is quite long.

Luckily, it’s easy to create a function that acts like grep. To boot, you can simply type it at the command line and it’s yours!

function grep {
  $input | out-string -stream | select-string $args

}

See http://stackoverflow.com/questions/1485215/powershell-how-to-grep-command-output

Get-AzureVMImage | Select ImageName | grep AppX

The entire command then to spin up a VM looks like the following. This assumes your subnet is named “Subnet-1”. (Note in this case here, the ImageName is a custom image. Any image you can Get-AzureVMImage with should work.)

Screen Shot 2015-12-19 at 6.46.43 AM

This is a ps1 file that we can see when we ls. We can execute the contents simply by typing the filename. Since we’ve returned to the command prompt without issue, the VM is being created.

Screen Shot 2015-12-16 at 6.49.02 AM

We can see evidence of the machine being created at manage.windowsazure.com.

Screen Shot 2015-12-19 at 6.52.49 AM

Categories
Computing

An Introduction to Writing Externs in C for Max/MSP

Abstract

The target reader of this paper is a Max/MSP user with limited programming experience. This paper analyzes a single sample program adapted from Ichiro Fujinaga’s tutorial on compiling externs using Xcode. Code samples are shown in Xcode, but a variety of programming environments is possible. The example discussed here introduces and explains the necessary framework to begin developing more complex externs. Knowing this framework is extremely helpful in developing externs.

[If you’re only interested in the code discussion and not in getting setup, skip ahead to section 3.]

1 Overview

A language provides a vocabulary and the rules for combining words in the vocabulary. Grady Booch

If we were to apply Booch’s comment to Max, we might first observe that Max has a considerable native vocabulary (sfplay~, ezdac~, ctlin, etc.) and that the mechanism for treating the native Max vocabulary is robust, which in this case is to say that the mechanism imposes few rules. The framework is the blank canvas in Max, do what you want with it. One can simply combine the existing vocabulary in any desired way. Even with that power, Max allows users to further syntactic extension. While creating a specialized vocabulary by writing externs is not necessary for the successful use of Max, it does allow developers the opportunity to extend the vocabulary and introduce new objects to the Max environment.

1.1 Recommended Sources

A word should be said about existing extern development documentation. There are limited, but excellent sources available. Two papers, “Writing External Objects for Max 4.0 and MSP 2.0” [2001] and “Writing External Objects for Max and MSP” [2005], are available from Cycling ’74. Both of these papers are excellent, easily readible and largely cover similar material. In fact, the 2005 version seems to be an updated 2001 version. There are also a number of sources available online at McGill University in Montreal. Ichiro Fujinaga teaches a course there titled Advanced Multimedia Development that focuses on writing externs for Max. As of this writing, Fujinaga has three tutorials available, each for a different version of the Mac/Programming Environment (Classic, OS X & OS X Xcode). There are limited PowerPoint slides from his course and many externs that serve as great examples.

1.2 Development Environment

The subject of development environment is a bit beyond the scope of this paper, but is critical to the success of compiling the code discussed here. In the paper “External Objects for Max and MSP”, Cycling ’74 explains how to write externs using CodeWarrior on the Mac and Microsoft Visual Studio on the PC. One of Fujinaga’s tutorials, “Max/MSP Externals Tutorial: Version 3.1”, discusses using Xcode on the Mac. There is a more recent tutorial at www.cycling74.com, entitled “Writing Externals with Xcode 2.2”. Getting the development environment set up correctly can be challenging.

1.3 Code used in this Paper

The code shown in this paper is taken directly from Fujinaga’s example in his paper “Max/MSP Externals Tutorial: Version 3.1”. The code presented here has been varied slightly. Fujinaga’s paper is largely concerned with getting the development environment setup and does provide an overview of the code. This paper is a bit more in depth (in terms of this single example) and aims to explain Fujinaga’s example in light of other sources, notably Zicarelli and general C programming constructs.

1.4 What you’ll need to compile and run this code

In order to compile and run the code in this paper, you’ll need the following.

1. Max/MSP2

2. The Max/MSP SDK3

3. A development environment 4 that will compile C code. This paper uses Xcode5 on the Mac. You’ll deploy your code to Max’s extern folder and access it similarly to any other Max object.

2 What is an Extern?

An extern, or external, is a computer program, not part of Max’s standard object palette, that will be consumed by Max. The program is in the form of a shared library or dll. The most common language used for externs is C, although a bridge called FlexT is available for C++.

There are two broadly defined types of externs – a normal object and a user interface object. A normal object rendered in Max looks like many Max objects, with either a single or double line both on the top and bottom of the object, inlets and outlets, the object’s name and arguments. A user interface object, beyond the scope of this document, brings its own UI to the table.

Screen Shot 2015-12-13 at 3.53.20 PM

In terms of C code, at a high level, an extern essentially consists of an entry point (the main() function), a description of the object (in the form of a struct) and definitions of functionality (in the form of methods). Certain methods and elements of the struct are required by Max.

3 An Example

Learning the framework of an extern, along with compiling and deployment will go a long way to getting into some more involved projects. The essential structure shown here is relevant to externs generally.

Screen Shot 2015-12-13 at 3.54.33 PM

Figure 2. bang.c Source Code in Xcode environment

Let’s look at this code from the perspective of how Max runs it. Max will load the extern’s code starting with main() – main() provides the entry point for Max to gain access to the behavior you will provide7 in your methods. main()’s job, in the context of this extern, is simply to “initialize its class”. This means that main() is called either when Max loads (if your extern in your max-startup folder) or when
you create an instance of your object at design time in the Max patcher window (this latter approach will occur if
your object is not in your max-startup folder, but is somewhere where Max can find it).

3.1 setup()

As Figure 2 shows, the first line of code in main() calls a function, setup(). If you spend some time coding Max objects, the details of this method call will become very familiar. This method is available by virtue of including ext.h which is the first non-commented line in the source code:

#include “ext.h”

setup() provides Max with the (1) information to find your object (where it lives in memory), (2) the name of your object’s constructor (the housekeeping tasks performed to create your object in memory), (3) the name of its cleanup method (the housekeeping tasks performed to remove the object from memory), (4) the size of its data structure, (5) the name of the method that will define your object’s UI (if you have one – we don’t in this example) and (6) the type list 9 . That may seem like quite a lot, but some of the parameters are optional and can be sent zero values (0 or 0L in the case of a long datatype). In the example above, we only use three of the six available parameters. Moreover, the nasty business of doing object creation and destruction is handled for us in this simple example. That turns out to be quite nice. Here’s the call to setup with the various arguments highlighted:

• the location (address) of your object:

setup((t_messlist**) &this_class, (method)bang_new, 0L, (short)sizeof(t_bang), 0L, 0);

• the name of your constructor (which is going to be in the form programname_new or programname_create):

setup((t_messlist**) &this_class, (method)bang_new, 0L, (short)sizeof(t_bang), 0L, 0);

• a method that will do cleanup; in this case this is pointing to nothing

setup((t_messlist**) &this_class, (method)bang_new, 0L, (short)sizeof(t_bang), 0L, 0);

• the size of your internal data structure (required):

setup((t_messlist**) &this_class, (method)bang_new, 0L, (short)sizeof(t_bang), 0L, 0);

• the name of the method that will define your user interface:

setup((t_messlist**) &this_class, (method)bang_new, 0L, (short)sizeof(t_bang), 0L, 0);

• an argument list you may pass to your class (here again, we are pointing to nothing, or null):

setup((t_messlist**) &this_class, (method)bang_new, 0L, (short)sizeof(t_bang), 0L, 0);

In our example, we’re providing Max with three pieces of information: (1) the object address, (2) the constructor, (3) the size of the data structure. The other bits are not needed, but we still must provide values as this method is not overloaded.

3.2 addbang()

We have one more line of code in our main() method and that line has a simple explanation. It’s important, for the purposes of running our extern, to distinguish between where a certain method is located in memory (accomplished by binding our function) and what that method actually does (accomplished by defining our function). The addbang((method)bang_bang) method tells Max which of our functions to run when our extern encounters a bang. In short, it says, “when my object receives a bang, the name of the method that is to be invoked is bang_bang”. addbang() is likely a method you’ll encounter often when writing externs. addbang() has a number of addsomething() siblings: addfloat(), addftx(), addint(), addinx(), addmess().

If our method name were N_bang, then the syntax for “binding” our method to our implementation is:

addbang((method)N_bang);

The method name for N is normally the name of our program followed by an underscore followed by the word bang. So, if we were writing an object called attenuator for Max and our object needed to accept a bang as input, our method name for handling such input might be attenuator_bang. Similarly, if we wanted methods to handle ints, floats, etc. in our attenuator object, we would have methods such as attenuator_int(), attenuator_float, etc. Typically, we bind these methods to inlets in our main() method.

3.3 Recap

So, in short, the main() routine of an extern is used to bind our methods.

3.4 Implementation

Telling Max how to build our object. In Max, most objects have inlets and outlets. We send messages in, we get something out. Take the ubiquitous notein object, for example:

Screen Shot 2015-12-13 at 4.07.12 PM

Figure 3. notein pictured in the patch from Max’s help on notein.

notein gets its information coming in via the MIDI stream, so there is no visible connector going to an inlet 13 . The implementation of this object, behind the scenes, takes that stream of data, parses it, and outputs specific pieces of data (pictured above). In Max then, we can do something with this data – we can route pitch, operate on the values, etc.

In code, we describe the outlets in our data structure. In our example, that is this:

Screen Shot 2015-12-13 at 4.08.34 PM

You may be asking, “where’s the inlet defined?”. One inlet is automatically created for an object so you don’t have to create one manually in code. This is a nice default since typically we’ll want at least one inlet. It is possible to instruct Max not to create an inlet in your constructor14 . You do need to create any outlets in the struct, however, and you’ll need to declare a void pointer for each outlet. We’ve created two outlets in our example here, simply for the sake of having more than one.

Telling Max about our methods

We’re actually fairly far along in our analysis. Following our typedef, we have prototype declarations for the methods we’ll implement after our main() function.

Screen Shot 2015-12-13 at 4.10.01 PM

Figure 4. Prototypes

Declaring the prototypes is our way of telling the compiler about the methods and appropriate arguments it will encounter before the method’s actual definition. We could put our implementation above the main() function, but we’ll follow the convention here of having the prototypes, followed by main(), following by the method implementation. So in main(), we reference both bang_new() and bang_bang(); however, these methods are not been declared in ext.h and are not native to C, so when we reference them in main(), they don’t technically exist. (Your compiler may not care if you skip the prototype, but it’s strongly recommended that you include prototypes.) The prototypes provide a nice way for us to see what our object has implemented, or at least what we want to implement and what our method signatures will be.

The prototypes outline (but do not define) the methods that tell Max what to do. This implementation is in contrast to our method references in main() that inform Max where to find our methods.

So our constructor, bang_new(void), is a void pointer that takes a void as an argument. That method is defined as this:

Screen Shot 2015-12-13 at 4.11.21 PM

Figure 5. bang_new

Our constructor creates a pointer pointing to our typedef, calls newobject, sets up our outlets (bangout15 ) and returns.We’ll let Zicarelli himself explain newobject:

You call newobject when creating an instance of your class in your creation function. newobject allocates the proper amount of memory for an object of your class and installs a pointer to your class in the object, so that it can respond with your class’s methods if it receives a message.

[Zicarelli, Writing External Objects for Max 4.0 and MSP 2.0, 35]

Our call to newobject refers to this_class. Earlier, we defined this_class as this:

Screen Shot 2015-12-13 at 4.15.02 PM

Figure 6. this_class

In our constructor, bang_new, we’re doing two things: we’re creating an instance of our class, declared as t_bang (and sending it to newobject()), and creating pointers to our outlets. Our outlets send out bangs. They send bangs by calling bangout().

Our constructor is done. Lastly, bang_bang will take our struct as an argument and bind its outlets to outlet_b. outlet_bang, as the name implies, simply sends a bang out the bound outlets.

4 Recap

That’s a lot of information, especially if you’re new to writing externs or programming more generallyScreen Shot 2015-12-13 at 4.16.49 PM. This does cover the framework for creating our extern. If your extern is going to do some sort of machinations to output some value based on a bang, the structure of your extern is not going to differ much from what you see here. For the sake of review, look over the code below again with a brief explanation of each part.

5 Going Forward

The functionality we’ve provided with our extern is certainly nothing you need an extern to do. We’ve received a bang and output a bang. If you can put this code in your favorite editor, compile it and deploy it, you’re well on your way to writing more complex externs. The goal here is to show the structure of an extern and to better understand what’s happening. There are tradeoffs in choosing any language – in terms of creating externs for Max, we have many choices and C is one of them. There are a variety of externs available at the Cycling ’74 website. A quick survey of those externs will show the breadth of what is possible and may give you ideas for some great extern of your own.

Acknowledgements

Howard Sandroff, professor – Music, University of Chicago

Mark Shacklette, adjunct professor – CSSP, University of Chicago References

Dobrian, Chris. Max: Tutorials and Topics. San Francisco: Cycling ’74, 2000. Cycling ’74. 31 Dec. 2005 .

Fujinaga, Ichiro. “Advanced Multimedia Development.” www.music.mcgill.ca. McGill University. 31 Dec. 2005 .
Zicarelli, David. MAX: Writing External Objects for Max and MSP. San Francisco: Cycling ’74, 2005. Max/MSP Software Development Kit (SDK) for Macintosh. 31 Dec. 2005 .

Feature Photo by Kevin Ku from Pexels