Updated music server
A few minutes of macro-writing and commenting and the new version stands at 266 lines, runs like lightning, and is extensible to boot. Hopefully the macros for building Applescript objects will be useful to someone else.
Here's the updated file; you now don't need the shell scripts.
Posted at 2005-02-04 10:21:56 by Richard • Link to Updated music serv…
, trackbacks.
Applescript vs. Cocoa
Ken Ferry mailed me about
my iTunes controller, wondering what the overhead was for using Applescript in my Lisp controller.
With a little experimentation I found that calling out to the shell added about 350ms to the runtime for each call, plus execution time. To refresh a page which interrogates iTunes for the current track, the current volume, and whether it was set to play on random or not would take well over a second just to call the scripts.
I decided to investigate further, and I've managed to get a massive speed boost (indeed, I now use the Web interface rather than my shell scripts!). As an example, to increase the volume this function was used:
(defun volume-up ()
(run-program "vu" ()) t)
Now, we close over a precompiled Applescript object, and provide a function to run it:
(defun make-volume-up ()
(let ((vu-event (make-instance 'ns:ns-apple-script
:init-with-source #@"tell application \"iTunes\"\
to set sound volume to (sound volume + 10)")))
(send vu-event :compile-and-return-error
(ccl::%null-ptr))
(defun volume-up ()
(send vu-event :execute-and-return-error
(ccl::%null-ptr)))))
The same approach is taken for the other functions, including those that return a value — in fact, we can call methods on the response to extract string or boolean values, which is better than relying on the string response from the shell. Page refreshes are now almost instantaneous.
One thing that I had to pay attention to: autorelease pools. We're creating objects in the script responses themselves, and these need to be in an autorelease pool to stop warnings. To do this, I wrapped each handler's body, and the calls to
make-volume-up &c, in
with-autorelease-pool macro calls.
I'll post the code when I get the chance, but there you have it: it's a lot quicker to construct
NSAppleScript objects and execute them than it is to escape to the shell and pass a string into
osascript. As with most things, though, it is also more effort. Pick your poison.
Posted at 2005-02-04 04:04:08 by Richard • Link to Applescript vs. Co…
, trackbacks.