Skip to content

PureData: iemguts for darwin

2010 August 19
tags:
by Tedb0t

Here’s a binary of the iemguts externals for Puredata built for x86 Darwin.  For future reference, all you have to do to build this from source is “make pd_darwin”.  To use it, unpack the zip to ~/Library/Pd/iemguts.  You can then start or restart Pd and get the objects like [iemguts/canvasconnections].

  • Share/Bookmark

The Rare Book Room

2010 August 17
by Tedb0t

Here’s a bit of a blast from the past:

http://www.epiphanus.net/rarebookroom/

The Rare Book Room is a collection of my drawings, paintings and sketches from the past 8 or so years of notebooks.  Enjoy, and let me know what you think!  Perhaps I’ll get a chance to update it with my more recent books ;)

  • Share/Bookmark

POSTing a ByteArray from Flash to Web.py

2010 August 16
by Tedb0t

…turns out to be really straightforward using the web.data() method (thanks to Brian for the heads-up!):

Flash code—for this example you’ll need the AS3CoreLib JPGEncoder class:

_video = new Video(640, 480);
_camera = Camera.getCamera();
_camera.setMode(640, 480, 30);
_video.attachCamera(_camera);
addChild(_video);

_jpegEncoder = new JPGEncoder(60);

_urlReq = new URLRequest();
_urlReq.url = "http://localhost:8080/addImage";
_urlReq.method = URLRequestMethod.POST;

_urlLoader = new URLLoader();

_snapShot = new BitmapData(_camera.width, _camera.height);
_snapShot.draw(_video);
_snapShotImage = new Bitmap(_snapShot);
var jpgStream:ByteArray = _jpegEncoder.encode(_snapShot);
_urlReq.data = jpgStream;

try {
	_urlLoader.load(_urlReq);
} catch (e:Error) {
	trace("Remote.request caught error: "+e);
}

And the Python (using web.py):

import web

urls = (
  '/addImage', 'addImage'
)

app = web.application(urls, globals())

class addImage:
    def POST(self):
        data = web.data()
        f = open("test.jpg", 'wb')
        f.write(data)

if __name__ == "__main__": app.run()

That’s it!

  • Share/Bookmark

How to Enable Flash Debug Player 10 Logging

2010 August 16
by Tedb0t

What’s the fastest, easiest way to debug remote Flash apps?  Adobe’s own log file: flashlog.txt.  Here’s how on OSX:

  1. Download the Flash Debug Player from Adobe (you want the “Plugin content debugger”).
  2.  
    cd /Library/Application\ Support/Macromedia
  3.  
    echo ErrorReportingEnable=1 > mm.cfg && echo TraceOutputFileEnable=1 >> mm.cfg
  4.  
    tail -f ~/Library/Preferences/Macromedia/Flash\ Player/Logs/flashlog.txt

Bam.  The funny part is, you’ll get trace messages from any and all Flash apps that run on your computer, so you get to see how terribly executed many Flash web apps are.  All the paths for various operating systems are listed here.

  • Share/Bookmark

Running Python on your OSX Apache server: mod_python

2010 August 8
by Tedb0t

Want to interpret Python scripts in Apache on your OSX installation?  Look no further!

