pyToners,
I've forked a copy of pyTone that I'm calling DanceBox. You can get a tarball of my work so far at sourceforge. No web page or mailing list exist so go to the dancebox project. http://sourceforge.net/projects/dancebox/
I'm using darcs as my vcs. The tarball contains the repository. You can pull directly from my local public repository @ http://tant.com/~dancebox/dancebox-devel
I haven't made any kind of public announcement and probably won't until I get much further along but I thought I'd mention something here so I can get some pre-alpha feedback.
What:
DanceBox is a customized version of pyTone for a Dance Studio. Specifically for a dance studio that does partner dancing. Things like Cha Cha, Hustle, Swing, Waltz etc.
Modifications from mainline pyTone:
- I added a SQLite database backend. Currently it supports _most_ of what pyTone did originally. Implementing that was how I started learning how pyTone worked. I say most of pyTone functionality because once I got where the curses interface would play a song I stopped trying to implement the remaining pyTone functionality. The primary reason for adding SQLite is supporting my song classification system. For my purposes the "song can only be 1 genre" is way to limiting. In the partner dance world a single song may be good for several different dances. So I have a full relational setup that allows a song to be categorized by class, genre, dance, speed, and style. The only limit on how many of those classifications any single song can belong to is the number of records in a a SQLite table. So for all practical purposes unlimited.
I feel that what I have set up is probably the most flexible classification system of _any_ open source jukebox and should rival commercial offerings.
- Added support for speeding up and slowing down the currently played song with the internal player. By adding code and events that change the output sample rate of pcm.rate_convert it is possible to speed up and slow down the song. Yes it changes the pitch as well but in partner dance we aren't concerned about that. Slow it down for practice/learning and then gradually speed it up back normal.
- Moved all the user interface(s) stuff into its own subdirectory of a directory called 'ui' and created packages for them. You can now create multiple user interfaces.
- Added a (fledgling) Qt interface with pyQt. My goal for DanceBox is to have it operated from a single window using a touchscreen. So I'm working on a ui that's simple and easy to use from a touchscreen. I've only just started so its very incomplete. But it does load and display some items queried from the database. No player functions yet.
Goals and Directions:
The focus for pyTone and DanceBox are very different. The object store model used with the berkley db doesn't map well into the relational SQL world in some cases. I store all the info rather then the entire object. Which means I have to re-create a song object every time. So to support that I had to create a new song_lite class that did not go read all the meta-info of a song when instantiated.
pyTone wants to parse a collection of files and display all the ID3 info in an organized manner. DanceBox doesn't care about the id3 info. The artist, title, album, year, etc are all secondary, what matters most are what dance is it and how fast is it. Speed in this setup is fuzzy. Slow, medium, fast, etc. The database has fields for BPM and MPM (Measures per minute) but a single BPM may be fast in one dance and slow in another so you can't really catagorize on BPM.
Bringing up full pyTone compatibility is left as an exercise to the pyTone community. I'll be glad to help however I can but I won't ever really complete that on my own since it doesn't match up with how DanceBox works. That said all of pyTone's functionality should be able to be implemented with the database I setup. So if someone wanted to re-tool pyTone into using SQLite this should be a great start. I saw in the archives that moving to SQLite was suggested but met some resistance due to the additional dependencies that would add.
I have plans of going cross platform as well. Windows and Max OS X are targets. I know of studios in my local area using these platforms. pyAo and apsw (the SQLite wrapper) already do both of these platforms and building pcm.rate_convert should not be much of a problem. I haven't looked yet at mad and the other dependencies
I called it a semi-fork because I'd like to stay compatible with pyTone such that both projects can use advancements from each other with minimum hassle. I just don't know if that will be possible given the very different operational methods.
The astute hacker will also notice a difference in coding styles. I strongly dislike the alllowercasefunctions naming scheme. Being a native english speaker I find this very hard to read. I do realize that you german and dutch speaking folks are used to that and that even python itself uses that style.
My code uses a mixture of underscore names (get_the_data) and Qt style StudlyCaps (getTheData) I started coding using the _ names but once I got into the PyQt stuff for the gui I started matching Qt's style. In my database code its underscores and the ui code its Qt. I'll probably continue to do that. Since I don't really care as long as its readable and to me longfuncitonnames are not readable.
If you do pull down the code to play with you will need pyQt and apsw as additional dependencies. At some point I may move from apsw to Qt's database wrapper to keep it only dependent on pyQt and also leverage Qt's ability to access several different SQL databases but apsw is very easy to use.
One drawback of apsw (from SQLite actually) is that all operations to the database must be called from the same thread the cursor was created from. Apsw complained about that early on. So right now I workaound by grabbing an new cursor every time a query is made and releasing it when I'm done. For SQLite this is very fast. But doing this with say Qt and MySQL would probably be quite a bit slower so I need to serialize the access all from one thread. I'll cross those bridges later on as I reach them. Moving to Qt database wrappers may take care of this for me.
To use dancebox you start with dancebox.py rather than pytone.py. Running pytone.py will load up the curses interface. But remember a large amount of pyTone functionality is _not_ implemented. In either case DanceBox or the original pyTone will try to look for 'dancebox.conf' rather than 'pytonerc' in the normal places. I have not modified the config.py yet to recognize that it was started as pyTone vs DanceBox. I've included my sample dancebox.conf in the ./conf directory
Thanks in advance for your time and comments