Sunday, March 28, 2010

Pyglet: Audio Support

music technology articleI promised I would cover audio support in Pyglet, even though, when all is said and done, there is little to say. Support is quite rudimentary, though what is there works well. I was able to write a simple application on Windows 7, test it on LINUX and then install it for OS X without any bugs, code changes or even configuration issues. That is cross-platform programming as it should be. (Though I would accept the need for config changes to address hardware-specific issues.)

Audio and video playback is handled by the same package, pyglet.media, which automatically detects the media type and acts appropriately. As I mentioned in Pyglet: Helpful Tips, you will want to install the "optional" AVbin to support anything other than plain uncompressed formats.

Though you might want to refer to the API docs for all the details, I'll explain here how to set up sound playback. In brief, you use a Source instance to decode an audio file and then queue this on a Player for playback. By default this decoding is done on-the-fly as a StreamingSource. If you want a sound to be decoded in advance, you can designate it as a StaticSource. This is useful for short sound effects and the like. There's not much you can do with a source except read its duration.

A Player can be used to play, pause and restart a sound. You can get the current playback point and seek to a position in the source. There is support for pitch shifting and attenuation, but I did not try these. There is no time stretching, however, and even basic filtering or EQ is outside the realm of what this simple library is designed to do. I would like to see these features, as well as the ability to cross-fade sources, as this would provide commonly needed functionality.

Here is the basic code I used:

import pyglet

wavfile = 'some/path/to/file.wav'
sound = pyglet.media.load(wavfile)

core = pyglet.media.Player()
core.queue(sound)
core.play()


There is only one event provided for responding to audio, on_eos(), which triggers when the player has reached the end of the current source. It would be great to be able to set up triggers at other times (so one could have advanced notice of the approaching end of a file) and on other events (for example, pausing).

This library for sufficient for my simple case, but I would have to look at something more complete for more than the rudiments... a search that still continues!
Sunday, March 28, 2010

Interactivity As Entropic Prison

sound resonatorsound resonator

In this article I will move from specific observations relating to my sound installation "The Lights In Room 7" to generally applicable philosophical points regarding the interactive utopia many technophiles promote. I will over-simplify and pontificate, for what else is a blog for? [This version revised from initial publication.]

This article started from a need to clarify a point I made in the initial announcement of this piece. I wrote then that "those who come to the room will hear sounds that differ for each visit". But in doing so did not wish to imply, as some have assumed, that the piece is interactive in any way. Visitors will hear different sounds only because there is so much sound to hear, and because I do not expect anyone to stay for the entire duration.
Friday, March 26, 2010

Quiet Club photo published

The Quiet Club
This photo of the Quiet Club was published in the last issue of The Wire, to accompany their track listing on the cover CD. Buy the magazine to get lots of intriguing music and see a microscopically small version of this image!

Apparently the photos are so small the magazine did not see fit to credit me. Likewise, the selection from The Quiet Club is so abbreviated that it scarcely hints at what their work is really like.
Friday, March 12, 2010

"The Lights In Room 7" for EV+A 2010

lights

Now I can reveal what I have been busy with these last few weeks.

As part of the international exhibit "EV+A 2010: Matters", curator Elizabeth Hatz of Sweden commissioned me to produce a sound art installation. The location is the old art college building on George's Quay, Limerick, a space once used for the fashion and sculpture departments.

The exhibition opens today, Friday 12 March at 7pm with a ceremony at LSAD Gallery, Limerick School of Art & Design, Clare Street. It runs for 10 weeks, until Sunday 23 May, at many venues across Limerick. These include The Hunt Museum, Limerick County Hall, Thomond Park Stadium and the Absolute Hotel. A total of 58 artists are included. For more details visit the ev+a website.
Wednesday, March 10, 2010

Running Python Scripts on Mac OS X

[Warning! This is complete newbie information!]