After about 4 hours of repeated head-to-wall collisions, I finally managed to get mod_python running with Apache 2.2.14 on my Snow Leopard machine.  Here’s what I had to do:

  1. Use the MacPorts Apache instead of MAMP.  I absolutely could not get this to work for MAMP, which might be because MAMP uses version 2.062 of Apache.  All the following instructions are for MacPorts installs.  Once you install MacPorts, you can install Apache by doing
    sudo port install apache
  2. Now you need mod_python, which is a module for Apache that allows the HTTP server to use the python interpreter “inside” the server.  With MacPorts, just do
    sudo port install mod_python

    If for some reason this doesn’t work, I’ve packaged it up along with the mod_python python package described next.  Put it in

    /opt/local/apache2/modules
  3. Make sure you have the mod_python Python package (yeah, it’s got the exact same name as the Apache module but is a completely different thing).  Get into your Python interpreter and try
    import mod_python

    If it works, rejoice.  If not, I’ve included mine in a zip because I could not for the life of me figure out where to get it from, but I had it in one of my other Python installs. It goes here:

    /Library/Python/2.6/site-packages
  4. Edit your httpd.conf file by adding the following:
    LoadModule python_module modules/mod_python.so
    
    SetHandler mod_python
    PythonHandler mod_python.publisher
    PythonDebug On

    This first tells Apache to load the module, which is a shared object file (.so).  Technical note for the curious: A shared object is a binary that contains compiled functions that can be directly addressed in memory, so you can call functions in it given a header file.  It’s similar to a Windows .dll.

    Anyway, the rest tells Apache to use mod_python’s VERY handy “publisher” function, described here.  This is a REALLY fast and easy way to start writing Python programs for the web.  Follow the examples there and you should be good to go!  Enjoy!

  • Share/Bookmark

PuréeData: Realtime Collaborative Patching

2010 July 30
by Tedb0t

PuréeData is a browser-based PureData interface for a remote, central server that allows live, collaborative patching for anyone, anywhere.

Using Pd’s internal messaging system and an accompanying python script, PureéData allows anyone with a browser to modify a public, shared patch running on a server and listen to the results live over an OGG audio stream.

The project is currently in development and is freely available on GitHub.  PureéData is in part adapted from code by Jeraman.

  • Share/Bookmark

Phrygian Étude for Distributed Version Control

2010 July 29
by Tedb0t

The Phrygian Étude is a “chain letter” musical experiment in PureData that is composed of YOUR commits!  So fork the Étude, modify the patch (following certain rules), and push it back to us.  When the time is ripe, we will then play back each stage of the composition—commit by commit—as a live performance!

  • Share/Bookmark

Setting up Flash Builder 4

2010 July 13
by Tedb0t
Here are my tips for setting up Flash Builder 4 for maximum utility.
  • SVN: Subclipse
  • Minimize the package explorer and outline and use two panes for source files (see image)
  • Generate ASDoc HTML using External Tool
  • Use “Set as Default Application” on main source file so that you can use the run keyboard shortcut while focused on any file.
  • Use the Flash Debug Player to get traces in Flash Builder
  • I’m still searching for the best way to launch your swf in the Flash Debug Player instead of the browser.
  • Enjoy!
  • Share/Bookmark

Photoshop to Flash: Best Practices

2010 July 9
by Tedb0t

Building out a Flash interface from a PSD can be a time consuming process, so to make things most efficient, here are some handy guidelines for preparing Photoshop files.  Designers may want to duplicate their PSD and save it as a new file specifically for Flash import if they want to keep extra hidden layers, etc..

  • Turn off or delete all unused or irrelevant layers.
  • Merge all adjustment layers or masks into regular layers.  Masked layers or groups cannot be used!
  • Layer effects are OK!  However, if you turn one off and don’t plan on using it at all, make sure you remove the effect by dragging it onto the trash icon in the Layers palette.
  • Vector graphics are always preferred!  If you are using Illustrator to design any assets, please provide the Illustrator file too, as Flash cannot import Smart Vector Objects.
  • Vector graphics are especially preferred for layers intended to be animated.  Imported bitmaps will often look shoddy and low-resolution when moving around and rotating.
  • If an Illustrator file can’t be provided, rasterize any Smart Vector Objects or other non-standard layers.
  • Keep groups and layers orderly and named accurately whenever possible ;)
  • Share/Bookmark

AS3: Copying object properties to other objects

2010 July 2
tags: ,
by Tedb0t

Say you want to copy all the properties of an object to another object, but you can’t just assign it because they’re different types:

var requestVars:URLVariables = new URLVariables();
var myObject:Object = {prop1:"someValue"};
requestVars = myObject; // Throws type mismatch error

