Sept. 26, 2010

CanOfBeats running on Android

There's a good reason I haven't been posting many squeakyshoecore tunes lately, or making much progress on my video game Infinite8BitPlatformer. I've been hacking hard in my spare time, and the good news is that CanOfBeats, my algorithmic hiphop beat generator, is now available for Android phones and devices! So if you are seeking beats and you rock an Android phone, help an indie developer out and get yrself a copy from the Android Market.

Enjoy!

Sept. 23, 2010

Android music panel 1

Android music panel 2

Android music panel 3

Android music panel 4

Hope you enjoyed these drawings of my ultimate music-making dream setup. My apologies to anyone using a screen reader.

Sept. 12, 2010

Hello!

Here is the build script which I use for deploying my apps such as Infinite8BitPlatformer on Windows and OSX. I have used it to build both Pygame and wxWindows apps in the past. "Cross platform" might be a bit of a misnomer; you need to run it on the environment you are targetting (e.g. be on Windows to build for Windows) and have the correct environment, libraries etc. installed, but the same script should work on both platforms.

For notes about installing Python libraries into somewhere other than the default Python root directory, see this earlier post.

Please pay attention to the comments marked NOTE.

### Cross platform (win32, mac) build script
### By Chris McCormick <chris@mccormick.cx>
### This has worked with pygame and wx
### This script is public domain

from setuptools import setup
from sys import platform, argv
import os
from shutil import rmtree, copytree
import zipfile

# NOTE: you may want to change these next few lines to set these values manuall
# get the current bzr version number of this build
from bzrlib.branch import Branch
revno = Branch.open(".").revno()
# get the name of the project/app from the name of the current directory
app = os.path.basename(os.getcwd())

# remove the build and dist directories
def clean():
    print "Removing build and dist directories"
    for d in ["build", "dist"]:
        if os.path.isdir(d):
            rmtree(d)

clean()

# the default os string and extension for each platform
platforms = {
    "darwin": ("osx", ".app", "dist/" + app + ".app/Contents/Resources"),
    "win32": ("windows", "", "dist"),
}

# more convenient representation of the platform config
config = {
    "os": platforms[platform][0],
    "extension": platforms[platform][1],
    "resources": platforms[platform][2],
    }

# NOTE: this is optional, you might want to remove this bit
# output the correct VERSION file for this build
print "Writing VERSION file"
version_file = file(os.path.join("resources", "VERSION"), "w")
version_file.write("%s\n%s\n%s\n" % (revno, config["os"], config["extension"] + ".zip"))
version_file.close()

### PLATFORM SPECIFIC SECTION ###

# mac osx
if platform == "darwin":
    # add mac specific options
    options = {
        # NOTE: you may want to put other libraries in here, such as wx for wxWindows apps
        # some libraries need forcing
        'includes': ['simplejson', 'pygame'],
        'resources': ['resources',],
        'argv_emulation': True,
        'iconfile': 'resources/icon.icns',
        'semi_standalone': False,
    }

    # force the py2app build
    argv.insert(1, "py2app")

    # setup for mac .app (does the actual build)
    setup(
        setup_requires=['py2app'],
        app=[app + ".py"],
        options={'py2app': options},
    )
elif platform == "win32":
    import py2exe

    # hack to include simplejson egg in the build
    import pkg_resources
    # NOTE: this bit is manually copying the simplejson egg into the current directory
    # you may want to manually import other libraries here
    # some libraries need forcing like this
    eggs = pkg_resources.require("simplejson")
    from setuptools.archive_util import unpack_archive
    for egg in eggs:
        if os.path.isdir(egg.location):
            copytree(egg.location, ".")
        else:
            unpack_archive(egg.location, ".")
            rmtree("EGG-INFO")

    # windows specific options
    options = {
        "script": app + ".py",
        # NOTE: assumes your icon is in a folder called resources and is called 'main.ico'
        "icon_resources": [(1, os.path.join("resources", "main.ico"))],
    }   
    resources = ['resources',]

    # force the py2exe build
    argv.insert(1, "py2exe")

    # setup for windows .exe (does the actual build)
    setup(
        setup_requires = ['py2exe'],
        windows=[options],
    )

    # manually copy resources as I couldn't get it to happen with py2exe
    for r in resources:
        print 'Copying resource "%s"' % r
        copytree(r, os.path.join("dist", r))

    # get rid of simplejson directory
    # NOTE: if you manually forced other libraries above you'll probably want to remove them here
    rmtree("simplejson")