One of the things I found difficult when first using Python on a Mac was simply getting my scripts to run as programmes, with a simple double-click. The nub of the problem is that one must run a script using the python interpreter, like so:
python script.py

This is easy enough to do in a command window, terminal window, at the shell prompt etc. (The terminology is different depending on the operating system, but the reality is the same.)

On Windows I would write a one-line batch file containing the command above. This could be then be treated in all ways like a self-contained application. Simple.

I had difficulty making anything like this work on Mac OS X until I did the following three things:

1. Make the script executable:
chmod a+x

2. Ensure the first line in the script is a "shebang line", telling it where to find the interpreter:
#!/usr/bin/env python

Er, hold on, that looks correct for LINUX but not the Mac. Anyway, be sure to put in the proper path!

3. Associate the script file with PythonLauncher. One does this by right-clicking (option-click) the script, selecting "open with", and then finding this programme.

In my case I had difficulties because the first PythonLauncher to be available in the menu was actually for an older Python version. It is quite common on the Mac and LINUX for there to be multiple versions of Python. This is because the operating systems come with one installed, and it is often best to leave that in situ so that any system tools that need it can still use it properly. But one inevitably wants to upgrade to the latest greatest version. The solution is to install this in parallel.

I had my script running with Python 2.3 when it needed 2.6. I got no error or indeed any feedback that something was wrong. This took me a while to figure out!

I had a second big problem, but that will wait for my next article.
Wednesday, March 10, 2010

Open Letter To Ken Rockwell

Hey Ken:

In your "review" of the Pentax 645D you come across as a right old sour-puss who can't even get his facts straight. So I'm writing you this open letter in an attempt to penetrate your smug armour.

Several times you mention the "small" sensor as a problem, apparently not aware that the 645D has a similar crop to the other digital 645 bodies out there, 80% as large as film 645.

So why is Pentax worse?
Wednesday, March 10, 2010

Pentax 645 Digital No Myth - It's Here!

Some of you scoffed when I wrote that the Pentax 645 Digital was On The Horizon, not being able to read the signs that denoted the difference between project development and product release. But those folk can be forgiven their scepticism, as it has certainly been a long road for those waiting for a medium format digital camera from Pentax. Now it is here, I can only image what the ripples are going to be like in the little pond of photographers that need and care about MF.

Units are due on the Japanese market in May, at a price that converts to US$9400. Depending on if and when the camera comes to Europe and North America, that could be a breakthrough price. After all, this is a 40MP (7264 x 5440) camera with a 44x33mm sensor, significantly larger than full-frame. (This spec different from that in my prediction article.)

Just to compare, the Mamiya DM40 and Hasselblad H4D-40 are both twice that price.
Monday, March 08, 2010

Pyglet: Helpful Tips

In my last article I introduced Pyglet, a small and elegant cross-platform library that implements OpenGL, 2D sprites and a complete windowing interface in minimal Python code. In this article I will outline a few issues I had setting up the library. I hope that in this way I will save others time and headache.

These issues came about due to the fact I am running a 64-bit version of Windows 7. It seems that many programmes are still not ready for 64-bit operating systems, and if they are it can still be quite confusing getting and installing the correct versions.

To start with, the Pyglet download page makes available a Windows installer in MSI format. This failed to find my Python installation. Apparently this is a common issue; the solutions I found online involved copying registry entries from one place to another. Unfortunately the specific entries mentioned were not to be found on my system, so I abandoned this approach.

A simpler solution was to grab the source distribution and run "python setup.py install" to do all the work.

This appeared to do the trick, but the example applications I tried failed with various errors. Then I resorted to the test suite (very nice that one is included) and this could not even create a window. Houston, we have a problem!

From the support group I determined that Pyglet supports 64-bit Windows but does not support 64-bit Python. You need to have 32-bit Python running on 64-bit Windows to use Pyglet. With the correct version of Python 2.6.4 installed, everything went fine. It sure would be nice if somewhere, in the install docs or FAQ or on the download page, this was mentioned.