So you need to iterate through the properties of the source object and assign them to the target. You can do this with AS3′s array-like property access syntax:

for (var prop in myObject) requestVars[prop] = myObject[prop];
trace(requestVars.prop1); // prints "someValue"

Easy! Now sometimes you might need to do something similar with an XML file, say, a configuration file with a bunch of properties that you want to automatically assign to a local object:

var configXML:XML =
<configXML>
  <paths>
    <host>www.something.com/</host>
    <list>list</list>
    <recent>recent/</recent>
    <liked>liked/</liked>
  </paths>
</configXML>;

var paths:Object = new Object();

for each (var val in configXML.paths.*) paths[val.name()] = val;

trace(paths.host); // prints "www.something.com/"

You now have a plain Object instance with all the properties of the XML tree. Bing!

  • Share/Bookmark

Flash/AS3: Universal onMouseUpOutside solution

2010 June 28
tags: ,
by Tedb0t

As has been observed many times in the years since its debut, ActionScript 3.0 has no “onMouseUpOutside” event, meaning that if you press the mouse button down while over an object, move the mouse, then release the mouse button, that button will not generate a MOUSE_UP event.

This problem is not too hard to solve for a single object, in which case you can hard-code any callbacks you might need.  The problem becomes really complicated if you need to pass in arguments to the event handler, i.e. if you’re writing a function that automatically initializes an arbitrary object.

The solution to this is not elegant, not simple, and I’m not convinced it’s 100% perfect, but in practice so far it seems to work pretty well. This example initializes a display object that has a drop shadow and animates the mouse down state and calls a callback on release.

import flash.utils.Dictionary;

var _lastButton;
var _callbackDict = new Dictionary();

function initShadowButton(which:Object, callback){
	which.buttonMode = true;
	which.useHandCursor = true;

	which.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent){
		_buttonShadow = e.currentTarget.filters;
		_buttonShadowDistance = _buttonShadow[0].distance;
		e.currentTarget.filters = [];
		e.currentTarget.x += _buttonShadowDistance;
		e.currentTarget.y += _buttonShadowDistance;
		_lastButton = e.currentTarget;
		_callbackDict[_lastButton] = callback;

		stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpOutside);
	});
}

function onMouseUpOutside(e:MouseEvent){
	_lastButton.filters = _buttonShadow;
	_lastButton.x -= _buttonShadowDistance;
	_lastButton.y -= _buttonShadowDistance;
	stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUpOutside);
	_callbackDict[_lastButton](e);
}
  • Share/Bookmark

Flash Error #2078 with no code

2010 June 25
by Tedb0t

I was getting this error:

Error #2078: The name property of a Timeline-placed object cannot be modified.

…even though I had no code addressing any Timeline-placed objects. What gived? I was trying to give an instance name of “name” to the object. Change it and you’re good. Word to the wise!

  • Share/Bookmark

Signing PDFs in Acrobat with an image

2010 June 21
by Tedb0t

If you’re like me, you occasionally get emailed PDFs that need to be signed (with a written signature, not a fancy-schmancy digital certificate). It would be ridiculous to print it out, sign it, and scan it, so luckily there are more logical (and environmentally friendly!) alternatives.

First you’ll want to scan in your signature and make the background transparent in Photoshop or equivalent, and save it as a transparent GIF (I also save it as a transparent PNG). Keep in mind that, security wise, it is not a Good Idea to have your signature sitting around on your computer unless it’s encrypted. I still have to find a good solution for that.

If you have Adobe Acrobat Professional, select Tools > Advanced Editing > TouchUp Object Tool, then right click on your document and choose your GIF in the picker (for some reason Acrobat didn’t recognize my PNG), then resize it and place it! Easy!

  • Share/Bookmark

Understanding Namespaces by Analogy

2010 June 10
by Tedb0t

Namespaces (or “packages” in Java & ActionScript) are a programming concept that get important when you’re dealing with lots of different libraries and other code-sources.  Consider this analogy:

Every state in the U.S. has zero or one McDonald’s.   If you’re in a state with a McDonald’s, referring to that McDonald’s is easy, you just say “let’s go to McDonald’s” and everyone assumes you mean the one in your state.  But if your state doesn’t have a McDonald’s and you say that, which McDonald’s are you referring to?  Here’s what this looks like in code:

public class NewYork {
    public var mcDonalds;
}
public class NewJersey{
    // no McDonald's here!
}

Now if you’re instantiating objects, it’s a typical situation:

int main(){
    myState = new NewYork();
    neighborState = new NewJersey();

    myMcDs = myState.mcDonalds;
    goTo(myMcDs);
}

But if you’re dealing with static methods or properties of classes from a library, for instance, you’ve got to know the namespace:

namespace NewYork {
    public var mcDonalds;
}

namespace NewJersey {
    //...
}

int main(){
    goTo(NewYork::mcDonalds);
}
  • Share/Bookmark

Multithreading is not as hard as it sounds

2010 June 7
by Tedb0t

I’ve been finally forced to really learn about multithreading, and I’ve got some basic concepts down.  I sifted through a lot of articles and tutorials and I think this one is the best.  Here’s the scoop:

Threads do the actual execution in a process, and they can all access the same region of memory.  If you’ve got multiple threads, you don’t want one to try to read from a block of memory while another thread is in the middle of writing to it, so you can use something called a mutex (meaning “mutual exclusion”) object to control this.  A mutex gives your program a way of saying “only this thread is allowed to work until I say so,” so you can read or write the entire block of memory safely.  It’s as simple as that!  Here’s a Windows C++ example and a pseudocode example:

var theData
var myMutex = CreateMutex()

waitForMutex(myMutex)
writeTheData(theData)
releaseMutex(myMutex)

Seriously, that’s really all there is to it.  At first I thought you had to specify which thread you want to do the work but I was thinking of it backwards; mutexes say “whichever thread is going now, don’t stop it until I say so.”  Bing!

  • Share/Bookmark

A Short Primer on Developing C++ in Windows

2010 June 3
by Tedb0t

As I have been working on a new contract involving C++ development on Windows, I thought I’d share some of my findings that tripped me up initially. Leave a comment if you found it helpful or think of other questions!

  • There are two different programming languages, and concepts, at play on Windows: straight-up C++ and “managed” C++/CLI, which stands for “Common Language Infrastructure.”  You’ll know it’s managed C++ if you see things like
    Bitmap^ myBitmap = gcnew Bitmap;

    or

    public ref class

    That single caret took me a while to even find given that it doesn’t exist (except as a bitwise operator) in C++!

    The idea of managed C++ is to create a kind of garbage collection system for C++ (gcnew stands for “garbage collected new”), so the heap can track pointers, which normal C++ definitely cannot do.  A good place to start is here and here.

  • For this gig I’ve been developing a managed DLL wrapper between plain C++ and C#.  There is a good tutorial, but Microsoft’s documentation just leaves out some really helpful tidbits, such as this: if you’re writing a managed DLL, anything tagged as “public” is automatically exposed to other managed executables.  It’s confusing because their plain DLL tutorial tells you to use the
    __declspec(dllexport)

    tag before exported classes/methods, but for a managed DLL you don’t have to.  More confusingly, the DUMPBIN tool will not show any exported methods, but you can use them anyway.  WTF?  Oh well.

  • Speaking of DUMPBIN, here’s an incredibly handy tool if you have to have anything to do with DLLs:
    Dependency Walker
  • The logging system I ended up using is log4net, which is working great after a bit of bumpiness (they had typos in their example config files!)
  • Visual Studio is capable of using special comments to generate documentation, like so:
    /// <summary>This method does this...</summary>

    But then what?  You can use VS itself to generate XML files from those tags but there are also various documentation generators that use them.  Sandcastle looks like the best thing to use but so far it’s simple not compatible with Visual Studio 2010 solutions.  >:-|

  • Share/Bookmark

