BeepSex: TranceVibrator Patch for Max/MSP
BeepSex: TranceVibrator Patch for Max/MSP
By qDot

Thanks to Ganucheau for poking me into playing with this in the first place.
1. Beepy Shit
2. Max/What?
3. Porting the TranceVibe to C
4. Writing the Patch
5. Connecting it All Together
6. Towards More Entertaining Beepy Shit Shows
Mmmmm lordy, do I love the beepy shit. Most of the music I listen to these days can be defined as such. I've moved beyond instruments, beyond vocals, to the point where I can be completely happy listening to something that most people would mistake for a broken CD player being fisted by angry robots. It's with that interest in mind that I'm starting up the BeepSex portion of Slashdong.
Now, I'm assuming many of the readers of this page are familiar with techno, electronica, glitch, IDM, or whatever the hell else you want to call it. If not, welcome to the world of good music, you fucking luddite. Put that neandrathal acoustic guitar away and pick up a sequencer, 'cause you're on the bullet train to modern elitest, obscure, inaccessible music!
Seriously, if you aren't familiar with types of electronic music and actually care to read up, the best place to go is Ishkur's Guide to Electronic Music. It's a nice overview of all of the hojillion genres available in electronic music today. Most of the sarcastic comments in these entries will refer to the Glitch and IDM genres, as that's what I know more than you about.

So, why have a section of a sex tech website dedicated to audio software interfacing? Simple. Ever been to an IDM show? Boring as shit, ain't it? One, maybe two guys, a ton of laptops and racks, and zero performance value. Everyone nods asynchronously to what THEY believe is the proper time signature (music quality is judged by the number of head-nodding patterns observed in the audience, more is better, as it shows that there are multiple interpretations of the white noise music happening), possibly some side to side movement of the performers. Add a turntable and DJ to the mix, and it's fucking christmas for those of us brave enough to leave our bedrooms and mailing list arguments long enough to go to a tiny, tiny, tiny room to see the show.
In other words, the majority of electronic shows blow. Bigtime.
BeepSex is an attempt to add a little bit of physical feedback to the music. During the original SeXBox articles period, we got quite a few emails from couples saying they enjoyed spending time together playing video games after building the SeXBox. Now, those significant others unfortunate enough to love someone who sits in front of a computer monitor for hours at a time fucking with waveforms when they could just as easily open their computer and kick it repeatedly while in close vicinity of a tape recorder can now be physically part of the grueling composition process.
I usually answer the question "What is Max/MSP, anyways?" with the answer "The shit. Totally."
Most people don't seem to like this answer very much.
Max/MSP is actually two things, so let's break it up.
Max is a visual programming language, created in 1986 as an environment for producing interactive music environments. In 1991, it was picked up by Opcode, and in 2000 changed hands to Cycling '74, who still owns it today.
The basic of Max are very, very simple. You have objects, and patch cables. Put the objects together, put patch cables in between them, and suddenly they can communicate to each other.

For example, the picture above is a very, very simple Max patch. The top object is a button. Whenever that button is pressed, it sends a "Bang" message across the patch cable to the Random object. When the Random object receives a Bang message, it generates a number between 0 and the argument given to it, in this case, 100. It then sends that number over the line to the Print object. The Print object prints the input received on the line to the Max Print Window. Eureka, we have a working Max Patch!
As you can see, programming in Max is very intuitive. No crazy syntax to remember (though value spread orders can get crazy, as they are dependant on the location of the object in the patch workspace), pictures you can drag instead of big boring text windows. Of course, what we just showed is rather simple. Actually, stupidly simple.

