eMusic/J 0.25 released
First update in a while, just fixes to various things.
- Overhauled the filename cleaning stuff, hopefully finally fixing issues on windows. — found more filenames that windows dies on, so this deals with them. Hopefully that’s the last of them.
- If the option ’spacesToUnderscore’ is ‘true’ then spaces will be converted to underscores in filenames. — someone asked for this, and it was easy enough to do when working on the other stuff
- Handle the case where the emusicj script is a symlink to the real location, and use that to find the program directory — makes it nicer for people who lay their applications out in complex ways.
Extension to the ‘Shunting Yard’ algorithm to allow variable numbers of arguments to functions
Here’s something a bit more computer-sciencey than usual. For something at work, I have had to implement a function parser, so you can type ‘1+2*b‘ and it’ll work it all out, with correct operator precedence and so forth. To do this, I use a three-step process:
- Tokenise the input, and at the same time convert any variables found to their numeric values
- Convert the input tokens to RPN using the Shunting Yard algorithm
- Evaluate the RPN form of the equation using an RPN parser, which is really easy to write
This did the job nicely, however the time came when it had to be extended, and able to accept functions, such as ‘max(1,2,3)‘. The standard shunting yard algorithm can handle functions, but with the restriction that the number of arguments to them is known (really, this is a limitation of the RPN algorithm, but it’s at this point in the process that we need to deal with the problem). In this case, I wanted to handle functions with a variable number of arguments, so ‘max(1,2)‘ would work, and so would ‘max(1,2,3,4,5)‘. To do this, I extended the standard algorithm. Below is the algorithm from Wikipedia. My additions are in bold. This requires two more stacks, a ‘were values‘ stack, and an ‘arg count‘ stack. It also requires that you can attach the number of arguments to an instance of a function. In my case, I did it with a small class that took the function and an argument count, with one of these created during tokenisation for each function encountered.
- While there are tokens to be read:
-
- Read a token.
- If the token is a number, then add it to the output queue. If the were values stack has a value on it, pop it and push true.
- If the token is a function token, then push it onto the stack. Push 0 onto the arg count stack. If the were values stack has a value on it, pop it and push true. Push false onto were values.
- If the token is a function argument separator (e.g., a comma):
-
- Until the topmost element of the stack is a left parenthesis, pop the element onto the output queue. If no left parentheses are encountered, either the separator was misplaced or parentheses were mismatched. Pop were values into w. If w is true, pop arg count into a, increment a and push back into arg count. Push false into were values.
- If the token is an operator, o1, then:
-
- while there is an operator, o2, at the top of the stack, and either
-
-
- o1 is associative or left-associative and its precedence is less than (lower precedence) or equal to that of o2, or
- o1 is right-associative and its precedence is less than (lower precedence) that of o2,
- pop o2 off the stack, onto the output queue;
-
- push o1 onto the operator stack.
- If the token is a left parenthesis, then push it onto the stack.
- If the token is a right parenthesis:
-
- Until the token at the top of the stack is a left parenthesis, pop operators off the stack onto the output queue.
- Pop the left parenthesis from the stack, but not onto the output queue.
- If the token at the top of the stack is a function token
- Pop stack into f
- Pop arg count into a
- Pop were values into w
- If w is true, increment a
- Set the argument count of f to a
- Push f onto output queue
- If the stack runs out without finding a left parenthesis, then there are mismatched parentheses.
- When there are no more tokens to read:
-
- While there are still operator tokens in the stack:
-
- If the operator token on the top of the stack is a parenthesis, then there are mismatched parenthesis.
- Pop the operator onto the output queue.
- Exit.
Note that because I didn’t feel like correctly listifying most of it, consider an if to apply to the end of that sentence only. Operation order is usually important.
With this done, the part of the RPN algorithm that says:
It is known that the function takes n arguments.
can now be satisfied.
eMusic/J 0.24 released
This is a pretty small one, mostly just to fix a problem some people were having.
Changelog:
- Truncate the pathname to save files to if it gets too long on windows (which has stupidly low limits) Some classical albums have really long names, and there were some that couldn’t be downloaded as a result. This hopefully fixes the problem, although I haven’t tested it yet.
- Added option to allow the user to specify that they don’t want cover art to be downloaded. This is done by adding the line ‘downloadCoverArt=false’ to ~/.emusicj/emusicj.prop. Someone wanted this, I can’t remember why, but it was easy enough to do.
- Updated build.xml to allow more flexible compiles, such as not always creating a dist build Apparently some people are making distro packages of eMusic/J, and this makes life easier for them. Related to this, I’ve started posting the source code of each release on the site, too.
It can be downloaded here.
Kiwi Foo Camp 08
Yesterday I got back from a bit of a holiday in Auckland. The purpose of the trip was to go to Kiwi Foo Camp (a.k.a. Baa Camp). It is a gathering of 150 people with creative interests in various, generally technology related, things. It’s aim is to be a way for all these people to get together in a way the breaks down normal barriers of hierarchy so that they can share ideas, plots, and schemes without these getting in the way.
I met a bunch of people that I’ve heard about or only ever talked to via email, such as Don Christie and Peter Gutmann, along with a host of people I probably would have never heard of if they weren’t there but who are also doing interesting work in a variety of fields. A nice effect, which is by design, of the 150 people cap is that you have the ability to meet nearly everyone there. It also means they can put on free beer and wine for the entire event.
Almost everyone was sleeping on the school grounds where it was hosted, or nearby, which meant that things like game playing (Werewolf is a favourite) carried on to 4am, and people were happily getting up at 8am for breakfast in the morning. I was supposed to be sleeping in the Wharenui at the school, however due to getting to bed a little late and an apparent overbooking of it meant that I ended up sleeping outside on the deck of it the first evening. From what I could tell, I got the better deal. It wasn’t hot and stuffy, and the one person out there with me didn’t snore too much. The following night was inside one of the school rooms, which was helpful because it kept the mosquitoes somewhere where I wasn’t, although I think by then they’d decided I was bled dry anyway.
As is common with conferences, and even moreso with this one being an ‘unconference’, much of the value isn’t so much from the sessions, but from chatting to people you happen to sit beside because there’s a spare seat, whether they do programming, community projects, are politicians (I talked with Judith Tizard extremely briefly), or whatever. They all seem to be doing good stuff. I did, however, do a session of my own. I was planning on doing one on neural networks and genetic algorithms, and another on Amazon web services but due to time constraints (some uncharitable folk may call it laziness) beforehand, I only had time to prepare the GA stuff. That worked out OK, as it managed to take up the whole hour anyway. I didn’t get a big turnout, but I didn’t expect one - this was a fair bit more on the computer science side than most of the things there.
The photos I took are here, many more can be found on flickr.
The rest of the time in Auckland was catching up with friends there, and spending way too much money at JB Hi-Fi on music and a little bit of anime.
eMusic/J 0.23 released
I’ve just put out eMusic/J 0.23. The main reason for getting this out there is that there is a bugfix for a problem that occurs in a certain (rare) circumstance.
Here’s a list of the changes:
- Allow multiple tracks to be selected This means you can shift-click or control-click to perform operations on multiple tracks. This is a prelude to drag-and-drop support, which I hope to get to some time soon.
- Adds auto-remove timer to tracks that were finished when the program started Previously, and tracks there when the program started were never cleared automatically. Now they are.
- Trim spaces from ends of album/track/artist names as vfat doesn’t like them
- Changed default save location of files to ~/Music or ~/My Music (whichever exists), defaulting to the first one if neither do This should make its default save location a bit nicer on various platforms.
- Fixed an infinite loop if the album/artist/track names contain a path wildcard (e.g. %t). Thanks to Hugh Brackett for spotting this one. This caused the program to peg the CPU on this album due to the track “S#%t Outta Luck”
It can be downloaded from the eMusic/J homepage.
An extra note, a customised version of this program was developed for Reggae Country to use with their download service. Thanks for their support!
Making the Hercules DJ Control MP3 work with Mixxx
(Note: files updated for Ubuntu 8.04)
A little while back, I got a Hercules DJ Control MP3, which is an entry-level DJ console that connects to the computer with USB. Unlike most of these kinds of things, this isn’t a MIDI device, so making it work requires a bit of hacking.
Mixxx supports the Herc DJ Control Mk1 and Mk2 just fine, by talking to them directly over USB, unfortunately the Control MP3 requires some magic for this to work that noone has figured out yet. However, the kernel can talk to it using the HID system, which usually is used for keyboards, mice, and other random controllers. The problem with this is that the LEDs don’t work. For some reason, the Linux kernel (as of 2.6) ignores any LEDs that the device says it has if it doesn’t know what they are. With a bit of kernel hacking, this behaviour can be changed, and then Mixxx will use it just fine. If you don’t do this, the controls work, but the LEDs don’t. And we all want blinky LEDs, don’t we?
(Also, I used some of the spare LEDs on the controller and made them into a VU meter, which works surprisingly well.)
So to start with: making the kernel work right. I’ve made a patch against the Ubuntu 2.6.22 2.6.24 kernel, here. Or, if you are using Ubuntu 32-bit with this kernel, you can just use these two modules: hid.ko and usbhid.ko. (Files for Ubuntu 7.10 are also available). With the Herc unplugged, do:
sudo rmmod usbhid; sudo rmmod hid; sudo insmod hid.ko; sudo insmod usbhid.ko
(it pays to do them all on one line, as USB keyboards and mice may stop working while the module is unloaded). If these load properly, then you’re half way there.
The next step is to make Mixxx work with this. By default, it only supports the Mk1 and Mk2, as it uses the direct USB way of talking to them. To make it use HID, you need to recompile it, using the current SVN version. How to do this is documented on the Mixxx website, but the compile command needs an extra option, thus:
scons djconsole_legacy=1
The binary that this spits out should handle the LEDs just fine.
This is all very hacky, but hopefully it won’t be in the future. I’m going to see if I can get that patch put in the kernel proper, which will solve the most annoying part of the problem. It would also be good to get Mixxx supporting both legacy mode and the newer one at the same time.
However, we’ve heard from Hercules, and they say that some time in the first part of this year, they’re going to try to get some Linux drivers out. Hopefully they’re open source, and turn the Herc devices into MIDI devices, which would make life a whole lot easier for support.
First ever DJ gig
For the past couple of months I’ve been playing with Mixxx, practising mixing music. Today I played in front of a crowd for the first time ever. It was a friends birthday, and I’d raided his Gatecrasher CD collection first, so it wasn’t nice, heavy industrial like I’d like, but still, most of the people there seemed to like it. Coincidentally, I’d included a few tracks that people knew, which helped.
It was a load of fun, so hopefully I’ll get the chance to do it more. Even better if it’s the sort of stuff I prefer, although it’s much harder to mix the heavier stuff. But, if I put in more practise I’ll get better at it.
I really need to get a cheap control system to use with the laptop, it’ll be much better than using the keyboard for everything. I’m looking at the Hercules DJ Control MP3, it’s supposed to be pretty crap (very laggy), but it’s cheap, small and portable. It also works with Mixxx properly. When I get into this more, I can look into buying a more expensive and good one and hack Mixxx to work with it. Unfortunately, they don’t ship this outside the US, so I’ll have to find someone there to ship it to and send it on.
eMusic/J 0.22 released
They’re coming thick and fast now, I’ve just released a new version of eMusic/J.
Here are the changes:
- Added quotes around $@ in launch script to make it work better with some temp file names. If your browser stores files in a location with a space in the path, eMusic/J probably would have had issues opening them. Now it won’t.
- Changed default cover art name for windows and mac to ‘folder.jpg’. Works better on Mac and Windows, iTunes should automatically pick the cover art up now. It still saves as ‘cover.jpg’ on Linux because that seems to work well enough there.
- Cover art filename can be overridden by coverArtFilename option in prefs file. If the above doesn’t suit, you can change it by providing a name in the preferences file (~/.emusicj/emusicj.prop)
- Current download list saves when files are added, this means that the computer crashing won’t lose the current progress. Previously, the current download state was only saved when the program closed. However, if the computer crashed, the in-progress stuff was lost. Now, whenever you add files to download the list is saved, so the worst that’ll happen is that it’ll retry them.
- Added ” and & to the stripped out characters, they may be causing issues on some file systems. I’ve had reports of files repeatedly refusing to save. It may be caused by these characters, so they’re turned to ‘_’. Hopefully that deals with it.
eMusic/J 0.21 released
After a hiatus of about a year, I finally made a new release of eMusic/J. This was mostly caused by the change in the file format that eMusic provides for downloading albums. This version is (internally) quite different to the old one, as it is set up to make it easy to produce customised versions, so that one set of source code can produce both the downloader for Naxos’ Classicsonline service, and the regular eMusic/J.
The most important change in this is that it now supports both .emx files, as well as .emp files. It also now requires Java 1.5 (this is less of an issue now that Java is going properly open source), and is available for five platforms: Linux i686, Linux x86_64, Linux PPC, Windows (32-bit) and Mac OSX (Intel and PPC, but in one package). There were also numerous bugs fixed, mostly thanks to Naxos’s QA people, but nothing earth-shattering.
I also had the lead developer behind eMusic’s new download manager get in touch with me, and he provided me with some information that made this easier than it would have been otherwise, which was good.
Anyway, the new version can be found at the usual location.