byteSlice()

2010 April 30
by Tedb0t

Here’s a weird little function I just wrote to “slice” an integer out of a byte:

int byteSlice(byte input, byte startIndex, byte endIndex){

  // generates an integer value from an arbitrary slice of a byte
  // Example:
  //
  // index:   01234567
  // input = B01101100 (int 108)
  //
  // startIndex = 1
  // endIndex = 4
  // slice = B1101
  // returns int 13

  byte output;

  // shift left to shave off bits before startIndex
  output = input << startIndex;
  // shift right to shave off bits after endIndex
  output = output >> (7-endIndex) + startIndex;

  return int(output);
}

This basically takes out a chunk of a byte and gives you the integer representation of its bits.  The input index byte datatypes are a neurotic memory optimization, since the indices can’t be greater than 7. ;) Example Arduino implementation:

void setup(){

  Serial.begin(9600);
  byte in = 108;

  Serial.print(in, DEC);
  Serial.print("\t");
  Serial.println(in, BIN);
  Serial.println("----------------");
  Serial.print(byteSlice(in, 0, 7), DEC);
  Serial.print("\t");
  Serial.println(byteSlice(in, 0, 7), BIN);
  Serial.println("----------------");
  Serial.print(byteSlice(in, 1, 4), DEC);
  Serial.print("\t");
  Serial.println(byteSlice(in, 1, 4), BIN);
  Serial.println("----------------");
  Serial.print(byteSlice(in, 3, 6), DEC);
  Serial.print("\t");
  Serial.println(byteSlice(in, 3, 6), BIN);
}

void loop(){
}
  • Share/Bookmark

Some thoughts on Jobs’ Thoughts on Flash

2010 April 29
by Tedb0t

Today Apple prominently published a statement about Flash and Apple’s stance on it.

This is really interesting and I’m glad to see a straight-up, public statement about the situation. It is clear that there are (at least) a host of technological issues behind the Flash absence. Pundit rebuttals about Apple not adopting such-and-such for business reasons have never made any sense—it would only behoove Apple to extend their market further and further, except at the cost of the UX and performance. It never ceases to amaze me that all the Flash-haters suddenly started bitching about Flash’s absence on iStuff just because they hate Apple more. Hypocrites.

Anyway, the third-party development thing is still foggy, I think. First of all, having gotten deep into the iPhone APIs and objective-c this semester, it is clear beyond any doubt that apple’s SDK cares foremost about consistent, effective UI and high performance. Anyone who disputes this simply does not know what they are talking about.

Jobs says:

We know from painful experience that letting a third party layer of software come between the platform and the developer ultimately results in sub-standard apps and hinders the enhancement and progress of the platform.

Defining “third party layer” can be tricky, but ok, sure, nobody wants sub-standard apps (meaning worse performance than it could have had otherwise).

If developers grow dependent on third party development libraries and tools, they can only take advantage of platform enhancements if and when the third party chooses to adopt the new features. We cannot be at the mercy of a third party deciding if and when they will make our enhancements available to our developers.

In general I’m inclined to agree here but then, the same argument could be made about a developer choosing to adopt changes in the native APIs in the first place. What he (and others) seems be saying here is that third-party dev platforms (again, not sure exactly what this includes and excludes) encourage laziness and are less likely to perform as well as native APIs. Maybe, at best.

Regarding cross-platform dev:

Hence developers only have access to the lowest common denominator set of features.

Maybe, though there’s no reason the platform couldn’t offer device-specific options that do follow up on new API developments.

It is not Adobe’s goal to help developers write the best iPhone, iPod and iPad apps.

Now that I definitely concur with. I can tell you from my own painful experience that the majority of Flash developers are total hacks who wouldn’t know a bit from a byte and couldn’t manage memory to save their lives. But who could blame them, since they’re encouraged to program that way? Indeed, the whole premise of Flash started out as, “Oh noes, programming is scary!! Help me to not have to learn!”