My second issue had to do with the declaration on the homepage that Pyglet has "No external dependencies or installation requirements". We have just seen that the last part of this is not true, but neither is the first part, in any real sense. A couple sentences later we find out that "pyglet can optionally use AVbin to play back audio formats such as MP3, OGG/Vorbis and WMA, and video formats such as DivX, MPEG-2, H.264, WMV and Xvid".

What is going on here is a matter of expectation. Other Python graphics toolkits have one or more external dependencies that require installing or compiling third-party libraries. Sometimes this can be quite an involved process. Further, these dependent libraries are not always free or open source. So long as one is using only uncompressed media, Pyglet is free from these dependencies. So, relative to other windowing libraries, this is in fact a Pyglet advantage.

However, to do any real work one will soon need to support some of the common compressed file formats and codecs that AVbin gives access to. (It does so by wrapping the extensive FFmpeg library.)

The AVbin site has one download for Windows, a file named "avbin-win32-5.zip". Hmmm.... does this mean it will not work on 64-bit Windows? I thought I'd give it a try. The ZIP contains only a readme and a DLL file. The former says to place the latter in your "\windows\system32" folder. I did this but applications that require AVbin still failed to work.

Pyglet has a Google Group to provide support. It averages about 150 messages a month. It is easy to get spoiled by groups that provide six answers within 3 hours; this is not one of those, so patience is required. My first query was answered in 12 hours, so I dashed off another request for information. This time it took 24 hours before I was told I would need to put the DLL in my "WOW64" folder. I found the similarly named "\windows\SysWOW64" folder. I put the DLL there and it worked perfectly.

The lesson to be learned is that if you want a 32-bit DLL to work in Windows 7 64-bit then put the file in SysWOW64.

There are two things that should be improved here. First, the zip file should be named in a way that makes it clear that it will in fact work on win64. Second, the readme needs more complete installation instructions.

Getting back to Pyglet itself, it would be marvellous if the correct version of the DLL could be included with the installation, saving a step and making the programme truly self-contained. (Actually, this is in fact the case for the full installer version, but not the manual process I needed to use.)

Better yet would be if AVbin could be dynamically linked as a Python library (a PYD file). This would have the distinct advantage of being loadable from elsewhere in the file system. No mucking about with Windows folders would be necessary and it would then be easier to distribute finished applications to clients.

Does someone want to create a PYD from AVbin? I have no idea what that entails. But it would be a real boon!

(I think that one disadvantage is that PYD files are specific to Python versions. This creates a maintenance issue.)
Sunday, March 07, 2010

Pyglet: A Python Gaming Library.

In a previous article I noted the difficulty in finding a complete, well-documented and active audio library for Python. That was two and a half years ago, but the situation does not seem to have improved. Many of the libraries are moribund or have no developer community. Hardcore coders can piece together what to do from doc strings embedded in the libraries themselves, but the rest of us are left waiting.

One of the anonymous comments on that article mentioned Pyglet. In this series of articles I will provide an overview of that library with a special look at its audio facilities. I will highlight any limitations I have come across in the short time I have been working with it. My viewpoint is that of the casual programmer who wants to pick up a tool and get work done. I do not code every day or for its own sake, but to get real tasks accomplished efficiently in the real world. That is one of the reasons I love Python; even after a year away all the syntax comes readily back to mind. My goal is to find tools that are equally efficient.

You can tell a lot about a tool from its website. The Pyglet site provides detailed API documentation and a handy walk-through guide. Sample applications come with the install. This makes it a lot easier to get started than with many other small tools. (As far as I can tell, Pyglet is the work of a single developer.) However, the FAQ is minimal and many "before sales" questions are not answered, especially those concerning scope and limitations. I find this common enough for developer tools, though it is frustrating. Why would I choose Pyglet over other tools? When would I not want to use it? These are the questions a website should answer simply.