### PLATFORM SECTION DONE ###

# zip up our app to the correctly named zipfile
def recursive_zip(zipf, directory, root=None):
    if not root:
        root = os.path.basename(directory)
    list = os.listdir(directory)
    for file in list:
        realpath = os.path.join(directory, file)
        arcpath = os.path.join(root, file)
        print "Zipping:", arcpath
        if os.path.isfile(realpath):
            zipf.write(realpath, arcpath)
        elif os.path.isdir(realpath):
            recursive_zip(zipf, realpath, arcpath)

outfilename = "%s-%d-%s%s.zip" % (app, revno, config["os"], config["extension"])
zipout = zipfile.ZipFile(outfilename, "w")
recursive_zip(zipout, os.path.join("dist", platform == "darwin" and app + config["extension"] or ""))
zipout.close()

# clean up afterwards
clean()

# output the build-finished message
print "--- done ---"
print "Created %s" % outfilename

You should probably use Esky instead of this script.

Aug. 25, 2010

squeakyshoecore

I finished this new tune a few days ago but I'm only just getting around to releasing it. Go to the squeakyshoecore page and click song five to hear it.

Here are the Pure Data patches used to create this music.

Aug. 20, 2010

Updates: see below for a link to a post about this same topic on Nick's blog, a link to more raw numbers on overstayers vs. refugees arriving by boat, and a video by GetUp on this topic.

I don't often get political on here, but watching the Australian Liberal party trot out the "we will stop the boats" line, referring to trying to stop people seeking refugee status in Australia who arrive by boat, has annoyed me enough to write something about it.

The Liberal party have obviously seen the numbers. They know that people arriving on boats seeking refugee status are statistically insignificant. This is basically a cynical political stunt by that party, designed to prey on a deep-seated "rational racism" found in modern Australian culture. Essentially they are taking some of the most powerless and unfortunate people in the world, turning them into boogie men, and then telling the Australian population that they will protect us against them. Heck, I'm going to say it; it's just plain un-Australian!

Why?

  1. As a member state of the United Nations, we are shirking our obligations to the United Nations under international law. We derive huge benefits from being part of the United Nations and we should meet our obligations in return. "Stop the boats," is quite possibly illegal in that context. See this article for an example of UN HCR's reaction to Australia refusing entry to refugees in 2003.

  2. The number of people arriving by boat is statistically insignificant, especially when compared with:

    • The number of people arriving by air and staying here illegally.
    • The number of refugees arriving to other nations, to European nations for example.
    • The total population of Australia.
  3. Finally, and most damningly, Australia's political policy on refugees and immigration has no demonstrable effect on the numbers of people arriving regardless. The number of people arriving are determined by external factors (like hostilities in Afghanistan; a war in which Australia is involved). See this article for details and a thorough statistical analysis.

In other words, if we wanted to regulate refugee immigration to Australia more tightly (a desire of debatable value), then we shouldn't focus on boat people at all. In that case, the rational thing to do would be to focus on our contribution to situations outside of Australia that cause people to want to seek refugee status here, such as wars, disasters, etc. Focusing on "boat people" is irrational at best, and racist at worst.

I will never vote for a party who will capitalise so cynically on, and in doing so advocate, such an awful cultural trait as the racist reflex we are witnessing. Surely we are smarter than that, Australia? Surely we can see through this kind of hateful scaremongering?

Because of this, I will put the candidates of the liberal party very last on my ballot paper on the 21st August, 2010.

Update: Here are some useful links with statistics:

"Boat arrivals since 1976 by calendar year"

"Australian Prime Ministers Since 1901"

I hope you'll notice something deeply ironic when you look at these links. The year with the highest number of refugees arriving by boat is 2001, which was smack bang in the middle of the term of John Winston Howard of the Liberal party.

Update #2

After writing this I suddenly realised that I'd read a post on exactly the same topic on Nick's blog, and forgotten about it. He makes some great points, and has done much more in-depth research into the legality of this under international law. Check it out.

Also, Moose sent me a couple of great links:

Voting is tommorrow here in Australia. If you are reading this before the election, I hope you bear this issue, and the stances of the major parties, in mind when voting.