I can’t help but think this dances around a development ideology issue: cross-compiled, garbage-collecting, “lazy” development that is not geared towards optimizing for its device, and old-fashioned tweak-the-shit-out-of-this-app-until-it-can’t-possibly-get-any-faster. Yes, the latter is hard than the former. My question is, why the antagonism towards the latter?

Curious to hear some other thoughts on this.

  • Share/Bookmark

Converting a byte to an array and vice-versa

2010 April 18
by Tedb0t

Here are two super-useful Arduino utility functions I just devised for my thesis:

byte arrayToByte(int arr[], int len){
  // Convert -1 to 0 and pack the array into a byte
  int i;
  byte result = 0;

  for(i=len-1; i>=0; i--){
    if(arr[i] == -1){
      result &= ~(0 << i);
    } else {
      result |= (1 << i);
    }
  }
  return result;
}
int* byteToArray(byte in){
  int i, temp, out[8];

  for(i=0; i<8; i++){     temp = (in >> i) & 1;
    if(temp == 0) temp = -1;
    out[i] = temp;
  }
  return out;
}

The first function takes in an array of up to 8 integers valued 1 or -1 and generates a corresponding byte; the second does the reverse.  Easy to modify for other integer values.

  • Share/Bookmark

Implementing the Perceptron Rule

2010 April 17
by Tedb0t

A perceptron is one of the simplest forms of neural networks: a linear classifier.  It is a method of associating input patterns with output patterns, with the advantage that it is forgiving of noise in the input.

The network consists of an input and output layer (and optional “hidden” layers in between) with weighted connections between all of them.  To train a perceptron, you present an input pattern and the output pattern it should learn to output.  Then you step through each pair of neurons in each pair of layers and modify their weights with this equation:

∆wi = c (d – sign( ∑xiwi)) xi

…where wi is the ith weight (real-valued), c is the learning constant (i.e. 0.1), d is the desired output for this node (1 or -1), and xi is the input activation (1 or -1).  The input activation term indicates that the input node in question “contributes” to the output or “inhibits” it.  sign() is given by:

sign(x) = 1 if x ≥ 0, else -1

Here’s a C++ implementation from my Neuroduino Arduino library:

int Neuroduino::signThreshold(double sum){
	if (sum >= _net.Theta) {
		return 1;
	} else {
		return -1;
	}
}

double Neuroduino::weightedSum(int l, int node){
	// calculates input activation for a particular neuron
	int i;
	double currentWeight, sum = 0.0;

	for (i=0; i<_net.Layer[l-1]->Units; i++) {
		currentWeight = _net.Layer[l]->Weight[node][i];
		sum += currentWeight * _net.Layer[l-1]->Output[i];
	}

	return sum;
}

void Neuroduino::adjustWeights(int trainArray[]){
	int l,i,j;
	int in,out, error;
	int activation;	// for each "rightmost" node
	double delta;

	for (l=1; l<_numLayers; l++) {
		// cycle through each pair of nodes
		for (i=0; i<_net.Layer[l]->Units; i++) {
			// "rightmost" layer
			// calculate current activation of this output node
			activation = signThreshold(weightedSum(l,i));
			out = trainArray[i];	// correct activation
			error = out - activation;	// -2, 2, or 0

			for (j=0; j<_net.Layer[l-1]->Units; j++) {
				// "leftmost" layer

				in = _net.Layer[l-1]->Output[j];

				delta = _net.Eta * in * error;
				_net.Layer[l]->Weight[i][j] += delta;
			}
		}
	}
}

void Neuroduino::simulateNetwork(){
	/*****
	 Calculate activations of each output node
	 *****/
	int l,j;

	for (l=_numLayers-1; l>0; l--) {
		// step backwards through layers
		// TODO: this will only work for _numLayers = 2!
		for (j=0; j < _net.Layer[l]->Units; j++) {
			_output[j] = signThreshold(weightedSum(1, j));
		}
	}
}
  • Share/Bookmark