I will say from the beginning that Pyglet has only minimal audio facilities. There is nothing in the way of signal processing, audio effects or algorithmic composition. But as a quick way to play back existing audio in a nice interface, it might be just the ticket.

But now, on to the library!

Pyglet is a game development library for Python that supports Windows, Mac OS X and LINUX. In this day and age I treat those as a minimum target. As a test I will be developing a simple app on Windows 7 64-bit for testing on LINUX and distribution on a Mac mini. This is not an arbitrary test; these are the real-world requirements of the programme, dictated by the availability of computers at my disposal.

Pyglet includes a windowing interface library along with keyboard and mouse detection. Text output can be formatted using a subset of HTML (which does not support CSS, however) or Pyglet-specific markup (about which I could find little). You can even work with fonts and glyphs at a primitive level if you need to design your own.

Images can be read from files or file-like objects, so you can easily store your programme resources in an archive, for instance. In fact the module "image.atlas" provides special support for image bins. A full image or some part thereof can be displayed and transformed within a particular view-port or projection. Images have full sprite control (position, scale and rotation). The demo applications include a convincing clone of the classic Asteroids game.

Pyglet is notable for supporting a complete OpenGL and GLU functionality set, including basic graphics primitives. I am certainly in no position to verify this claim but it seems that anyone familiar with OpenGL can get right to work.

A clock module provides not only scheduled events at specific time slices, but can calculate or limit the frame rate of your application.

Some time has been spent solving common application development problems. For example the "resource" module handles locating data files relative to the application root. Everyone coding in Python ends up writing something similar, but it's good to see the application framework support it.

Without further ado, here is the canonical Hello World programme, taken from the examples provided.

import pyglet

window = pyglet.window.Window()
label = pyglet.text.Label('Hello, world',
    font_name='Times New Roman',
    font_size=36,
    x=window.width//2, y=window.height//2,
    anchor_x='center', anchor_y='center')

@window.event
def on_draw():
  window.clear()
  label.draw()

pyglet.app.run()

We first define a window instance and a label instance. The "@window.event" decorator provides an easy way to modify the class methods, in this case the "on_draw" event. The "app" module hides the application event loop in a single line of code.

And that is all! I don't think I have ever seen a simpler windowing application framework.

This should whet your appetite for what seems to be an uncommonly useful little library. In the second article I will look at some of the configuration "gotchas" I referred to above.
Thursday, March 04, 2010

just stopping in to dust the shelves

Don't forget I am still very active over on Theatre of Noise, even if this site has been moribund for a year. I'd like to tell you I've been spending my time researching Quantum Computing, but the truth is even more fantastic... I've been taking photographs and composing music.

I also took a year to get my Masters. This in fact did involve a significant amount of programming but I was too busy getting grades to write here.

Maybe later.
Wednesday, March 03, 2010

Cirque de Céramique

lighting grid

I don't always have the time to get out to all the openings I'd like. But sometimes I'm really glad I do. Case in point: This week's show of works from third and fourth year students at the Limerick School of Art & Design. Cirque de Céramique features finished works and ideas in progress. The results cover the widest range of techniques and forms, from more-or-less traditional pottery to decorative items and even wearable art.

You only have until Friday 5 March to get out and see this exceptional show. There's a catalogue to purchase so you need not be content with my snapshots.
Wednesday, March 03, 2010

Chanting Out The Pantheon

Paul Henderson.

There. I just divided my readership into two groups. Those who know what that name means and those who don't. It's like a talisman, a divining rod for determining who is Canadian.

There's something about Canada and hockey that cannot fail to stir the spirit, to inspire, to unleash all manner of poetic clichés. It's hard to express unless you've been at a Junior A game in a small town somewhere in the back of beyond, unless you've seen children barely old enough to walk being urged across the ice in skates, unless you've been in a crowd when the home team wins a big game. Yes, sport is the opiate of the masses, fuelling disagreeable tribal urges and distracting money and attention from more important issues. But still: Canada. Hockey. Beer. Life. Inextricably bound, one to another.