Real Max patches tend to look more like this (click the picture to see the fullsize version). That hurts my head.
So what does this have to do with music? That's where the MSP part comes in. MSP is a set of patches for audio construction and performance. Combined with the integrated MIDI functionality of Max, users can create mixers, software synths, and many other horribly complex things that boring violin players like me don't grok. There's also a patch set called Jitter that provides video manipulation patches. All of these patches can be used together to create complex audio/visual performance environments.
One of the great things about Max is the fact that you can load in External Objects. Using a freely available C SDK, you can write your own objects to insert directly into the Max workspace, meaning the development environment is almost infinitely extensible. And extend it we will!
Anyways, we'll let the artists make the pinko commie shit, we're here to engineer. Let's get to work.
3. Porting the TranceVibe to C
Our goal is to get a Windows Max object that will control a Rez TranceVibrator (Sorry Mac users, I swear I'll create a Mac version of the patch the second I get time to develop C TranceVibe code for the Mac). In a later article, we'll have it control a SexBox, but since there's a higher chance of people that playing with Max/MSP owning a Rez TranceVibrator, we're concentrating on that for the moment.
From the information in the earlier Rez TranceVibrator article here on Slashdong, we have C# source code and a driver DLL available. Since the DLL is in C, that means that C# is using basically the same calls a C program would to get to the juicy parts of the DLL. Yay for cross-language reusability!
You can skip this paragraph if you've already got your TranceVibrator working on your machine. Pick up the Trance Sharp Alpha utility. This has the INF and DLL file you'll need to use to install your TranceVibrator. Next, follow the instructions here on how to install the drivers for your TranceVibrator. Finally, assuming you've got the .Net Framework installed, run the TranceSharp program and make sure things vibrate.
Porting this to C is pretty simple. In fact, I'll just go ahead and list the source code here.
To compile the program, you'll need to link it with the uusbd.lib library in order to have the USB communications functions available. You can pick up the uusbd SDK by clicking here. To run the program, you'll need to have the uusbd DLL in either the same directory as the executable or in one of the designated DLL library paths.
- #include "uusbd.h"
- #include <cstdio>
- //This is actually a void pointer. I love C.
- HUSB husb;
- int SetPower(short val)
- {
- //If we don't have a handle to a device, return
- if ((int)husb == -1) return 0;
- //Else, just shove the given value over the pipe
- return Uusbd_VendorRequest(husb, false, 1, 1, val, 0, 0, (char)0);
- }
- int main(int argc, char** argv)
- {
- int ret;
- //Create the handle to the TranceVibe, by passing the
- //Vendor ID and Product ID to look for
- husb = Uusbd_Open_mask(1<<2 | 1<<3, 0, 0, 0x0B49, 0x064F, 0);;
- //If the device doesn't exist on the bus, die
- if(husb == INVALID_HANDLE_VALUE) {
- return 1;
- }
- //If we can't communicate with the device, die
- ret = Uusbd_Check(husb);
- if(ret != UU_CHECK_OK) {
- return 1;
- }
- //Else, set the power to the argument given, or 0 if
- //no argument
- if(argc >= 2) SetPower(atoi(argv[1]));
- else SetPower(0);
- return 0;
- }
The TranceVibrator wants a number between 0 and 255 to set the motor power with. So, for those of you that don't read C, this program takes a number from the command line, and feeds it to the TranceVibrator. If no number is passed, it just turns the TranceVibrator off. Please note that there's a ton of interesting and fun ways to crash the program, so don't go expecting to use it for everything, it's just a quick example to get this working in C.
Now that we have this working as a simple C program, we can start porting to the Max patch format. To do this, I gutted the plussz demo project that came with the Max/MSP SDK, divided up the code that we used in the prior program to get the TranceVibrator running, and pasted it to the proper functions in the patch code.
MaxTrance Patch Source Code
MaxTrance Patch Binaries
- //you must include this - it contains the external
- //object's link to available Max functions
- #include "ext.h"
- //USB Function header
- #include "uusbd.h"
- //defines our object's internal variables for
- //each instance in a patch
- typedef struct _maxtrance
- {
- // object header - ALL objects MUST begin with this...
- t_object p_ob;
- //int value - received from the left inlet
- //and stored internally for each object instance
- // In this case, this is the motor power value
- //recieved from another object
- long p_value0;
- } t_maxtrance;
- //define our power storage variable and USB handle
- long motor_power = 0;
- HUSB husb;
- //global pointer to the object class - so
- //max can reference the object
- void *maxtrance_class;
- // these are prototypes for the methods that are defined below
- void maxtrance_bang(t_maxtrance *x);
- void maxtrance_int(t_maxtrance *x, long n);
- void maxtrance_in1(t_maxtrance *x, long n);
- void maxtrance_assist(t_maxtrance *x, void *b, long m, long a, char *s);
- void *maxtrance_new(long n);
- int SetMotorPower(short val);
- //--------------------------------------------------------------------------
- void main(void)
- {
- setup((t_messlist **)&maxtrance_class, (method)maxtrance_new, 0L, (short)sizeof(t_maxtrance), 0L, A_DEFLONG, 0);
- // setup() loads our external into Max's memory so it can be used in a patch
- // maxtrance_new = object creation method defined below,
- //A_DEFLONG = its (optional) arguement is a long (32-bit) int
- // the method it uses when it gets a bang in the left inlet
- addbang((method)maxtrance_bang);
- //the method for an int in the left inlet (inlet 0)
- addint((method)maxtrance_int);
- //(optional) assistance method needs to be declared like this
- addmess((method)maxtrance_assist, "assist", A_CANT, 0);
- //post any important info to the max window when our object is loaded
- post("maxtrance object loaded...",0);
- }
- //--------------------------------------------------------------------------
- // x = reference to this instance of the object
- void maxtrance_bang(t_maxtrance *x)
- {
- //Sets the motor power to whatever we
- //got on the last Bang event
- SetMotorPower(motor_power);
- }
- //--------------------------------------------------------------------------
- // x = the instance of the object; n = the int received in the left inlet
- void maxtrance_int(t_maxtrance *x, long n)
- {
- motor_power = n;
- //Sets the motor power to whatever we
- //value we received
- SetMotorPower(motor_power);
- }
- //--------------------------------------------------------------------------
- //Function that defines the help text for the object
- //4 final arguments are always the same for the assistance method
- void maxtrance_assist(t_maxtrance *x, void *b, long m, long a, char *s)
- {
- if (m == ASSIST_OUTLET)
- sprintf(s,"Controls Motor Speed of the Trance Vibrator");
- else {
- switch (a) {
- case 0:
- sprintf(s,"Motor Speed");
- break;
- }
- }
- }
- //--------------------------------------------------------------------------
- //n = int argument typed into object box (A_DEFLONG)
- //defaults to 0 if no args are typed
- void *maxtrance_new(long n)
- {
- int ret;
- //local variable (pointer to a t_maxtrance data structure)
- t_maxtrance *x;
- //create a new instance of this object
- x = (t_maxtrance *)newobject(maxtrance_class);
- //set initial (default) left operand value
- //in the instance's data structure
- x->p_value0 = 0;
- //Setup the USB device, like we did in the first program
- husb = Uusbd_Open_mask(1<<2 | 1<<3, 0, 0, 0x0B49, 0x064F, 0);;
- if(husb == INVALID_HANDLE_VALUE) {
- post("ERROR: Uusbd.sys‚Cannot pick up device\n");
- return 0;
- }
- ret = Uusbd_Check(husb);
- if(ret != UU_CHECK_OK) {
- post("ERROR: Cannot check device?\n");
- return 0;
- }
- //Make sure the motor is off
- SetMotorPower(0x0);
- //post important info to the max window when new instance is created
- post(" new maxtrance object instance added to patch...",0);
- //return a reference to the object instance
- //Now Max is in charge of the object lifetime
- return(x);
- }
- //--------------------------------------------------------------------------
- //Function that sets the motor power
- int SetMotorPower(short val)
- {
- if (husb == -1) return 0;
- return Uusbd_VendorRequest(husb, false, 1, 1, val, 0, 0, (char)0);
- }
So, there's the code. Instead of taking our value from the command line input, we now take it from the bang event sent from whatever object is connected to the input of the MaxTrance event. Lots more work than just getting it from the command line, but it'll also be a lot cooler in the end, too. :)
Ok, now that we have the patch together, we need to add it to Max and set up a control environment. We put the .mxe file into the patches directory of the Max/MSP install, and then select "Install" from the File menu. Select the new patch in the install file dialog, and you're ready to go!
Here's a picture of the demo patch we used.

This is just a slider bar with the output connected to a print statement and the MaxTrance object. Every time the bar is changed, it sends a Bang event over the output, which prints the value of the slider bar, and sets the motor speed of the TranceVibrator.
That's it! Max/MSP is now a sex toy controller.
6. Towards More Entertaining Beepy Shit Shows
There is now no excuse for there to be boring musical performances. You can hook sex toys up to this shit, for christ sake, so just hire some porn model to get on stage and offset your geeky, knob twiddling ass with some hawt sex0rz. It doesn't matter if you play the shittiest speedcore ever heard by man, I can guarentee people will show up, they just may not remember the performance for the 1000bpm earfuck you think is music.
Oh yeah, and if someone could tell me where to pick up the "l33t ae trickz" patch, that'd be awesome.










